GithubHelp home page GithubHelp logo

sorcery / sorcery Goto Github PK

View Code? Open in Web Editor NEW
1.4K 1.4K 222.0 1.53 MB

Magical Authentication

Home Page: https://rubygems.org/gems/sorcery

License: MIT License

Ruby 98.87% HTML 1.00% JavaScript 0.01% Dockerfile 0.11% Shell 0.02%
authentication rails ruby sorcery

sorcery's Introduction

Sorcery: Magical Authentication

Gem Version Gem Downloads Build Status

Magical Authentication for Rails. Supports ActiveRecord, DataMapper, Mongoid and MongoMapper.

Inspired by Restful Authentication, Authlogic and Devise. Crypto code taken almost unchanged from Authlogic. OAuth code inspired by OmniAuth and Ryan Bates's Railscast about it.

Philosophy

Sorcery is a stripped-down, bare-bones authentication library, with which you can write your own authentication flow. It was built with a few goals in mind:

  • Less is more - less than 20 public methods to remember for the entire feature-set make the lib easy to 'get'.
  • No built-in or generated code - use the library's methods inside your own MVC structures, and don't fight to fix someone else's.
  • Magic yes, Voodoo no - the lib should be easy to hack for most developers.
  • Configuration over Confusion - Centralized (1 file), Simple & short configuration as possible, not drowning in syntactic sugar.
  • Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.

Table of Contents

  1. Useful Links
  2. API Summary
  3. Installation
  4. Configuration
  5. Full Features List by Module
  6. Planned Features
  7. Contributing
  8. Contact
  9. License

Useful Links

Check out the tutorials in the wiki for more:

API Summary

Below is a summary of the library methods. Most method names are self explaining and the rest are commented:

Core

require_login # This is a before action
login(email, password, remember_me = false)
auto_login(user) # Login without credentials
logout
logged_in? # Available in views
current_user # Available in views
redirect_back_or_to # Use when a user tries to access a page while logged out, is asked to login, and we want to return him back to the page he originally wanted
@user.external? # Users who signed up using Facebook, Twitter, etc.
@user.active_for_authentication? # Add this method to define behaviour that will prevent selected users from signing in
@user.valid_password?('secret') # Compares 'secret' with the actual user's password, returns true if they match
User.authenticates_with_sorcery!

HTTP Basic Auth

require_login_from_http_basic # This is a before action

External

login_at(provider) # Sends the user to an external service (Facebook, Twitter, etc.) to authenticate
login_from(provider) # Tries to login from the external provider's callback
create_from(provider) # Create the user in the local app database
build_from(provider) # Build user instance using user_info_mappings

Remember Me

auto_login(user, should_remember = false) # Login without credentials, optional remember_me
remember_me!
forget_me!
force_forget_me! # Forgets all sessions by clearing the token, even if remember_me_token_persist_globally is set to true

Reset Password

User.load_from_reset_password_token(token)
@user.generate_reset_password_token! # Use if you want to send the email by yourself
@user.deliver_reset_password_instructions! # Generates the token and sends the email
@user.change_password(new_password)
@user.change_password!(new_password) # Same as change_password but raises exception on save

Session Timeout

invalidate_active_sessions! #Invalidate all sessions with a login_time or last_action_time before the current time. Must Opt-in

User Activation

User.load_from_activation_token(token)
@user.setup_activation
@user.activate!

Please see the tutorials in the github wiki for detailed usage information.

Installation

Add this line to your application's Gemfile:

gem 'sorcery'

And then execute:

$ bundle

Or install it yourself as:

$ gem install sorcery

Configuration

Run the following command to generate the core migration file, the initializer file and the User model class.

$ rails generate sorcery:install

Run the following command generate the migrations files for remember_me and reset_password submodules and will create the initializer file (and add submodules to it), and create the User model class.

$ rails generate sorcery:install remember_me reset_password

Run the following command to generate the core migration file, the initializer and change the model class (in the initializer and migration files) to the class Person (and its pluralized version, 'people')

$ rails generate sorcery:install --model Person

Run the following command to generate only the migration files for the specified submodules and will add them to the initializer file.

$ rails generate sorcery:install http_basic_auth external remember_me --only-submodules

Inside the initializer, the comments will tell you what each setting does.

Full Features List by Module

Core (see lib/sorcery/model.rb and lib/sorcery/controller.rb):

  • Login / logout, optional return user to requested url on login, configurable redirect for non-logged-in users.
  • Password encryption, algorithms: bcrypt (default), MD5, SHA-1, SHA-256, SHA-512, AES or custom. Configurable stretches and salt.
  • Configurable attribute names for username, password and email.
  • Allow multiple fields to serve as username.

