We need to be able to eval an expression outside of the Hobo module so that, e.g. “User” doesn’t eval to “Hobo::Model::User” (Ruby determines this constant lookup scope lexically)
# File lib/hobo/model/lifecycles/actions.rb, line 4 def __top_level_eval__(obj, expr) obj.instance_eval(expr) end
# File lib/hobo/extensions/active_record/permissions.rb, line 71 def _create_record_with_user_create(attrs, options, raise = false, &block) klass = @reflection.klass user = acting_user if klass < Hobo::Model if user if attributes.is_a?(Array) attributes.collect { |attr| create_record(attr, options, raise, &block) } else transaction do add_to_target(klass.user_create(attributes)) do |record| yield(record) if block_given? insert_record(record, true, raise) end end end else create_record_without_user_create(attrs, options, raise, &block) end end
moved here from authentication_support.rb for easy overriding Redirect as appropriate when an access request fails.
The default action is to redirect to the login screen.
Override this method in your controllers if you want to have special behavior in case the user is not authorized to access the requested action. For example, a popup window might simply close itself.
# File lib/hobo/extensions/action_controller/hobo_methods.rb, line 29 def access_denied(user_model) respond_to do |accepts| accepts.html do store_location redirect_to(login_url(user_model)) end accepts.xml do headers["Status"] = "Unauthorized" headers["WWW-Authenticate"] = %Q(Basic realm="Web Password") render :text => t("hobo.messages.unauthenticated", :default=>["Couldn't authenticate you"]), :status => '401 Unauthorized' end end false end
Helper - the user acting on the owner (if there is one)
# File lib/hobo/extensions/active_record/permissions.rb, line 4 def acting_user @owner.acting_user if @owner.is_a?(Hobo::Model) end
Similar to human_name_attributes, this method retrieves the localized help string of an attribute if it is defined as the key “activemodel.attribute_help.<attribute_name>”, otherwise it returns “”.
# File lib/hobo/extensions/active_model/translation.rb, line 22 def attribute_help(attribute, options = {}) defaults = lookup_ancestors.map do |klass| :"#{self.i18n_scope}.attribute_help.#{klass.to_s.underscore}.#{attribute}" end defaults << :"attribute_help.#{attribute}" defaults << options.delete(:default) if options[:default] defaults << '' options.reverse_merge! :count => 1, :default => defaults I18n.translate(defaults.shift, options) end
# File lib/hobo/extensions/active_record/permissions.rb, line 135 def create(attrs = {}) if attrs.is_a?(Array) attrs.collect { |attr| create(attr) } else create_record(attrs) do |record| yield(record) if block_given? user = acting_user if record.is_a?(Hobo::Model) user ? record.user_save(user) : record.save end end end
# File lib/hobo/extensions/active_record/permissions.rb, line 147 def create!(attrs = {}) create_record(attrs) do |record| yield(record) if block_given? user = acting_user if record.is_a?(Hobo::Model) user ? record.user_save!(user) : record.save! end end
# File lib/hobo/extensions/active_record/permissions.rb, line 9 def delete_records(records, method) if method == :destroy records.each { |r| r.is_a?(Hobo::Model) ? r.user_destroy(acting_user) : r.destroy } update_counter(-records.length) unless inverse_updates_counter_cache? else keys = records.map { |r| r[reflection.association_primary_key] } scope = scoped.where(reflection.association_primary_key => keys) if method == :delete_all update_counter(-scope.delete_all) else update_counter(-scope.update_all(reflection.foreign_key => nil)) end end end
TODO - add dependent option support
# File lib/hobo/extensions/active_record/permissions.rb, line 105 def delete_records_with_hobo_permission_check(records, method) user = acting_user problem_joiner=nil association = self.respond_to?(:proxy_association) ? proxy_association : self through_assoc_name = association.send(:through_reflection).name if user && records.any? { |r| ja = construct_join_attributes(r) problem_joiner = joiner = association.owner.send(through_assoc_name).where(ja).first joiner.is_a?(Hobo::Model) && !joiner.destroyable_by?(user) } message = "#{@owner.class}##{association.reflection.name}.destroy " if 'development' == Rails.env message += " because of #{problem_joiner.class.name}(#{problem_joiner.to_json})" end raise Hobo::PermissionDeniedError, message end delete_records_without_hobo_permission_check(records, method) end
# File lib/hobo/extensions/action_controller/hobo_methods.rb, line 16 def home_page base_url end
adds a default pluralization and singularization for english useful to avoid to set a locale ‘en’ file and avoid to pass around pluralize calls for ‘en’ defaults in hobo
# File lib/hobo/extensions/active_model/translation.rb, line 6 def human_attribute_name_with_en_pluralization_default(attribute, options={}) if I18n.locale.to_s.match(/^en/) unless options[:count].blank? # skip default if we don't pass any count default = options[:count] == 1 ? attribute.to_s.singularize.humanize : # singularize possible plural attributes attribute.to_s.pluralize.humanize options.merge! :default => default end end human_attribute_name_without_en_pluralization_default(attribute, options) end
adds a default pluralization for english useful to avoid to set a locale ‘en’ file and avoid to pass around pluralize calls for ‘en’ defaults in hobo
# File lib/hobo/extensions/active_model/name.rb, line 5 def human_with_en_pluralization_default(options={}) if I18n.locale.to_s.match(/^en/) unless options[:count] == 1 || options[:count].blank? default = ActiveSupport::Inflector.pluralize(@human) options.merge! :default => default end end human_without_en_pluralization_default(options) end
# File lib/hobo/extensions/active_record/permissions.rb, line 42 def insert_record_with_owner_attributes(record, force = true, raise = false) set_owner_attributes(record) if (user = acting_user) && record.is_a?(Hobo::Model) if respond_to?(:with_acting_user) with_acting_user(user) { insert_record_without_owner_attributes(record, force, raise) } else record.with_acting_user(user) { insert_record_without_owner_attributes(record, force, raise) } end else insert_record_without_owner_attributes(record, force, raise) end end
Set the fkey used by this has_many to null on the passed records, checking for permission first if both the owner and record in question are Hobo models
# File lib/hobo/extensions/active_record/permissions.rb, line 28 def nullify_keys(records) if (user = acting_user) records.each { |r| r.user_update_attributes!(user, @reflection.foreign_key => nil) if r.is_a?(Hobo::Model) } end # Normal ActiveRecord implementatin ids = records.map { |record| record.quoted_id }.join(',') @reflection.klass.update_all( "#{@reflection.foreign_key} = NULL", "#{@reflection.foreign_key} = #{@owner.quoted_id} AND #{@reflection.klass.primary_key} IN (#{ids})" ) end
# File lib/hobo/extensions/action_view/tag_helper.rb, line 5 def tag(name, options = nil, open = false, escape = true) open = !scope.xmldoctype if defined?(scope) tag_without_doctype(name, options, open, escape) end
simple wrapper around the translate helper it implements a dryml <translate> and a <t> tag Improved security: interpolated variables are escaped Improved management: when it returns a string it is always html_safe It assumes the base translation string is html_safe It removes the <span> tag when the key is missing, because it would mess up the dryml tags when ht or t is used in some place
# File lib/hobo/extensions/action_view/translation_helper.rb, line 11 def translate(key, options={}) key, options = normalize_args(key, options) translation = I18n.translate(scope_key_by_partial(key), options.merge!(:raise => true)) if translation.respond_to?(:html_safe) translation.html_safe else translation end rescue I18n::MissingTranslationData => e keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope]).join('.') "[MISSING: #{keys}]" end
# File lib/hobo/extensions/active_record/permissions.rb, line 56 def viewable_by?(user, field=nil) # view check on an example member record is not supported on associations with conditions return true if @reflection.options[:conditions] new_candidate.viewable_by?(user, field) end
# File lib/hobo/extensions/action_controller/hobo_methods.rb, line 12 def self.hobo_controller include Hobo::Controller end
# File lib/hobo/extensions/active_record/hobo_methods.rb, line 2 def self.hobo_model include Hobo::Model fields(false) # force hobo_fields to load end
# File lib/hobo/extensions/action_controller/hobo_methods.rb, line 8 def self.hobo_model_controller include Hobo::Controller::Model end
# File lib/hobo/extensions/action_controller/hobo_methods.rb, line 3 def self.hobo_user_controller include Hobo::Controller::Model include Hobo::Controller::UserBase end
# File lib/hobo/extensions/active_record/hobo_methods.rb, line 6 def self.hobo_user_model include Hobo::Model include Hobo::Model::UserBase end
# File lib/hobo/extensions/i18n.rb, line 4 def translate_with_show_keys(key, options = {}) translation = translate_without_show_keys(key, options) return translation unless translation.is_a?(String) keys = normalize_keys(locale, key, options[:scope]).join('.') "[#{keys}]" + translation end