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.