Skip to content

Instantly share code, notes, and snippets.

@lukerandall
Last active December 16, 2015 08:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukerandall/5403752 to your computer and use it in GitHub Desktop.
Save lukerandall/5403752 to your computer and use it in GitHub Desktop.
class Doorman
attr_reader :user, :portal, :account
def initialize(user, portal, account)
@user = user
@portal = portal
@account = account
end
def accessible_accounts
accounts(intent: :access)
end
def modifiable_account
accounts(intent: :modify)
end
def access_account(id)
find_account(id, intent: :access)
end
def modify_account(id)
find_account(id, intent: :modify)
end
def users
User.where(id: editable_users)
end
def find_user(id)
users.exists?(id) ? find_user!(id) : nil
end
def find_user!(id)
users.find(id)
end
private
# Returns a collection of accounts scoped to the user's rights of access.
# The 'intent' of the user will have an effect on the scope of
# the collection (users can access more than they can modify).
# The 2 supported intents are: 'access', 'modify'
# Intent is specified as an argument as follows:
#
# doorman.accounts(:intent => :access)
#
# The default intent is :modify
def accounts(options = {})
options[:intent] ||= :modify
if user.is_superuser?
Account.scoped # can access all accounts
elsif user.is_group_administrator?(portal)
portal.accounts # can access all portal accounts
elsif user.is_consolidation_administrator?(portal) or user.is_portal_administrator?(portal)
user.extend(PortalAdministrator)
user.accessible_accounts(portal) # can access all associated accounts and their descendants
elsif user.is_administrator?
user.accounts # can access accounts associated with them
else
# normal users may not modify any accounts
return user.accounts if options[:intent] == :access
# but they may enter those associated with them
Account.none
end
end
def find_account(id, options = {})
accounts(options).exists?(id) ? find_account!(id, options) : nil
end
def find_account!(id, options = {})
accounts(options).find(id)
end
def editable_users
potentially_editable_users
.select {|u| user.can_edit?(u)}
end
def potentially_editable_users
if user.is_superuser?
User.scoped
elsif user.is_portal_administrator?(portal)
User.joins(:accounts).where("accounts_users.account_id" => accounts)
elsif user.is_administrator?
account ? account.users : User.none
else
User.none
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment