Devise and OmniAuth. Vkontakte scope problem - ruby-on-rails-3

I just got setup using Rails 3, Devise and OmniAuth via https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview.
I want integrate my app with vkontakte.ru. When i'm using this config everything goes fine i can create user and i can access user data.
config.omniauth :vkontakte, 'xxx', 'xxx'
But when i'm adding a scope param
config.omniauth :vkontakte, 'xxx', 'xxx', {
:scope => "notify,friends,photos,notes,docs,pages,wall,offline"
}
omniauth raise failure(redirects me on user sign up page and dont store data in env["omniauth.auth"]).
I'll be appreciated for any help.

Seems like that's because of the attribute expires_in=0 in the VK oauth response, that indicates the long-living token that was requested by the 'offline' scope and leads to the instant token refreshing by omniauth.
I've just submitted patch here.

Related

Using Omniauth both for login with Devise as well as for accessing API's

In our application, we allow the user to access their data at different providers (Google Calendar, Microsoft Outlook, Facebook timeline, etc.) through the available API's, using Omniauth. For this we have an omniauth.rb with all the necessary configs, like:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], scope: 'email,user_posts,user_status,public_profile,manage_pages,instagram_basic'
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
name: 'google',
scope: 'email, profile, calendar.readonly',
access_type: 'offline',
prompt: 'select_account consent'
# etc...
end
Now we like to add login with Google as an alternative way to log in. Since we use Devise for our user session management, we'd like to use Devise's Omniauth features to implement login with an OAuth provider like Google. However, as soon as we make our model "omniauthable", the existing Omniauth functionality stops working throwing an No route matches [GET] "/auth/facebook" when trying to add an oauth account to access an API.
What is the correct way of combining the use of Omniauth in both Devise and in our own plain vanilla OAuth flow?
I found the answer myself: it's a matter of not using the thin wrapper of functionality that Devise adds to OmniAuth, but instead taking care of the OmniAuth routing yourself. I have described this approach here in the Devise Wiki.

Registrer new user from client app and authorize him with Doorkeeper

My Rails app is an oauth provider with Doorkeeper. Client registered apps could make API calls to retrieve informations from my service on behalf of user.
What i want to achieve is client app being able to :
register new user on my app via API dedicated endpoint
authorize this user and return an authorization code
In one or two calls, it doesn't matter.
Users are managed by Devise. I see how I can create user via Devise Invitable but I don't know how I can authorize this user with Doorkeeper because User must be authenticated before being authorized even with skip_authorization config.
I would like some help or just ideas to achieve that. Thanks
Finally I found a solution in Doorkeeper issues :
app = Doorkeeper::Application.where(uid: params[:client_id]).first
access_token = Doorkeeper::AccessToken.create!({
:application_id => app.id,
:resource_owner_id => #user.id,
:scopes => 'all',
:expires_in => Doorkeeper.configuration.access_token_expires_in,
:use_refresh_token => Doorkeeper.configuration.refresh_token_enabled?
})
#token_response = Doorkeeper::OAuth::TokenResponse.new(access_token)
puts #token_response.body
I can use this code in my user signup endpoint to create user and then return access_token.

Ember Simple Auth with Multiple Devise Scopes

I have the following scenario:
Rails app with User and Admin devise models, so I have two scopes.
Created on ember app on router:
Router.map(function() {
this.route('panel', function() {
this.route('login');
this.route('logout');
});
this.route('admin', function() {
this.route('login');
this.route('logout');
});
});
I'm using jj-abrams branch once my app is Ember 2.0
Both authenticating on /users/sign_in and /admins/sign_in
I followed steps on https://github.com/simplabs/ember-simple-auth/tree/master/packages/ember-simple-auth-devise#server-side-setup and authentication is working.
Ember is hitting the right urls after creating authenticators and adapters, but the problem is that ESA just have one session service. Once user or admin is logged in session.isAuthenticated is true and I don't know which scopes are logged in.
Which is the best way to proceed:
Add a role on user reply and set on session
Create a new session for admin user
I solved this problema creating 3 authenticators for each scope, and I handle each one.
It is a particular solution once I don't use other authenticators (OAuth2), but now I can check if authenticator:user, authenticator:admin, authenticator:manager was used on to login.
I have created checks on routes, so user can only access his panel, admin can access user and admin panel, and manager can access the whole system.
I've posted the ember and the API on github:
https://github.com/fernandes/ember-auth-web for the ember
https://github.com/fernandes/ember-auth-api for the devise api
ps: I think would be better to create sessions for each scope, but I don't know how to do it (and if its better or not), in this solution you can login one scope at once (not like devise on rails you can log with many scopes at once).

EmberAuth and Rails 3 - session cookie sticks around after signout, rails treats user as authenticated

I have an ember app accessing a Rails API with devise for authentication, more or less following the ember-auth-demo github project.
Everything works, but in my testing I've noticed that if I sign in and out and then try to register a new account, rails complains with:
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.2ms)
Googling has revealed that this is to prevent authenticated users from creating new accounts, which seems like a sound policy I shouldn't necessarily circumvent.
However, it's curious because my front-end ember app is not in an authenticated state. Looking at my local cookie store, remember_token is successfully destroyed on signout. However the session cookie is still hanging around. If I manually destroy that, then everything is back to working as expected, the user is not considered authenticated by the back-end app and processes the request normally.
For brevity, the relevant files are in this gist: https://gist.github.com/DVG/5975064 , but my sign_out functions are here:
#EmberAuth Signout Method
App.ApplicationController = Ember.Controller.extend
signOut: ->
App.Auth.signOut()
App.Auth.destroySession()
#Rails SessionsController#destroy
def destroy
return missing_params unless params[:auth_token]
resource = resource_class.find_by_authentication_token(params[:auth_token])
return invalid_credentials unless resource
resource.reset_authentication_token!
render json: {user_id: resource.id}, status: 200
end
The issue was I was storing the token in the session. Had to disable it with:
config.skip_session_storage = [:http_auth, :token_auth]
in the devise initializer

Soundcloud API 401 Unauthorized When Using /resolve

I'm using the 'Authenticating without the SoundCloud Connect Screen' method of authentication (see http://developers.soundcloud.com/docs#authentication). That's the method where you provide the whole shebang of credentials -- client_id, client_secret, username, and password. I'm also using the Ruby SDK.
# create client object with app and user credentials
client = Soundcloud.new(:client_id => 'YOUR_CLIENT_ID',
:client_secret => 'YOUR_CLIENT_SECRET',
:username => 'YOUR_USERNAME',
:password => 'YOUR_PASSWORD')
I am trying to use the client to resolve a user.
puts client.get('/resolve', :url => 'https://soundcloud.com/random-username').inspect
However, I keep getting a 401 Unauthorized returned by the client.
I can confirm that I am authenticating, because the following executes fine.
puts client.get('/me').username
Does anyone have any clues what I'm doing wrong?
I figured out that you need to include your client_id in every request.
puts client.get('/resolve', :url => 'https://soundcloud.com/random-username', client_id: 'YOUR_CLIENT_ID')