User Activation (see lib/sorcery/model/submodules/user_activation.rb):

  • User activation by email with optional success email
  • Configurable attribute names
  • Configurable mailer, method name, and attribute name
  • Configurable temporary token expiration
  • Optionally prevent non-active users to login

Reset Password (see lib/sorcery/model/submodules/reset_password.rb):

  • Reset password with email verification
  • Configurable mailer, method name, and attribute name
  • Configurable temporary token expiration
  • Configurable time between emails (hammering protection)

Remember Me (see lib/sorcery/model/submodules/remember_me.rb):

  • Remember me with configurable expiration
  • Configurable attribute names
  • Configurable to persist globally (supporting multiple browsers at the same time), or starting anew after each login

Session Timeout (see lib/sorcery/controller/submodules/session_timeout.rb):

  • Configurable session timeout
  • Optionally session timeout will be calculated from last user action
  • Optionally enable a method to clear all active sessions, expects an invalidate_sessions_before datetime attribute.

Brute Force Protection (see lib/sorcery/model/submodules/brute_force_protection.rb):

  • Brute force login hammering protection
  • configurable logins before lock and lock duration

Basic HTTP Authentication (see lib/sorcery/controller/submodules/http_basic_auth.rb):

  • A before action for requesting authentication with HTTP Basic
  • Automatic login from HTTP Basic
  • Automatic login is disabled if session key changed

Activity Logging (see lib/sorcery/model/submodules/activity_logging.rb):

  • Automatic logging of last login, last logout, last activity time and IP address for last login
  • Configurable timeout by which to decide whether to include a user in the list of logged in users

External (see lib/sorcery/controller/submodules/external.rb):

  • OAuth1 and OAuth2 support (currently: Twitter, Facebook, Github, Google, Heroku, LinkedIn, VK, LiveID, Xing, Salesforce)
  • Configurable database column names
  • Authentications table

Planned Features

  • Passing a block to encrypt, allowing the developer to define his own mix of salting and encrypting
  • Forgot username, maybe as part of the reset_password module
  • Scoping logins (to a subdomain or another arbitrary field)
  • Allowing storing the salt and encrypted password in the same DB field for extra security
  • Other reset password strategies (security questions?)
  • Other brute force protection strategies (captcha)

Have an idea? Let us know, and it might get into the gem!

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/Sorcery/sorcery.

Contact

Feel free to ask questions using these contact details:

Current Maintainers:

Past Maintainers:

License

The gem is available as open source under the terms of the MIT License.

sorcery's People

Contributors

9mm avatar arnvald avatar asmsuechan avatar banyan avatar brianp avatar ch4s3 avatar chhlga avatar ckruse avatar dankimio avatar ebihara99999 avatar joshbuker avatar juike avatar kbighorse avatar kirs avatar kuboon avatar kyuden avatar mladenilic avatar mlainez avatar noamb avatar palkan avatar pirj avatar rafaelsachetto avatar rubiety avatar supremebeing7 avatar tyrauber avatar ubermajestix avatar weimeng avatar wendy0402 avatar willnet avatar willywg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sorcery's Issues

:session_timeout broken after hard reboot of server?

Rails app using Rails 5.0.2, Thin web server, Mac OS X 10.12.6.
I had to force-quite my web server running in Terminal.app and when I restarted everything I get the error: comparison of Float with String failed in the browser (using better_errors). In the server console it shows:
ArgumentError - comparison of Float with String failed:
sorcery (0.10.2) lib/sorcery/controller/submodules/session_timeout.rb:49:in sorcery_session_expired?' sorcery (0.10.2) lib/sorcery/controller/submodules/session_timeout.rb:40:in validate_session'
activesupport (5.0.2) lib/active_support/callbacks.rb:382:in block in make_lambda' activesupport (5.0.2) lib/active_support/callbacks.rb:169:in block (2 levels) in halting'
actionpack (5.0.2) lib/abstract_controller/callbacks.rb:12:in block (2 levels) in <module:Callbacks>' activesupport (5.0.2) lib/active_support/callbacks.rb:170:in block in halting'
...
If I remove the :session_timeout module from the config file and restart it works and I can log in. As soon as I re-enable :session_timeout the same error happens. I'm stumped. I've rebooted the laptop again and still the same.

