lib/osso/routes/oauth.rb in osso-0.0.5.pre.zeta vs lib/osso/routes/oauth.rb in osso-0.0.5

- old
+ new

@@ -14,19 +14,18 @@ # of the user who wants to sign in. If the sign in request # is valid, the user is redirected to their Identity Provider. # Once they complete IdP login, they will be returned to the # redirect_uri with an authorization code parameter. get '/authorize' do - client = find_client(params[:client_id]) - enterprise = find_account(domain: params[:domain], client_id: client.id) + identity_providers = find_providers validate_oauth_request(env) - redirect "/auth/saml/#{enterprise.provider.id}" if enterprise.single_provider? + redirect "/auth/saml/#{identity_providers.first.id}" if identity_providers.one? - @providers = enterprise.identity_providers.not_pending - erb :multiple_providers if @providers.count > 1 + @providers = identity_providers.not_pending + return erb :multiple_providers if @providers.count > 1 raise Osso::Error::MissingConfiguredIdentityProvider.new(domain: params[:domain]) rescue Osso::Error::Base => e @error = e erb :error @@ -36,52 +35,71 @@ # In addition to the authorization code, you must include all # paramaters required by OAuth spec: redirect_uri, client ID, # and client secret post '/token' do Rack::OAuth2::Server::Token.new do |req, res| - code = Models::AuthorizationCode. - find_by_token!(params[:code]) client = Models::OauthClient.find_by!(identifier: req.client_id) req.invalid_client! if client.secret != req.client_secret + + code = Models::AuthorizationCode.find_by_token!(params[:code]) req.invalid_grant! if code.redirect_uri != req.redirect_uri + res.access_token = code.access_token.to_bearer_token end.call(env) end # Use the access token to request a profile for the user who # just logged in. Access tokens are short-lived. get '/me' do - json Models::AccessToken. + token = Models::AccessToken. includes(:user). valid. - find_by_token!(params[:access_token]). - user + find_by_token!(access_token) + + json token.user.as_json.merge(requested: token.requested) end end private - def find_account(domain:, client_id:) - Models::EnterpriseAccount. - includes(:identity_providers). - find_by!(domain: domain, oauth_client_id: client_id) - rescue ActiveRecord::RecordNotFound - raise Osso::Error::NoAccountForOAuthClientError.new(domain: params[:domain]) + def find_providers + if params[:email] + user = Osso::Models::User. + includes(:identity_provider). + find_by(email: params[:email]) + return [user.identity_provider] if user + end + + Osso::Models::IdentityProvider. + joins(:oauth_client). + where( + domain: domain_from_params, + oauth_clients: { identifier: params[:client_id] }, + ) end + def domain_from_params + params[:domain] || params[:email].split('@')[1] + end + def find_client(identifier) @client ||= Models::OauthClient.find_by!(identifier: identifier) rescue ActiveRecord::RecordNotFound raise Osso::Error::InvalidOAuthClientIdentifier end - def validate_oauth_request(env) + def validate_oauth_request(env) # rubocop:disable Metrics/AbcSize Rack::OAuth2::Server::Authorize.new do |req, _res| client = find_client(req[:client_id]) session[:osso_oauth_redirect_uri] = req.verify_redirect_uri!(client.redirect_uri_values) session[:osso_oauth_state] = params[:state] + session[:osso_oauth_requested] = { domain: req[:domain], email: req[:email] } end.call(env) rescue Rack::OAuth2::Server::Authorize::BadRequest raise Osso::Error::InvalidRedirectUri.new(redirect_uri: params[:redirect_uri]) + end + + def access_token + params[:access_token] || env.fetch('HTTP_AUTHORIZATION', '').slice(-64..-1) end end end