Module: Cyclid::API::AuthHelpers

Defined in:
app/cyclid/sinatra/auth_helpers.rb

Overview

Sinatra Warden AuthN/AuthZ helpers

Instance Method Summary collapse

Instance Method Details

#authenticate!Object

Call the Warden authenticate! method



39
40
41
# File 'app/cyclid/sinatra/auth_helpers.rb', line 39

def authenticate!
  env['warden'].authenticate!
end

#authorized_admin!(operation) ⇒ Object

Authenticate the user, then ensure that the user is an admin and authorized for the resource for the given username & operation



80
81
82
# File 'app/cyclid/sinatra/auth_helpers.rb', line 80

def authorized_admin!(operation)
  authorized_for!('admins', operation)
end

#authorized_as!(username, operation) ⇒ Object

Authenticate the user, then ensure that the user is authorized for the resource for the given username & operation



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'app/cyclid/sinatra/auth_helpers.rb', line 86

def authorized_as!(username, operation)
  authenticate!

  user = current_user

  # Users are always authorized for any operation on their own data
  return true if user.username == username

  # Super Admins may be authorized, depending on the operation
  if super_admin?(user)
    begin
      organization = user.organizations.find_by(name: 'admins')
      permissions = user.userpermissions.find_by(organization: organization)
      Cyclid.logger.debug permissions

      # Admins have full authority, regardless of the operation
      return true if permissions.admin
      return true if operation == Operations::WRITE && permissions.write
      return true if operation == Operations::READ && (permissions.write || permissions.read)
    rescue StandardError => ex # XXX: Use a more specific rescue
      Cyclid.logger.info "authorization failed: #{ex}"
      halt_with_json_response(401, Errors::HTTPErrors::AUTH_FAILURE, 'unauthorized')
    end

  end

  halt_with_json_response(401, Errors::HTTPErrors::AUTH_FAILURE, 'unauthorized')
end

#authorized_for!(org_name, operation) ⇒ Object

Authenticate the user, then ensure that the user is authorized for the given organization and operation



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/cyclid/sinatra/auth_helpers.rb', line 45

def authorized_for!(org_name, operation)
  authenticate!

  user = current_user

  # Promote the organization to 'admins' if the user is a SuperAdmin
  org_name = 'admins' if super_admin?(user)

  begin
    organization = user.organizations.find_by(name: org_name)
    halt_with_json_response(401, Errors::HTTPErrors::AUTH_FAILURE, 'unauthorized') \
      if organization.nil?
    Cyclid.logger.debug "authorized_for! organization: #{organization.name}"

    # Check what Permissions are applied to the user for this Org & match
    # against operation
    permissions = user.userpermissions.find_by(organization: organization)
    Cyclid.logger.debug "authorized_for! #{permissions.inspect}"

    # Admins have full authority, regardless of the operation
    return true if permissions.admin
    return true if operation == Operations::WRITE && permissions.write
    return true if operation == Operations::READ && (permissions.write || permissions.read)

    Cyclid.logger.info "user #{user.username} is not authorized for operation #{operation}"

    halt_with_json_response(401, Errors::HTTPErrors::AUTH_FAILURE, 'unauthorized')
  rescue StandardError => ex # XXX: Use a more specific rescue
    Cyclid.logger.info "authorization failed: #{ex}"
    halt_with_json_response(401, Errors::HTTPErrors::AUTH_FAILURE, 'unauthorized')
  end
end

#current_userObject

Current User object from the session



122
123
124
# File 'app/cyclid/sinatra/auth_helpers.rb', line 122

def current_user
  env['warden'].user
end

#halt_with_json_response(error, id, description) ⇒ Object

Return an HTTP error with a RESTful JSON response XXX Should probably be in ApiHelpers?



34
35
36
# File 'app/cyclid/sinatra/auth_helpers.rb', line 34

def halt_with_json_response(error, id, description)
  halt error, json_response(id, description)
end

#super_admin?(user) ⇒ Boolean

Check if the given user is a Super Admin; any user that belongs to the ‘admins’ organization is a super admin

Returns:

  • (Boolean)


117
118
119
# File 'app/cyclid/sinatra/auth_helpers.rb', line 117

def super_admin?(user)
  user.organizations.exists?(name: 'admins')
end