Move and/or merge existing pull requests

There's plenty of open pull requests on NoamB/sorcery. We can either merge them on NoamB/sorcery and then pull the commits directly onto Sorcery/sorcery, or encourage moving the PR to Sorcery/sorcery and merging there instead. If we mix and match however, there's bound to be a history conflict and the Sorcery/sorcery history would get a bit messy with merging NoamB/sorcery onto Sorcery/sorcery multiple times; so we should probably choose one of the two options and proceed with that method only.

External page in Wiki causes overwriting of AR attributes which results in Save errors

https://github.com/Sorcery/sorcery/wiki/External contains instructions for creating a migration

rails g sorcery:install external --only-submodules

Which will create:

class SorceryExternal < ActiveRecord::Migration
  def change
    create_table :authentications do |t|
      t.integer :user_id, :null => false
      t.string :provider, :uid, :null => false
    
      t.timestamps
    end
  end
end

And the content of the model file, which creates accessors overriding the AR accessors with the same names.

# app/models/authentication.rb
class Authentication < ActiveRecord::Base
  attr_accessor :user_id, :provider, :uid
  belongs_to :user
end

This results in errors on save when calling @user = create_from(provider) and more specifically here:

sorcery_config.authentications_class.create!(

Here's a pry session attempting to save the record:

pry(User)> Authentication.create! :user_id=>33, :provider=>"google", :uid=>"820179..."
   (10.5ms)  BEGIN
  SQL (5.1ms)  INSERT INTO "authentications" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"  [["created_at", "2017-06-09 18:52:10.490163"], ["updated_at", "2017-06-09 18:52:10.490163"]]
   (0.8ms)  ROLLBACK
ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "user_id" violates not-null constraint
DETAIL:  Failing row contains (13, null, null, null, 2017-06-09 18:52:10.490163, 2017-06-09 18:52:10.490163).
: INSERT INTO "authentications" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"
from /Users/andrei_says_/.rvm/gems/ruby-2.3.1/gems/rack-mini-profiler-0.10.2/lib/patches/db/pg.rb:93:in `exec'


Also:

[9] pry(User)> a1 = Authentication.new :user_id=>33, :provider=>"google", :uid=>"820179..."
=> #<Authentication:0x007f9adf993140 id: nil, user_id: nil, provider: nil, uid: nil, created_at: nil, updated_at: nil>

[10] pry(User)> a1.provider
=> "google"
[11] pry(User)> a1.user_id
=> 33
[12] pry(User)> a1.uid
=> "820179..."
[13] pry(User)> a1.save!
   (3.8ms)  BEGIN
  SQL (3.3ms)  INSERT INTO "authentications" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"  [["created_at", "2017-06-09 18:56:51.193465"], ["updated_at", "2017-06-09 18:56:51.193465"]]
   (3.6ms)  ROLLBACK
ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "user_id" violates not-null constraint
DETAIL:  Failing row contains (15, null, null, null, 2017-06-09 18:56:51.193465, 2017-06-09 18:56:51.193465).
: INSERT INTO "authentications" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"
from /Users/andrei_says_/.rvm/gems/ruby-2.3.1/gems/rack-mini-profiler-0.10.2/lib/patches/db/pg.rb:93:in `exec'

As a solution to this, I propose removing the attr_accessors in the model:

# app/models/authentication.rb
class Authentication < ActiveRecord::Base
  # attr_accessor :user_id, :provider, :uid
  belongs_to :user
end

Which branch should I use for implementation?

Hello.

It's just a bit question. I'm not sure the branch operation of this repository. I recognize branch 0-9-x is release branch. But recent commit is on master. Which branch should I use for implementation?

Server side session termination

How do i do this: I want to do server side session termination - hacker can still login into the system using cookie even after the user has loges out ....

SocketError when calling login_at

Failed to open TCP connection to api.twitter.com:443 (getaddrinfo: nodename nor servname provided, or not known)

I assume this is due to the DDoS attack on Twitter today. I guess my question is, should this error be thrown by login_at? And if so, should we add using begin/rescue to the documentation for it?

OAuth2::Error in OauthsController#callback

I try facebook login referring this external wiki .
but I get this error

OAuth2::Error in OauthsController#callback

if @user = login_from(provider)
{"access_token":"xxxxxxx", "token_type":"bearer","expires_in":5183999}

What should I do?

this is log

/Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/fog-xenserver-0.2.3/lib/fog/utilities.rb:4: warning: constant ::Fixnum is deprecated
Started GET "/oauth/callback?provider=facebook&code=AQBOQE_RUqzhWDcY41CIHtghbVu98NHYzS14nEcK5HPZQBsKCol3h1_f79HaUTb3NVGXc1PvOVjEfc_wZcT_xISBNiibW3gygu1Z3zT1O4vSFPXm1l6B_jZAy7WwkEe-GfsteRrQmbIcmxA5pICQs85PEb_S5QyDsBUDoEaj_qXm7cmJp_kajq4FiP9iIU388MWwvkE-8v3Rx4MqE4GsSdlB4-B9jrX8cBNmDF7Ehs_xxDBwbRK-izHUSUaIl8LSjLlt3M7jFzskjH0uupiytbZ9KorLWdRGdweuZnYfuKsRt7V75qOWajI9kEr5GEkDjnC5f28WrB_Y5Igk38FZu5I6IU38agfYeP4XHC2uKYqOqA" for 127.0.0.1 at 2017-07-12 06:46:18 +0900
Processing by OauthsController#callback as HTML
  Parameters: {"provider"=>"facebook", "code"=>"AQBOQE_RUqzhWDcY41CIHtghbVu98NHYzS14nEcK5HPZQBsKCol3h1_f79HaUTb3NVGXc1PvOVjEfc_wZcT_xISBNiibW3gygu1Z3zT1O4vSFPXm1l6B_jZAy7WwkEe-GfsteRrQmbIcmxA5pICQs85PEb_S5QyDsBUDoEaj_qXm7cmJp_kajq4FiP9iIU388MWwvkE-8v3Rx4MqE4GsSdlB4-B9jrX8cBNmDF7Ehs_xxDBwbRK-izHUSUaIl8LSjLlt3M7jFzskjH0uupiytbZ9KorLWdRGdweuZnYfuKsRt7V75qOWajI9kEr5GEkDjnC5f28WrB_Y5Igk38FZu5I6IU38agfYeP4XHC2uKYqOqA"}
Completed 500 Internal Server Error in 204ms (ActiveRecord: 0.0ms)


  
OAuth2::Error (: 
{"access_token":"EAAb0SDXOsEABAGo44x3CS18CSVNlQkrsarKmVTnRySt6OYOI8XF2tOlHP8nyv9tovSJKKS0YpFQElciGF4jRnmcYxNzJu339Uy7JZAE9edTZBuqbP5Lu4lOrI1WDs2M9nSb6StopxccnrYhnQkZCcJHQEkPkrnPpHOaUP1ZBIwZDZD","token_type":"bearer","expires_in":5183999}):
  
app/controllers/oauths_controller.rb:12:in `callback'
  Rendering /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
  Rendering /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
  Rendered /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (4.6ms)
  Rendering /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.2ms)
  Rendering /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.2ms)
  Rendered /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/actionpack-5.0.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (97.4ms)

OauthsController#callback

[1] pry(#<OauthsController>)> params
=> <ActionController::Parameters {"provider"=>"facebook", "code"=>"AQD6WCCmUNBYJAU6dRHaWPGZW2gXujz8iMUl9iYVKgmteOUMPH7ODl65pvOmsoY-z4LcM6Ja1w88D6PsbgQxxPiZRf6TdPHKoF-UKnYOiKqfcduIM72agsaVaUXrzVIeIhuc1lYupzuGxncSJnktBBsxXlw_5cAd-jMyeu1E-_XzL9UCnJ1EZBA_ys6QIKdzSjKAAmKvhXw5yj0cJ8Qq5rlzAuHkGUCsgCSpjcUV1HoiOjEZBew6BNXWbhg3rubs0-GAYtvSFiew0l2HbapaN9yAeQfnOEDnvujMjyQaXi3wEafR3SGb0E9bVl3FgpHd-BiVPmQ1OxemIPZX5ffH50B6r-j9VwjTuZ8MBdiZ7Tsbdg", "controller"=>"oauths", "action"=>"callback"} permitted: false>
[2] pry(#<OauthsController>)> login_from("facebook")
OAuth2::Error: : 
{"access_token":"EAAb0SDXOsEABAPtuab8FYwF7yESinN48E2fSuYEqZBQOPbD4TUzvOhZBr4xyGlFpQVWqzkyckfD3JbPsemKimYcE9dCy9faBr3spoL5C36vpughq9HWGuKlJ15e8XxjdakmAkfOoYyprpWCSYZAU8ncvSf9u9K7yskotIrxPgZDZD","token_type":"bearer","expires_in":5182749}
from /Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/oauth2-1.3.0/lib/oauth2/client.rb:149:in `get_token'
[5] pry(#<OauthsController>)> 

get_token method in Oauth2's client.rb
options[:raise_errors]
=> true

and I get error get_access_token in sorcery's oauth2.rb

    20:       def get_access_token(args, options = {})
 => 21:         binding.pry
    22: 		client = build_client(options)
    23:         client.auth_code.get_token(
    24:           args[:code],
    25:           {
    26:             redirect_uri: @callback_url,
    27:             parse: options.delete(:parse)
    28:           },
    29:           options
    30:         )
    31:       end

[1] pry(#<Sorcery::Providers::Facebook>)> options
=> {:token_url=>"oauth/access_token", :mode=>:query, :param_name=>"access_token", :parse=>:query}
[2] pry(#<Sorcery::Providers::Facebook>)> build_client(options)
=> #<OAuth2::Client:0x007fbdb3762118
 @id="1957440837824576",
 @options=
  {:authorize_url=>"/oauth/authorize",
   :token_url=>"oauth/access_token",
   :token_method=>:post,
   :auth_scheme=>:request_body,
   :connection_opts=>
    {:ssl=>
      {:ca_file=>
        "/Users/horiekentarou/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/sorcery-0.10.2/lib/sorcery/controller/submodules/../../protocols/certs/ca-bundle.crt"}},
   :connection_build=>nil,
   :max_redirects=>5,
   :raise_errors=>true,
   :mode=>:query,
   :param_name=>"access_token",
   :parse=>:query},
 @secret="****",
 @site="https://graph.facebook.com">

Rails 5 , require login error

I am trying to upgrade my rails version from 4.2 to 5.0, After upgrading rails version. I am facing this error
Before process_action callback :require_login has not been defined

This is my application_controller.rb code

before_filter :require_login

I am using sorcery 0.9.1.

User can not be loaded from other_sources when session expires in current request

I'm using such submodules:

[:remember_me, :reset_password, :user_activation, :brute_force_protection, :session_timeout, :activity_logging]

I logged in with remember_me option. And leaved tab opened for more that 1 hour. Then I reloaded page and was redirected to login page. Then I reloaded page again and I was logged in. So I started digging code and found this:

        base.prepend_before_action :validate_session

          def validate_session
            session_to_use = Config.session_timeout_from_last_action ? session[:last_action_time] : session[:login_time]
            if session_to_use && sorcery_session_expired?(session_to_use.to_time)
              reset_sorcery_session
              # USER IS DEFINED THERE
              @current_user = nil     
            else
              session[:last_action_time] = Time.now.in_time_zone
            end
          end

def current_user

      def current_user
        unless defined?(@current_user)
          # USER IS DEFINED SO THIS WILL BE SKIPPED IN CURRENT REQUEST
          @current_user = login_from_session || login_from_other_sources || nil
        end
        @current_user
      end

So maybe remove_instance_variable :@current_user if defined? @current_user will be better option. And IMHO this should be done everywhere where user is settled to nil.

And also I found this place. I don't understand the reason of that ELSE block:

Get endorsement from original creator

While not technically necessary, it would be nice to get @NoamB's approval for moving Sorcery to this organization. Sorcery is still very much in use, but until it's moved to an organization it remains difficult to maintain.

@NoamB has been contacted by @arnvald and myself, but there has been no response yet as far as I'm aware.

How to generate new session token

How to generate new session token for users upon authentication. When a user has logged in successfully after that how to create new session token.

Facebook provider doesn't work with Facebook API version 'v2.3' and above

Facebook changed access_token format response in version 2.3, so now it returns :json format. See https://developers.facebook.com/docs/apps/changelog

Oauth2 gem can handle :json, but in facebook provider there is no option to change :parse option from :query to :json.

In facebook.rb in method process_callback we have :parse option:

def process_callback(params, _session)
        args = {}.tap do |a|
          a[:code] = params[:code] if params[:code]
        end

        get_access_token(args, token_url: token_url, mode: mode,
                               param_name: param_name, parse: parse)
end

But it's always :query (@parse = :query) and there is no ability to change it via config.

Class method encrypt conflicts with attr_encrypted

I'm trying to use the gems Sorcery and attr_encrypted both on the User model, which is defined like this (simplified):

class User < ActiveRecord::Base
  authenticates_with_sorcery!

  attr_encrypted :otp_secret, key: :otp_encryption_key
end

Both Sorcery and attr_encrypted will define the class method encrypt and that makes it unable to use both gems in one class. I could move the otp_secret to another class to work around this problem but I prefer not to.

Q: Is the Class.encrypt method considered part of the public API and if not, would you consider to rename it? (to e.g. encrypt_tokens)

Error: Undefined method `authenticates_with_sorcery!' for User:Class

I get the "Undefined method `authenticates_with_sorcery!' for User:Class" error in Rails 5.0.1 with Mongoid 6.0.3 and Sorcery 0.10.0. I added the authenticates_with_sorcery! beneath the includes in my model but still getting the error. As long as I use Rails 5.0.1, Mongoid 6.0.3 and Sorcery 0.9.1 it works fine. Is there any change I have to make with loading the functions?

Regards,
Sven

Override current_user to remove certain fields?

Is it possible to override current_user so it doesn't contain certain fields?

For instance can we remove :crypted_password_attribute_name from being included in current_user, or internal_secret_field?

Password reset token leak via HTTP referer

The reset password token is leaking through the HTTP referer header ... This happens when user clicks at the link sent to their email and when the page is rendered with the token at the URL, if there is some subsequent requests to CDN/analytics or malicious JS , the token will be present at the REFERER header of this requests... As reported at here: https://robots.thoughtbot.com/is-your-site-leaking-password-reset-links A solution will be to store the token to session and then redirect to the page without the token at the URL ...
Is there any chance to change this behavior to current versions?

Can't remove crypted_password or salt from User model

NoMethodError:
       undefined method `crypted_password' for #<User:0x007fac4838f918>
       Did you mean?  encrypt_password
     # /Users/jbuker/.rvm/gems/ruby-2.3.1/gems/sorcery-0.9.1/lib/sorcery/model.rb:146:in `external?'
     # /Users/jbuker/.rvm/gems/ruby-2.3.1/gems/sorcery-0.9.1/lib/sorcery/model/submodules/user_activation.rb:127:in `send_activation_success_email?'
     # /Users/jbuker/.rvm/gems/ruby-2.3.1/gems/sorcery-0.9.1/lib/sorcery/model/submodules/user_activation.rb:111:in `activate!'

For my particular use-case, I need users that only authenticate with external providers. Currently it works, but if I try to remove the crypted_password and/or salt fields from User, it gives this error. I tried setting the config to use nil or '' instead, but that also gives errors.

When we figure out how to go forward with the modularization, we should have the option to exclude the usual crypted_password setup.

Is it fine to add undocumented option to initializer.rb?

As I found the undocumented option which is about Github's scope with external module in Github OAuth. I think it is better if below code is inserted in initializer.rb, because it takes time to find the option out if someone who uses Github OAuth with external module and want to manage the Github's scope.

config.github.scope = 'user, repo'

Memory consumption problem

Based on result from
CUT_OFF=1 bundle exec derailed bundle:mem
it takes 6 megabytes to load this gem
sorcery: 6.1797 MiB (Also required by: sorcery/engine) sorcery/protocols/oauth2: 2.5352 MiB oauth2: 2.5352 MiB oauth2/client: 1.1797 MiB oauth2/response: 1.1055 MiB
If I am not using oauth2 gem still load it into memory.
Can we drop this forced dependency on oauth2?

Upgrading from Rails 4.2.0 to 5.1.2 causes the following error:

Before process_action callback :require_login has not been defined. Here is my HomeController:

class HomeController < ApplicationController

testing new keys

skip_before_action :require_login, :only => [:index]
end

Here is the stack-trace:

ArgumentError - Before process_action callback :require_login has not been defined:
activesupport (5.1.2) lib/active_support/callbacks.rb:710:in block (2 levels) in skip_callback' activesupport (5.1.2) lib/active_support/callbacks.rb:706:in block in skip_callback'
activesupport (5.1.2) lib/active_support/callbacks.rb:622:in block in __update_callbacks' activesupport (5.1.2) lib/active_support/callbacks.rb:620:in __update_callbacks'
activesupport (5.1.2) lib/active_support/callbacks.rb:705:in skip_callback' actionpack (5.1.2) lib/abstract_controller/callbacks.rb:181:in block (3 levels) in module:ClassMethods'
actionpack (5.1.2) lib/abstract_controller/callbacks.rb:74:in block in _insert_callbacks' actionpack (5.1.2) lib/abstract_controller/callbacks.rb:73:in _insert_callbacks'
actionpack (5.1.2) lib/abstract_controller/callbacks.rb:180:in block (2 levels) in <module:ClassMethods>' app/controllers/home_controller.rb:3:in class:HomeController'
app/controllers/home_controller.rb:1:in `<top (required)>'

I am sure it is something basic that I do not know about Rails 5 upgrade. Please advise

I am using the latest version of Sorcery as shown below:

Bharat:~/vgoffice_512
โ†’ gem list | grep sorcery
sorcery (0.11.0)

Bharat:~/vgoffice_512

Thanks.

Add before_session_timeout callback method

It will be very useful to add before_session_timeout callback method to the session_timeout module, because after timeout the user instance is lost and it is impossible to clean dependent records.

Conditional validation does not work with Rails 5

Hi,

the validation does not seem to work (using Rails 5.1.1) as described in the Wiki:

validates :password, length: { minimum: 3 }, if: -> { new_record? || changes[:crypted_password] }
validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] }
validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] }

Whenever i update the password, the validation gets skipped silently.

After i changed it to this, it works:

validates :password, length: { minimum: 3 }, if: -> { new_record? || :crypted_password_changed? }
validates :password, confirmation: true, if: -> { new_record? || :crypted_password_changed? }
validates :password_confirmation, presence: true, if: -> { new_record? || :crypted_password_changed? }

Does anyone know about this?

Discussion about the state and a near-term plan

This is taken from a part of the conversations here.

splitting the external providers into its own gem should probably happen sooner rather than later.
@Ch4s3 perhaps we should set a time for discussion on the state of Sorcery and our near-term plans for it?

Rails 5 Release

Creating this issue to discuss releasing a version that fixes all the rails 5 deprecation warnings. Probably won't have time to develop some of the more major items, so I was thinking maybe call this release 0.10.0 and have it be the last release before we go through the existing code with a fine tooth comb and modularize the various features (1.0.0). IIRC, master branch solves most if not all of the problems, so it will be more going through and verifying it's production ready.

@Ch4s3, what are your thoughts and availability? I'll likely be able to dedicate large amounts of time over the next week or two to getting this done.

Error: undefined method `login'. 'Rails 5' and 'ruby-grape'.

Hello.
Is it possible use core sorcery's methods ('login' for example) in the 'ruby-grape' API controller with Rails 5 ?
Code example:
class Users < Grape::API
resource :users do
post "login" do
if @current_user = login(params[:email], params[:password])
@current_user
else
error!("Invalid email/password combination", 401)
end
end
end
end
I receive error "undefined method `login'".

Module including
include Sorcery::Controller
to the class Users < Grape::API is not success for me.
Thanks for the answer.

Redirect NoamB/sorcery to Sorcery/sorcery

NoamB/sorcery is probably going to be visited for a while after the transition, so having it link to the new repo would be preferable. I've opened a PR on NoamB/sorcery for this.

1.0 Roadmap

I'm starting this issue to discuss our path to a 1.0 release. Please feel free to request features here and discuss areas that need improvement or bug fixes.

  • OAuth / Provider test mocking (see omniauth mocking)
    • Fake successful auth call for any provider
    • Fake unsuccessful auth call for any provider
  • Token auth #70 probably with something like jwt
  • Support usage of multiple authentications for a single user (not sure if this is already implemented)
  • Support accounts without passwords (strictly external auth)
  • Contribution guide
  • Consider OmniAuth re NoamB/sorcery#533
  • Issue template
  • Improve docs

ported from here

InstanceMethods of remember_me for Model aren't included

Why can't I use methods forget_me! and remember_me! as they're missing for the User class?
Submodule is enabled and everything works fine, e.g. login when remember is false

Rails.application.config.sorcery.submodules = [:remember_me]
if @user = login(email, params[:password], params[:remember])
    render json: {'login' => 'successful'}.to_json
else
    render json: {'login' => 'failed'}.to_json
end
class User < ApplicationRecord
  authenticates_with_sorcery!
...
end

Necessary fields are also created in the database

Add documentation about magic login

Need to add documentation about magic login to wiki.
The codes have been already merged.
See: #95

@Tomomichi, would you add documentation or give me code snippets you really use?
I thought I could, but it appears to be somehow a hard work to arrange a sandbox app...

Rails 5 | Remember_me_token not being set as a cookie in the browser

Rails 5

I have followed the sorcery tutorial on implementing the remember_me feature but when I wrote my feature specs to test user login and that a remember_me_token cookie was set, the test failed. I then started up the server and actually went through the login in process and checked the browser and remember_me_token cookie was not being set in the browser.

When I manually place the following code, the cookie is there in the browser and the tests pass. Isn't Sorcery suppose to take care of this so that I don't have to?

cookies.signed[:remember_me_token] = { 
    value: @user.remember_me_token, 
    expires: @user.last_login_at + 7.days 
}

Facebook as an external provider not including user info as defined in user_info_mapping.

I am trying to set up external providers in my app. I have followed the guide listed here: https://github.com/Sorcery/sorcery/wiki/External

Google works fine and I receive the email as requested. However when trying Facebook the data is not being received from Facebook. I have checked the @user_hash and it seems it's only including "name" and "id".

This is what my Sorcery config looks like.

config.external_providers = %i[facebook google]

config.facebook.key = Rails.application.secrets.facebook_app_id
config.facebook.secret = Rails.application.secrets.facebook_app_secret
config.facebook.callback_url = "#{ENV['WEB_URL']}/oauth/callback?provider=facebook"
config.facebook.user_info_mapping = { email: 'email', first_name: 'first_name', last_name: 'last_name' }
config.facebook.scope = 'email'
config.facebook.display = 'page'

config.google.key = Rails.application.secrets.google_client_id
config.google.secret = Rails.application.secrets.google_client_secret
config.google.callback_url = "#{ENV['WEB_URL']}/oauth/callback?provider=google"
config.google.user_info_mapping = { email: 'email' }

And this is what my oauths controller looks like.

class OauthsController < ApplicationController
  skip_before_action :require_login

  def oauth
    login_at(params[:provider])
  end

  def callback
    provider = auth_params[:provider]
    if @user = login_from(provider)
      redirect_to root_path
    else
      @user = create_from(provider)
      @user.activate!
      reset_session
      auto_login(@user)
      redirect_to root_path
    end
  end

  private

  def auth_params
    params.permit(:code, :provider)
  end
end

Command returns error

I've tried to run this command available on the README page

rails generate sorcery:install http_basic_auth external remember_me --only-submodules

and it is returning me

/Users/username/.asdf/installs/ruby/2.4.1/lib/ruby/gems/2.4.0/gems/thor-0.20.0/lib/thor/actions/file_manipulation.rb:263:in `binread': No such file or directory @ rb_sysopen - /Users/username/workspace/app-name/config/initializers/sorcery.rb (Errno::ENOENT)

The error occurs at

sorcery-0.11.0/lib/generators/sorcery/install_generator.rb:39:in `configure_initializer_file'

where gsub_file sorcery_config_path, gsub is running regex on a non-existing file at that point. Can someone guide me on how I could run the command successfully?

Cannlot load such file bcrypt_ext - Windows 10 - ruby 2.3.3 - rails 5.1.2

I've created a new rails application and added sorcery as a required gem to my gemfile.
When bundling and then trying to start the console I get the following error message:

C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/activesupport-5.1.2/lib/active_support/dependencies.rb:292:in `require': cannot load such file -- bcrypt_ext (LoadError)
        from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/activesupport-5.1.2/lib/active_support/dependencies.rb:292:in `block in require'
....

Googled a bit and it seems that bcrypt has a problem when installing the right version for windows.
For example see this issue.

Anyway to add this fix to the Sorcery dependencies?

`#update_attributes` uses `#update_all` inside it

Sorcery::Adapters::ActiveRecordAdapter#update_attributes uses #update_all inside instead of simply #update.
I think it intends one active record object to be updated because the code does it, so #updated_all is not necessary.

If I open a PR, I plan to change from

@model.class.where(:"#{primary_key}" => @model.send(:"#{primary_key}")).update_all(attrs)

to

@model.class.find_by(:"#{primary_key}" => @model.send(:"#{primary_key}")).update(attrs)

The good points are:

  • keep the code simple
  • return boolean, not integer ( seems more understandable to me )

Thank you for watching, I would appreciate it if someone gives me suggestion.

How can I get access_token in using github aouth?

Can I get GitHub's access_token , when I use GitHub aouth External with?

I've checked Sorcery handles GitHub's access token as access_token.
Is there any option or idea that gets Gitbub's access_token ?

Update Documentation

While working on my personal site, I've noticed several spots where the documentation is starting to show its age. Opening this ticket to remind myself to go back and update it / discuss any issues that may arise. Also, while each individual module seems to be well documented, there doesn't seem to be a general "get started" article yet; I'm thinking about creating that with the assumption of an app that has all submodules enabled.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.