lib/rack/oauth2/server.rb in rack-oauth2-server-2.0.0.beta4 vs lib/rack/oauth2/server.rb in rack-oauth2-server-2.0.0.beta5

- old
+ new

@@ -77,14 +77,16 @@ # making a request to /oauth/access_token. # # @param [String] identity User ID, account ID, etc # @param [String] client_id Client identifier # @param [Array, nil] scope Array of string, nil if you want 'em all + # @param [Integer, nil] expires How many seconds before access grant + # expires (default to 5 minutes) # @return [String] Access grant authorization code - def access_grant(identity, client_id, scope = nil) + def access_grant(identity, client_id, scope = nil, expires = nil) client = get_client(client_id) or fail "No such client" - AccessGrant.create(identity, client, scope || client.scope).code + AccessGrant.create(identity, client, scope || client.scope, nil, expires).code end # Returns AccessToken from token. # # @param [String] token Access token (e.g. from oauth.access_token) @@ -189,20 +191,20 @@ if token begin access_token = AccessToken.from_token(token) raise InvalidTokenError if access_token.nil? || access_token.revoked - raise ExpiredTokenError if access_token.expires_at && access_token.expires_at <= Time.now.utc + raise ExpiredTokenError if access_token.expires_at && access_token.expires_at <= Time.now.to_i request.env["oauth.access_token"] = token request.env["oauth.identity"] = access_token.identity - logger.info "Authorized #{access_token.identity}" if logger + logger.info "RO2S: Authorized #{access_token.identity}" if logger rescue OAuthError=>error # 5.2. The WWW-Authenticate Response Header Field - logger.info "HTTP authorization failed #{error.code}" if logger + logger.info "RO2S: HTTP authorization failed #{error.code}" if logger return unauthorized(request, error) rescue =>ex - logger.info "HTTP authorization failed #{ex.message}" if logger + logger.info "RO2S: HTTP authorization failed #{ex.message}" if logger return unauthorized(request) end # We expect application to use 403 if request has insufficient scope, # and return appropriate WWW-Authenticate header. @@ -244,17 +246,17 @@ begin if request.GET["authorization"] auth_request = self.class.get_auth_request(request.GET["authorization"]) rescue nil if !auth_request || auth_request.revoked - logger.error "Invalid authorization request #{auth_request}" if logger + logger.error "RO2S: Invalid authorization request #{auth_request}" if logger return bad_request("Invalid authorization request") end response_type = auth_request.response_type # Needed for error handling client = self.class.get_client(auth_request.client_id) # Pass back to application, watch for 403 (deny!) - logger.info "Request #{auth_request.id}: Client #{client.display_name} requested #{auth_request.response_type} with scope #{auth_request.scope.join(" ")}" if logger + logger.info "RO2S: Client #{client.display_name} requested #{auth_request.response_type} with scope #{auth_request.scope.join(" ")}" if logger request.env["oauth.authorization"] = auth_request.id.to_s response = @app.call(request.env) raise AccessDeniedError if response[0] == 403 return response @@ -262,11 +264,11 @@ # 3. Obtaining End-User Authorization begin redirect_uri = Utils.parse_redirect_uri(request.GET["redirect_uri"]) rescue InvalidRequestError=>error - logger.error "Authorization request with invalid redirect_uri: #{request.GET["redirect_uri"]} #{error.message}" if logger + logger.error "RO2S: Authorization request with invalid redirect_uri: #{request.GET["redirect_uri"]} #{error.message}" if logger return bad_request(error.message) end # 3. Obtaining End-User Authorization response_type = request.GET["response_type"].to_s # Need this first, for error handling @@ -282,11 +284,11 @@ uri = URI.parse(request.url) uri.query = "authorization=#{auth_request.id.to_s}" return [303, { "Location"=>uri.to_s }, ["You are being redirected"]] end rescue OAuthError=>error - logger.error "Authorization request error: #{error.code} #{error.message}" if logger + logger.error "RO2S: Authorization request error #{error.code}: #{error.message}" if logger params = { :error=>error.code, :error_description=>error.message, :state=>state } if response_type == "token" redirect_uri.fragment = Rack::Utils.build_query(params) else # response type is code, or invalid params = Rack::Utils.parse_query(redirect_uri.query).merge(params) @@ -309,24 +311,24 @@ auth_request.grant! headers["oauth.identity"] end # 3.1. Authorization Response if auth_request.response_type == "code" if auth_request.grant_code - logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} granted access code #{auth_request.grant_code}" if logger + logger.info "RO2S: Client #{auth_request.client_id} granted access code #{auth_request.grant_code}" if logger params = { :code=>auth_request.grant_code, :scope=>auth_request.scope.join(" "), :state=>auth_request.state } else - logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} denied authorization" if logger + logger.info "RO2S: Client #{auth_request.client_id} denied authorization" if logger params = { :error=>:access_denied, :state=>auth_request.state } end params = Rack::Utils.parse_query(redirect_uri.query).merge(params) redirect_uri.query = Rack::Utils.build_query(params) else # response type if token if auth_request.access_token - logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} granted access token #{auth_request.access_token}" if logger + logger.info "RO2S: Client #{auth_request.client_id} granted access token #{auth_request.access_token}" if logger params = { :access_token=>auth_request.access_token, :scope=>auth_request.scope.join(" "), :state=>auth_request.state } else - logger.info "Request #{auth_request.id}: Client #{auth_request.client_id} denied authorization" if logger + logger.info "RO2S: Client #{auth_request.client_id} denied authorization" if logger params = { :error=>:access_denied, :state=>auth_request.state } end redirect_uri.fragment = Rack::Utils.build_query(params) end return redirect_to(redirect_uri) @@ -340,38 +342,39 @@ client = get_client(request) case request.POST["grant_type"] when "authorization_code" # 4.1.1. Authorization Code grant = AccessGrant.from_code(request.POST["code"]) - raise InvalidGrantError unless grant && client.id == grant.client_id - raise InvalidGrantError unless grant.redirect_uri.nil? || grant.redirect_uri == Utils.parse_redirect_uri(request.POST["redirect_uri"]).to_s + raise InvalidGrantError, "Wrong client" unless grant && client.id == grant.client_id + raise InvalidGrantError, "Wrong redirect URI" unless grant.redirect_uri.nil? || grant.redirect_uri == Utils.parse_redirect_uri(request.POST["redirect_uri"]).to_s + raise InvalidGrantError, "This access grant expired" if grant.expires_at && grant.expires_at <= Time.now.to_i access_token = grant.authorize! when "password" raise UnsupportedGrantType unless options.authenticator # 4.1.2. Resource Owner Password Credentials username, password = request.POST.values_at("username", "password") - raise InvalidGrantError unless username && password + raise InvalidGrantError, "Missing username/password" unless username && password requested_scope = Utils.normalize_scope(request.POST["scope"]) allowed_scope = client.scope raise InvalidScopeError unless (requested_scope - allowed_scope).empty? args = [username, password] args << client.id << requested_scope unless options.authenticator.arity == 2 identity = options.authenticator.call(*args) - raise InvalidGrantError unless identity + raise InvalidGrantError, "Username/password do not match" unless identity access_token = AccessToken.get_token_for(identity, client, requested_scope) else raise UnsupportedGrantType end - logger.info "Access token #{access_token.token} granted to client #{client.display_name}, identity #{access_token.identity}" if logger + logger.info "RO2S: Access token #{access_token.token} granted to client #{client.display_name}, identity #{access_token.identity}" if logger response = { :access_token=>access_token.token } response[:scope] = access_token.scope.join(" ") - return [200, { "Content-Type"=>"application/json", "Cache-Control"=>"no-store" }, response.to_json] + return [200, { "Content-Type"=>"application/json", "Cache-Control"=>"no-store" }, [response.to_json]] # 4.3. Error Response rescue OAuthError=>error - logger.error "Access token request error: #{error.code} #{error.message}" if logger + logger.error "RO2S: Access token request error #{error.code}: #{error.message}" if logger return unauthorized(request, error) if InvalidClientError === error && request.basic? return [400, { "Content-Type"=>"application/json", "Cache-Control"=>"no-store" }, - { :error=>error.code, :error_description=>error.message }.to_json] + [{ :error=>error.code, :error_description=>error.message }.to_json]] end end # Returns client from request based on credentials. Raises # InvalidClientError if client doesn't exist or secret doesn't match.