validate :ensure_filesystem_compatible_name
validate :check_group_class
+ validate :check_filter_group_filters
before_create :assign_name
after_create :after_ownership_change
after_create :update_trash
before_update :before_ownership_change
after_update :after_ownership_change
+ after_create :add_role_manage_link
+
after_update :update_trash
before_destroy :clear_permissions_and_trash
end
def ensure_filesystem_compatible_name
- # project groups need filesystem-compatible names, but others
+ # project and filter groups need filesystem-compatible names, but others
# don't.
- super if group_class == 'project'
+ super if group_class == 'project' || group_class == 'filter'
end
def check_group_class
- if group_class != 'project' && group_class != 'role'
- errors.add :group_class, "value must be one of 'project' or 'role', was '#{group_class}'"
+ if group_class != 'project' && group_class != 'role' && group_class != 'filter'
+ errors.add :group_class, "value must be one of 'project', 'role' or 'filter', was '#{group_class}'"
end
if group_class_changed? && !group_class_was.nil?
errors.add :group_class, "cannot be modified after record is created"
end
end
+ def check_filter_group_filters
+ if group_class == 'filter'
+ if !self.properties.key?("filters")
+ errors.add :properties, "filters property missing, it must be an array of arrays, each with 3 elements"
+ return
+ end
+ if !self.properties["filters"].is_a?(Array)
+ errors.add :properties, "filters property must be an array of arrays, each with 3 elements"
+ return
+ end
+ self.properties["filters"].each do |filter|
+ if !filter.is_a?(Array)
+ errors.add :properties, "filters property must be an array of arrays, each with 3 elements"
+ return
+ end
+ if filter.length() != 3
+ errors.add :properties, "filters property must be an array of arrays, each with 3 elements"
+ return
+ end
+ if !filter[0].include?(".") and filter[0].downcase != "uuid"
+ errors.add :properties, "filter attribute must be 'uuid' or contain a dot (e.g. groups.name)"
+ return
+ end
+ if (filter[0].downcase != "uuid" and filter[1].downcase == "is_a")
+ errors.add :properties, "when filter operator is 'is_a', attribute must be 'uuid'"
+ return
+ end
+ if ! ["=","<","<=",">",">=","!=","like","ilike","in","not in","is_a"].include?(filter[1].downcase)
+ errors.add :properties, "filter operator is not valid (must be =,<,<=,>,>=,!=,like,ilike,in,not in,is_a)"
+ return
+ end
+ end
+ end
+ end
+
def update_trash
- if trash_at_changed? or owner_uuid_changed?
+ if saved_change_to_trash_at? or saved_change_to_owner_uuid?
# The group was added or removed from the trash.
#
# Strategy:
end
def after_ownership_change
- if owner_uuid_changed?
+ if saved_change_to_owner_uuid?
update_permissions self.owner_uuid, self.uuid, CAN_MANAGE_PERM
end
end
end
true
end
+
+ def ensure_owner_uuid_is_permitted
+ if group_class == "role"
+ @requested_manager_uuid = nil
+ if new_record?
+ @requested_manager_uuid = owner_uuid
+ self.owner_uuid = system_user_uuid
+ return true
+ end
+ if self.owner_uuid != system_user_uuid
+ raise "Owner uuid for role must be system user"
+ end
+ raise PermissionDeniedError unless current_user.can?(manage: uuid)
+ true
+ else
+ super
+ end
+ end
+
+ def add_role_manage_link
+ if group_class == "role" && @requested_manager_uuid
+ act_as_system_user do
+ Link.create!(tail_uuid: @requested_manager_uuid,
+ head_uuid: self.uuid,
+ link_class: "permission",
+ name: "can_manage")
+ end
+ end
+ end
end