#coding: utf-8 #-- # Copyright (c) 2012-2013 Damjan Rems # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #++ class DcCommonController < DcApplicationController layout false ######################################################################## # Autocomplete request, for search fiels ######################################################################## def autocomplete # return '' unless session[:edit_mode] > 0 # return render text: t('drgcms.not_authorized') unless dc_user_can(DcPermission::CAN_VIEW) # TODO Double check if previous line works as it should. table = params['table'].classify.constantize id = [params['id']] || '_id' # call method in class if search parameter has . This is for user defined sofisticated searches # result must be returned as array of [id, search_field_value] a = if params['search'].match(/\./) name, method = params['search'].split('.') table.send(method, params['input']).inject([]) do |r,v| r << { label: v[1], value: v[1], id: v[0].to_s } end # simply search which will search and return field_name defined in params['search'] else table.where(params['search'] => /#{params['input']}/i).limit(20).inject([]) do |r,v| r << { label: v[params['search']], value: v[params['search']], id: v.id.to_s } end end render inline: a.to_json, formats: 'js' end ######################################################################## # Register and save click on ad link ######################################################################## def ad_click if (ad = DcAd.find(params[:id])) ad.clicked += 1 ad.save DcAdStat.create!(dc_ad_id: params[:id], ip: request.ip, type: 2 ) #.save else logger.error "ERROR ADS: Invalid ad id=#{params[:id]} ip=#{request.ip}." end render :nothing => true end ########################################################################## # Toggle cmd edit mode ########################################################################## def toggle_edit_mode session[:edit_mode] ||= 0 # called directly without authorization if session[:edit_mode] < 1 dc_render_404 #(:file => "#{Rails.root}/public/404", :status => 404, :layout => false, :formats => [:html]) else session[:edit_mode] = (session[:edit_mode] == 1) ? 2 : 1 redirect_to params[:return_to] end end #################################################################### # Process login action #################################################################### def process_login # Something is really wrong return dc_render_404 unless ( params[:record] and params[:record][:username] and params[:record][:password] ) user = DcUser.find_by(username: params[:record][:username]) if user and user.authenticate(params[:record][:password]) fill_login_data(user, params[:record][:remember_me].to_i == 1) else flash[:error] = t('drgcms.invalid_username') params[:return_to] = params[:return_to_error] # return_to error end redirect_to params[:return_to] || '/' end #################################################################### # Process logout action #################################################################### def logout clear_login_data redirect_to params[:return_to] || '/' end #################################################################### # Alternative login. If remember_me cookie is found it tries to automatically logs #################################################################### def login if cookies.signed[:remember_me] user = DcUser.find(cookies.signed[:remember_me]) if user fill_login_data(user, true) return redirect_to params[:return_to] else clear_login_data # on the safe side end end # Display login # redirect_to controller: 'poll', poll_id: 'login', return_to: params[:return_to] # redirect_to( {host: 'poll', poll_id: 'login', return_to: params[:return_to]} ) route = params[:route] || 'poll' redirect_to "/#{route}?poll_id=login&return_to=#{params[:return_to]}" end #################################################################### # Processes restore from journal action #################################################################### def restore_from_journal # selected fields to hash restore = params[:select].inject({}) {|r,v| r[v.first] = 0 if v.last == '1'; r} result = if restore.size == 0 { 'msg_error' => (t ('drgcms.dc_journal.zero_selected')) } else j = DcJournal.find(params[:id]) # update hash with data to be restored JSON.parse(j.diff).each {|k,v| restore[k] = v.first if restore[k] } # determine tables and record ids tables = j.tables.split(';') ids = (j.ids.blank? ? [] : j.ids.split(';') ) << j.doc_id # find record doc = nil tables.each_index do |i| doc = if doc.nil? (tables[i].classify.constantize).find(ids[i]) else doc.send(tables[i].pluralize).find(ids[i]) end end # restore values restore.each do |k,v| doc.send("#{k}=",v) end # save record doc.save # TODO Error checking { 'msg_info' => (t ('drgcms.dc_journal.restored')) } end render inline: result.to_json, formats: 'js' end ######################################################################## # Update some anomalies in json ######################################################################## def update_json(json, is_update=false) result = {} json.each do |k,v| if v.class == Hash result[k] = v['$oid'] if is_update elsif v.class == Array result[k] = [] v.each {|e| result[k] << update_json(e, is_update)} else result[k] = v end end result end ######################################################################## # Copy current record to clipboard as json text. It will actually ouput an # window with data formatted as json. ######################################################################## def copy_clipboard # Only administrators can perform this operation return render(text: t('drgcms.not_authorized') ) unless dc_user_has_role('admin') # respond_to do |format| # just open new window to same url and come back with html request format.json { dc_render_ajax(operation: 'window', url: request.url ) } format.html do doc = dc_find_document(params[:table], params[:id], params[:ids]) text = "

