Class: Puavo::Authentication
- Inherits:
-
Object
- Object
- Puavo::Authentication
- Defined in:
- lib/puavo/authentication.rb
Instance Attribute Summary collapse
-
#authenticated ⇒ Object
Returns the value of attribute authenticated.
-
#authorized ⇒ Object
Returns the value of attribute authorized.
Class Method Summary collapse
Instance Method Summary collapse
-
#authenticate ⇒ Object
Authenticate configured connection to LDAP.
-
#authorize ⇒ Object
Authorize that user has permissions to use Puavo.
- #base ⇒ Object
- #configure_ldap_connection(credentials) ⇒ Object
- #current_organisation ⇒ Object
- #current_user ⇒ Object
- #external_service? ⇒ Boolean
-
#initialize ⇒ Authentication
constructor
A new instance of Authentication.
- #ldap_host ⇒ Object
- #logger ⇒ Object
- #oauth_access_token? ⇒ Boolean
- #oauth_client_server? ⇒ Boolean
- #puavo_configuration ⇒ Object
- #server? ⇒ Boolean
-
#test_bind(dn, password) ⇒ Object
Test dn&password bind to LDAP without actually configuring ActiveLdap to use them.
-
#user_password? ⇒ Boolean
User is authenticated with real password.
Constructor Details
#initialize ⇒ Authentication
Returns a new instance of Authentication.
40 41 42 |
# File 'lib/puavo/authentication.rb', line 40 def initialize @credentials = {} end |
Instance Attribute Details
#authenticated ⇒ Object
Returns the value of attribute authenticated.
34 35 36 |
# File 'lib/puavo/authentication.rb', line 34 def authenticated @authenticated end |
#authorized ⇒ Object
Returns the value of attribute authorized.
34 35 36 |
# File 'lib/puavo/authentication.rb', line 34 def @authorized end |
Class Method Details
.dn_cache_key(organisation_key, uid) ⇒ Object
36 37 38 |
# File 'lib/puavo/authentication.rb', line 36 def self.dn_cache_key(organisation_key, uid) "user_dn:#{ organisation_key }:#{ uid }" end |
.remove_connection ⇒ Object
62 63 64 65 66 |
# File 'lib/puavo/authentication.rb', line 62 def self.remove_connection ActiveLdap::Base.active_connections.keys.each do |connection_name| ActiveLdap::Base.remove_connection(connection_name) end end |
Instance Method Details
#authenticate ⇒ Object
Authenticate configured connection to LDAP.
Raises AuthenticationFailed if connection could not be made. Returns possible admin permissions on successful connect
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/puavo/authentication.rb', line 155 def authenticate # This is the first time when LDAP connection is used with the user's # credentials. So this search call will initialize the connection and # will raise ActiveLdap::AuthenticationError if user supplied a # bad password. begin @admin_permissions = School.search( :filter => "(puavoSchoolAdmin=#{ dn })", :scope => :one, :attributes => ["puavoId"], :limit => 1 ) AccessToken.validate @credentials if oauth_access_token? rescue ActiveLdap::AuthenticationError raise AuthenticationFailed, "Bad dn or password" rescue AccessToken::Expired raise AuthenticationFailed, "OAuth Access Token expired" end @authenticated = true end |
#authorize ⇒ Object
Authorize that user has permissions to use Puavo
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/puavo/authentication.rb', line 204 def raise AuthorizationFailed, "Cannot authorize before authenticating" unless @authenticated # Authorize school admins if not @admin_permissions.empty? logger.info "Authorization ok: Admin #{ dn }" return @authorized = true end # Authorize External Services if external_service? logger.info "Authorization ok: External Service #{ dn }" return @authorized = true end # Authorize OAuth Access Tokens if oauth_access_token? return @authorized = true end # Authorize organisation owners organisation = LdapOrganisation.first if organisation && organisation.owner && organisation.owner.include?(dn) logger.info "Authorization ok: Organisation owner #{ dn }" return @authorized = true end # Authorize servers if server? logger.info "Authorization ok: Server #{ dn }" return @authorized = true end raise AuthorizationFailed, "Unauthorized access for #{ dn }" end |
#base ⇒ Object
54 55 56 |
# File 'lib/puavo/authentication.rb', line 54 def base return current_organisation.ldap_base end |
#configure_ldap_connection(credentials) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/puavo/authentication.rb', line 68 def configure_ldap_connection(credentials) @credentials = credentials if current_organisation.nil? raise Puavo::AuthenticationError, "Bad organisation" end if uid = @credentials[:uid] if uid.nil? || uid.empty? raise AuthenticationFailed, "Cannot get dn from empty or nil uid" end if uid.match(/^service\//) uid = uid.match(/^service\/(.*)/)[1] user_class = ExternalService else user_class = User end user_dn = Rails.cache.fetch self.class.dn_cache_key(organisation_key, uid) do # Remove previous connection self.class.remove_connection LdapBase.ldap_setup_connection( ldap_host, base.to_s, puavo_configuration["bind_dn"], puavo_configuration["password"] ) user = user_class.find(:first, :attribute => "uid", :value => uid) if user user.dn.to_s else nil end end raise AuthenticationFailed, "Cannot get dn for UID '#{ uid }'" if not user_dn logger.debug "Found #{ dn } for #{ uid }" @credentials[:dn] = ActiveLdap::DistinguishedName.parse user_dn end # Reset attributes on new configuration @current_user = nil @authenticated = false @authorized = false # Remove previous connection self.class.remove_connection logger.info "Configuring ActiveLdap to use #{ @credentials.select{ |a,b| a != :password }.map { |k,v| "#{ k }: #{ v }" }.join ", " }" logger.debug "PW: #{ @credentials[:password] }" if ENV["LOG_LDAP_PASSWORD"] # Setup new ActiveLdap connections to use user's credentials LdapBase.ldap_setup_connection ldap_host, base.to_s, @credentials[:dn], @credentials[:password] # Do not never ever allow anonymous connections in Puavo. Should be # false in config/ldap.yml, but we just make sure here. LdapBase.connection.instance_variable_set :@allow_anonymous, false end |
#current_organisation ⇒ Object
261 262 263 |
# File 'lib/puavo/authentication.rb', line 261 def current_organisation Puavo::Organisation.find organisation_key end |
#current_user ⇒ Object
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/puavo/authentication.rb', line 241 def current_user raise "Cannot get current user before authentication" if not @authenticated return @current_user if @current_user if external_service? @current_user = ExternalService.find dn elsif oauth_access_token? access_token = AccessToken.find dn @current_user = User.find access_token.puavoOAuthEduPerson else @current_user = User.find dn end raise "Failed get User object for #{ dn }" if @current_user.nil? return @current_user end |
#external_service? ⇒ Boolean
181 182 183 |
# File 'lib/puavo/authentication.rb', line 181 def external_service? dn.rdns[1]["ou"] == "System Accounts" end |
#ldap_host ⇒ Object
58 59 60 |
# File 'lib/puavo/authentication.rb', line 58 def ldap_host @credentials[:ldap_host] || puavo_configuration["host"] end |
#logger ⇒ Object
265 266 267 |
# File 'lib/puavo/authentication.rb', line 265 def logger RAILS_DEFAULT_LOGGER end |
#oauth_access_token? ⇒ Boolean
193 194 195 |
# File 'lib/puavo/authentication.rb', line 193 def oauth_access_token? dn.rdns.first.keys.first == "puavoOAuthTokenId" end |
#oauth_client_server? ⇒ Boolean
189 190 191 |
# File 'lib/puavo/authentication.rb', line 189 def oauth_client_server? dn.rdns.first.keys.first == "puavoOAuthClientId" end |
#puavo_configuration ⇒ Object
50 51 52 |
# File 'lib/puavo/authentication.rb', line 50 def puavo_configuration ActiveLdap::Base.ensure_configuration end |
#server? ⇒ Boolean
185 186 187 |
# File 'lib/puavo/authentication.rb', line 185 def server? dn.rdns[1]["ou"] == "Servers" end |
#test_bind(dn, password) ⇒ Object
Test dn&password bind to LDAP without actually configuring ActiveLdap to use them
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/puavo/authentication.rb', line 133 def test_bind(dn, password) ldap = Net::LDAP.new( :host => ldap_host, :port => 389, :encryption => { :method => :start_tls }, :auth => { :method => :simple, :username => dn.to_s, :password => password }) if not ldap.bind raise AuthenticationFailed, "Test bind failed: Bad dn or password" end end |
#user_password? ⇒ Boolean
User is authenticated with real password
198 199 200 201 |
# File 'lib/puavo/authentication.rb', line 198 def user_password? return false if oauth_access_token? current_user.classes.include? "puavoEduPerson" end |