Closed gregwinn closed 12 years ago
Anyone have an solution to this?? Or is anyone seeing the same thing?
Not sure, if it's good idea. But as a temporary solution, you may try this:
config/roures.rb :
scope '/oauth2', :as => 'oauth2' do
match 'authorize' => 'oauth_authorizations#new'
end
app/controllers/oauth_authorizations_controller.rb :
class OauthAuthorizationsController < Oauth2::AuthorizationsController
def new
params[:approve] = true
respond *authorize_endpoint(:allow_approval).call(request.env)
end
end
Thank you, i will give this a try and let you know!
This solution does work but it approves the user even if they have not approved the client. For me this is only a temp solution... I am looking for a long term fix so the user can approve or deny the client only once.
Here is my controller:
class OauthAuthorizationsController < Devise::Oauth2Providable::AuthorizationsController
def new
params[:approve] = true
respond *authorize_endpoint(:allow_approval).call(request.env)
end
end
Add before filter to :create action and save approved clients to DB. On the :new action - get approved clients of user and authorize (or not).
Not sure if this is the right solution, but in my branch of devise_oauth2_providable, I modified the authorize_endpoint function to check for a valid refresh token. If I have a valid refresh token stored already, then I force params[:approve] to true and allow_approval to :allow_approval.
authorizations_controller.rb
def authorize_endpoint(allow_approval = false)
Rack::OAuth2::Server::Authorize.new do |req, res|
@client = Devise::Oauth2Providable::Client.find_by_client_identifier(req.client_id) || req.bad_request!
res.redirect_uri = @redirect_uri = req.verify_redirect_uri!(@client.redirect_uri)
# Auto-approve if we have a valid refresh token.
valid_refresh_token = get_valid_refresh_token
if valid_refresh_token
params[:approve] = true
allow_approval = :allow_approval
end
if allow_approval
if params[:approve].present?
case req.response_type
when :code
authorization_code = current_user.authorization_codes.create!(:client => @client)
res.code = authorization_code.token
when :token
access_token = current_user.access_tokens.create!(:client => @client).token
bearer_token = Rack::OAuth2::AccessToken::Bearer.new(:access_token => access_token)
res.access_token = bearer_token
res.uid = current_user.id
end
res.approve!
else
req.access_denied!
end
else
@response_type = req.response_type
end
end
end
The get_valid_refresh_token function looks like this:
def get_valid_refresh_token
return current_user.refresh_tokens.where(:client_id => @client.id).not_expired.first if current_user
nil
end
Note that I'm using Mongoid as my data store, so the query syntax in get_valid_refresh_token is written for Mongoid. But you could modify it for ActiveRecord.
Thanks for all the replies! The solution we ended up using was a mix of the first reply and a suggestion from @denyago. We are saving the approval to the DB then checking once the user comes back to see if the client is approved. The user now only sees the approve deny once until they revoke access. Please contact me if you have any questions on how we implemented this solution.
Big thanks to @denyago and @joe1chen
Hello, I have an issue, and this could be my own issue but looking for an answer. Each time the user logs in it's asking to "Approve" or "Deny", should this only take place once or until the refresh token expires or the user removes the app from the approved list?
Am i missing something?
Request in order:
/oauth2/authorize "Approve" or "Deny" (every time) /oauth2/ token (Grant type Authorization code)
Is there a way for the user to ONLY "Approve" or "Deny" once?
Thanks in advance!