diff options
-rw-r--r-- | app/controllers/application_controller.rb | 15 | ||||
-rw-r--r-- | app/models/concerns/token_authenticatable.rb | 31 | ||||
-rw-r--r-- | app/models/user.rb | 3 | ||||
-rw-r--r-- | config/initializers/devise.rb | 4 |
4 files changed, 48 insertions, 5 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d58890fa33b..6128f6e48ed 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,7 @@ require 'gon' class ApplicationController < ActionController::Base + before_filter :authenticate_user_from_token! before_filter :authenticate_user! before_filter :reject_blocked! before_filter :check_password_expiration @@ -28,6 +29,20 @@ class ApplicationController < ActionController::Base protected + # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example + def authenticate_user_from_token! + user_token = params[:user_token].presence + user = user_token && User.find_by_authentication_token(user_token.to_s) + + if user + # Notice we are passing store false, so the user is not + # actually stored in the session and a token is needed + # for every request. If you want the token to work as a + # sign in token, you can simply remove store: false. + sign_in user, store: false + end + end + def log_exception(exception) application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace application_trace.map!{ |t| " #{t}\n" } diff --git a/app/models/concerns/token_authenticatable.rb b/app/models/concerns/token_authenticatable.rb new file mode 100644 index 00000000000..9b88ec1cc38 --- /dev/null +++ b/app/models/concerns/token_authenticatable.rb @@ -0,0 +1,31 @@ +module TokenAuthenticatable + extend ActiveSupport::Concern + + module ClassMethods + def find_by_authentication_token(authentication_token = nil) + if authentication_token + where(authentication_token: authentication_token).first + end + end + end + + def ensure_authentication_token + if authentication_token.blank? + self.authentication_token = generate_authentication_token + end + end + + def reset_authentication_token! + self.authentication_token = generate_authentication_token + save + end + + private + + def generate_authentication_token + loop do + token = Devise.friendly_token + break token unless self.class.unscoped.where(authentication_token: token).first + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 6d7350881df..19104336598 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -52,6 +52,7 @@ require 'file_size_validator' class User < ActiveRecord::Base include Gitlab::ConfigHelper extend Gitlab::ConfigHelper + include TokenAuthenticatable default_value_for :admin, false default_value_for :can_create_group, gitlab_config.default_can_create_group @@ -60,7 +61,7 @@ class User < ActiveRecord::Base default_value_for :projects_limit, gitlab_config.default_projects_limit default_value_for :theme_id, gitlab_config.default_theme - devise :database_authenticatable, :token_authenticatable, :lockable, :async, + devise :database_authenticatable, :lockable, :async, :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable attr_accessor :force_random_password diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 50669ece7a8..34f4f386988 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -155,10 +155,6 @@ Devise.setup do |config| # REST_AUTH_SITE_KEY to pepper) # config.encryptor = :sha512 - # ==> Configuration for :token_authenticatable - # Defines name of the authentication token params key - config.token_authentication_key = :private_token - # Authentication through token does not store user in session and needs # to be supplied on each request. Useful if you are using the token as API token. config.skip_session_storage << :token_auth |