Snapi

Section 7

Authorizer

Authorizer

Responsibility

  • Determines which items in a collection the current user can read or write.

include magic

class ContactCurator < BaseCurator
  include Omicron.authorization(ContactAuthorizer)

  def show_action
    def search_action
      pipe(default_response, :through => [
        :search, :filter_readable, :apply_readables, :set_is_editable, :decorate
      ])
    end

    pipe(default_response, :through => [
      :find, :authorize_to_read, :apply_readables, 
      :set_is_editable, :decorate
    ])
  end
end

We use the include magic to
inject authorize_to_read, authorize_to_write, and filter_readable into the curator. 

Concepts

  • scopes

    • apply_default_scopes
    • append_scopes
  • can_read?

  • can_write?

  • multiple authorizers

Scopes

need help from geoff

  • authorize_to_read -> can_read?
    • can read everything in a collection
       
  • authorize_to_write -> can_write?
    • ​can write everything in collection
       
  • filter_readable -> can_read?
    • removes items from the collection that can't be read

can_read? can_write?

class ContactAuthorizer < BaseAuthorizer
  apply_default_scopes
  append_scopes :write, "write_members"
  append_scopes :update, "write"

  def can_read?(contact)
    user.member_ids.include?(contact.member_id) ||
      is_user_on_team?(contact.team_id) ||
      user.managed_division_ids.include?(contact.division_id) ||
      auth_object.teamsnap_service
  end

  def can_write?(contact)
    user.member_ids.include?(contact.member_id) ||
      user.owned_team_ids.include?(contact.team_id) ||
      user.managed_division_ids.include?(contact.division_id) ||
      (
        user.managed_team_ids.include?(contact.team_id) &&
        !contact.is_member_team_owner
      ) ||
      auth_object.teamsnap_service
  end
end

BaseAuthorizer

  • user (current user)
    • team_ids
    • managed_team_ids
    • owned_team_ids
    • commissioned_team_ids
    • managed_division_ids
    • owned_division_ids
    • member_ids
  • oauth_application
    • teamsnap_service
    • first_party_token

Multiple Authorizers

  pipe(default_response, :through => [
    :search, :authorize_to_update_plan, :decorate
  ]

  def authorize_to_update_plan(response)
    _, _, collection = response
    auth = Roadblock::Stack.new(
      authentication_response, :scopes => current_scopes
    )
    auth.add(ServiceAuthorizer, authorizer)

    if auth.can?(:update_plan, collection)
      response
    else
      response.with(:status => 403, :collection => [])
    end
  end

# need help from Geoff

Add the ServiceAuthorizer to the chain.

Authorizer

Responsibility

  • Determines which items in a collection the current user can read or write.

Thank you!

Snapi Section 07 Authorizer

By Dustin McCraw

Snapi Section 07 Authorizer

  • 692