[#{params[:table]},#{params[:id]},#{params[:ids]}]
" render text: text + doc.as_document.to_json end end end ######################################################################## # Paste data from clipboard into text_area and update documents in destination database. ######################################################################## def paste_clipboard # Only administrators can perform this operation return render(text: t('drgcms.not_authorized') ) unless dc_user_has_role('admin') result = '' respond_to do |format| # just open new window to same url and come back with html request format.html { return render('paste_clipboard', layout: 'cms') } format.json { table, id, ids = nil params[:data].split("\n").each do |line| line.chomp! next if line.size < 5 # empty line. Skip begin if line[0] == '[' # id(s) result << "
#{line}" line = line[/\[(.*?)\]/, 1] # just what is between [] table, id, ids = line.split(',') elsif line[0] == '{' # document data result << process_document(line, table, id, ids) end rescue Exception => e result << " Runtime error. #{e.message}\n" break end end } end dc_render_ajax(operation: :div, div: 'result', value: result ) end protected ######################################################################## # Processes one document. Subroutine of paste_clipboard. ######################################################################## def process_document(line, table, id, ids) if params[:do_update] == '1' doc = dc_find_document(table, id, ids) # document found. Update it and return if doc doc.update( update_json(ActiveSupport::JSON.decode(line), true) ) msg = dc_check_model(doc) return (msg ? " ERROR! #{msg}" : " UPDATE. OK.") end end # document will be added to collection if ids.to_s.size > 5 #TODO Add embedded document " NOT SUPPORTED YET!" else doc = table.classify.constantize.new( update_json(ActiveSupport::JSON.decode(line)) ) doc.save end msg = dc_check_model(doc) msg ? " ERROR! #{msg}" : " NEW. OK." end #################################################################### # Clears all session data related to login #################################################################### def clear_login_data session[:edit_mode] = 0 session[:user_id] = nil session[:user_name] = nil session[:user_roles] = nil cookies.delete :remember_me end #################################################################### # Fills session with data related to succesfull login. #################################################################### def fill_login_data(user, remember_me) session[:user_id] = user.id session[:user_name] = user.name session[:edit_mode] = 0 session[:user_roles] = nil # special for SUPERADMIN sa = DcPolicyRole.find_by(system_name: 'superadmin') if sa and (role = user.dc_user_roles.find_by(dc_policy_role_id: sa.id)) session[:user_roles] = [] session[:user_roles] << role.dc_policy_role_id session[:edit_mode] = 2 return end # read default policy from site default_policy = dc_get_site().dc_policies.find_by(is_default: true) # load user roles user.dc_user_roles.each do |role| next unless role.active next if role.valid_from and role.valid_from > Time.now.end_of_day.to_date next if role.valid_to and role.valid_to < Time.now.to_date # check if role is active in this site policy_role = default_policy.dc_policy_rules.find_by(dc_policy_role_id: role.dc_policy_role_id) next unless policy_role # set edit_mode # session[:edit_mode] = 1 if policy_role.has_cms_menu session[:edit_mode] = 1 if policy_role.permission > 1 session[:user_roles] ||= [] # session[:user_roles] << role.dc_policy_role_id end # Save remember me cookie if not CMS user and remember me is selected if session[:edit_mode] == 0 and remember_me cookies.signed[:remember_me] = { :value => user.id, :expires => 180.days.from_now} end end end