Commit 1a80d13a authored by Valery Sizov's avatar Valery Sizov

Multi-provider auth. LDAP is not reworked

parent 23674100
...@@ -42,10 +42,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController ...@@ -42,10 +42,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def handle_omniauth def handle_omniauth
if current_user if current_user
# Change a logged-in user's authentication method: # Add new authentication method
current_user.extern_uid = oauth['uid'] current_user.identities.find_or_create_by(extern_uid: oauth['uid'], provider: oauth['provider'])
current_user.provider = oauth['provider']
current_user.save
redirect_to profile_path redirect_to profile_path
else else
@user = Gitlab::OAuth::User.new(oauth) @user = Gitlab::OAuth::User.new(oauth)
...@@ -53,6 +51,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController ...@@ -53,6 +51,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
# Only allow properly saved users to login. # Only allow properly saved users to login.
if @user.persisted? && @user.valid? if @user.persisted? && @user.valid?
# binding.pry
sign_in_and_redirect(@user.gl_user) sign_in_and_redirect(@user.gl_user)
else else
error_message = error_message =
......
module ProfileHelper module ProfileHelper
def oauth_active_class(provider) def oauth_active_class(provider)
if current_user.provider == provider.to_s if current_user.identities.exists?(provider: provider.to_s)
'active' 'active'
end end
end end
......
class Identity < ActiveRecord::Base
belongs_to :user
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
scope :ldap, -> { where('provider LIKE ?', 'ldap%') }
end
\ No newline at end of file
...@@ -79,6 +79,7 @@ class User < ActiveRecord::Base ...@@ -79,6 +79,7 @@ class User < ActiveRecord::Base
# Profile # Profile
has_many :keys, dependent: :destroy has_many :keys, dependent: :destroy
has_many :emails, dependent: :destroy has_many :emails, dependent: :destroy
has_many :identities, dependent: :destroy
# Groups # Groups
has_many :members, dependent: :destroy has_many :members, dependent: :destroy
...@@ -113,7 +114,6 @@ class User < ActiveRecord::Base ...@@ -113,7 +114,6 @@ class User < ActiveRecord::Base
validates :name, presence: true validates :name, presence: true
validates :email, presence: true, email: {strict_mode: true}, uniqueness: true validates :email, presence: true, email: {strict_mode: true}, uniqueness: true
validates :bio, length: { maximum: 255 }, allow_blank: true validates :bio, length: { maximum: 255 }, allow_blank: true
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0} validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
validates :username, presence: true, uniqueness: { case_sensitive: false }, validates :username, presence: true, uniqueness: { case_sensitive: false },
exclusion: { in: Gitlab::Blacklist.path }, exclusion: { in: Gitlab::Blacklist.path },
...@@ -178,7 +178,6 @@ class User < ActiveRecord::Base ...@@ -178,7 +178,6 @@ class User < ActiveRecord::Base
scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) } scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all } scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') } scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') }
scope :ldap, -> { where('provider LIKE ?', 'ldap%') }
scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active } scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active }
# #
......
class AddIdentityTable < ActiveRecord::Migration
def up
create_table :identities do |t|
t.string :extern_uid
t.string :provider
t.references :user
end
add_index :identities, :user_id
User.where("provider is not NULL").find_each do |user|
execute "INSERT INTO identities(provider, extern_uid, user_id) VALUES('#{user.provider}', '#{user.extern_uid}', '#{user.id}')"
end
#TODO remove user's columns extern_uid and provider
end
def down
#TODO
end
end
...@@ -11,11 +11,20 @@ ...@@ -11,11 +11,20 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20141121133009) do ActiveRecord::Schema.define(version: 20141121161704) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
create_table "appearances", force: true do |t|
t.string "title"
t.text "description"
t.string "logo"
t.integer "updated_by"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "broadcast_messages", force: true do |t| create_table "broadcast_messages", force: true do |t|
t.text "message", null: false t.text "message", null: false
t.datetime "starts_at" t.datetime "starts_at"
...@@ -74,6 +83,29 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -74,6 +83,29 @@ ActiveRecord::Schema.define(version: 20141121133009) do
add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree
create_table "git_hooks", force: true do |t|
t.string "force_push_regex"
t.string "delete_branch_regex"
t.string "commit_message_regex"
t.boolean "deny_delete_tag"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "username_regex"
t.string "email_regex"
t.string "author_email_regex"
t.boolean "member_check", default: false, null: false
t.string "file_name_regex"
end
create_table "identities", force: true do |t|
t.string "extern_uid"
t.string "provider"
t.integer "user_id"
end
add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree
create_table "issues", force: true do |t| create_table "issues", force: true do |t|
t.string "title" t.string "title"
t.integer "assignee_id" t.integer "assignee_id"
...@@ -130,6 +162,15 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -130,6 +162,15 @@ ActiveRecord::Schema.define(version: 20141121133009) do
add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree
create_table "ldap_group_links", force: true do |t|
t.string "cn", null: false
t.integer "group_access", null: false
t.integer "group_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.string "provider"
end
create_table "members", force: true do |t| create_table "members", force: true do |t|
t.integer "access_level", null: false t.integer "access_level", null: false
t.integer "source_id", null: false t.integer "source_id", null: false
...@@ -209,6 +250,8 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -209,6 +250,8 @@ ActiveRecord::Schema.define(version: 20141121133009) do
t.string "type" t.string "type"
t.string "description", default: "", null: false t.string "description", default: "", null: false
t.string "avatar" t.string "avatar"
t.string "ldap_cn"
t.integer "ldap_access"
end end
add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree
...@@ -240,6 +283,14 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -240,6 +283,14 @@ ActiveRecord::Schema.define(version: 20141121133009) do
add_index "notes", ["project_id"], name: "index_notes_on_project_id", using: :btree add_index "notes", ["project_id"], name: "index_notes_on_project_id", using: :btree
add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree
create_table "project_group_links", force: true do |t|
t.integer "project_id", null: false
t.integer "group_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "group_access", default: 30, null: false
end
create_table "projects", force: true do |t| create_table "projects", force: true do |t|
t.string "name" t.string "name"
t.string "path" t.string "path"
...@@ -247,21 +298,22 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -247,21 +298,22 @@ ActiveRecord::Schema.define(version: 20141121133009) do
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.integer "creator_id" t.integer "creator_id"
t.boolean "issues_enabled", default: true, null: false t.boolean "issues_enabled", default: true, null: false
t.boolean "wall_enabled", default: true, null: false t.boolean "wall_enabled", default: true, null: false
t.boolean "merge_requests_enabled", default: true, null: false t.boolean "merge_requests_enabled", default: true, null: false
t.boolean "wiki_enabled", default: true, null: false t.boolean "wiki_enabled", default: true, null: false
t.integer "namespace_id" t.integer "namespace_id"
t.string "issues_tracker", default: "gitlab", null: false t.string "issues_tracker", default: "gitlab", null: false
t.string "issues_tracker_id" t.string "issues_tracker_id"
t.boolean "snippets_enabled", default: true, null: false t.boolean "snippets_enabled", default: true, null: false
t.datetime "last_activity_at" t.datetime "last_activity_at"
t.string "import_url" t.string "import_url"
t.integer "visibility_level", default: 0, null: false t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false t.boolean "archived", default: false, null: false
t.string "import_status" t.string "import_status"
t.float "repository_size", default: 0.0 t.float "repository_size", default: 0.0
t.integer "star_count", default: 0, null: false t.integer "star_count", default: 0, null: false
t.text "merge_requests_template"
end end
add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree
...@@ -327,12 +379,12 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -327,12 +379,12 @@ ActiveRecord::Schema.define(version: 20141121133009) do
end end
create_table "users", force: true do |t| create_table "users", force: true do |t|
t.string "email", default: "", null: false t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false t.string "encrypted_password", default: "", null: false
t.string "reset_password_token" t.string "reset_password_token"
t.datetime "reset_password_sent_at" t.datetime "reset_password_sent_at"
t.datetime "remember_created_at" t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0 t.integer "sign_in_count", default: 0
t.datetime "current_sign_in_at" t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at" t.datetime "last_sign_in_at"
t.string "current_sign_in_ip" t.string "current_sign_in_ip"
...@@ -340,24 +392,24 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -340,24 +392,24 @@ ActiveRecord::Schema.define(version: 20141121133009) do
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "name" t.string "name"
t.boolean "admin", default: false, null: false t.boolean "admin", default: false, null: false
t.integer "projects_limit", default: 10 t.integer "projects_limit", default: 10
t.string "skype", default: "", null: false t.string "skype", default: "", null: false
t.string "linkedin", default: "", null: false t.string "linkedin", default: "", null: false
t.string "twitter", default: "", null: false t.string "twitter", default: "", null: false
t.string "authentication_token" t.string "authentication_token"
t.integer "theme_id", default: 1, null: false t.integer "theme_id", default: 1, null: false
t.string "bio" t.string "bio"
t.integer "failed_attempts", default: 0 t.integer "failed_attempts", default: 0
t.datetime "locked_at" t.datetime "locked_at"
t.string "extern_uid" t.string "extern_uid"
t.string "provider" t.string "provider"
t.string "username" t.string "username"
t.boolean "can_create_group", default: true, null: false t.boolean "can_create_group", default: true, null: false
t.boolean "can_create_team", default: true, null: false t.boolean "can_create_team", default: true, null: false
t.string "state" t.string "state"
t.integer "color_scheme_id", default: 1, null: false t.integer "color_scheme_id", default: 1, null: false
t.integer "notification_level", default: 1, null: false t.integer "notification_level", default: 1, null: false
t.datetime "password_expires_at" t.datetime "password_expires_at"
t.integer "created_by_id" t.integer "created_by_id"
t.string "avatar" t.string "avatar"
...@@ -365,9 +417,10 @@ ActiveRecord::Schema.define(version: 20141121133009) do ...@@ -365,9 +417,10 @@ ActiveRecord::Schema.define(version: 20141121133009) do
t.datetime "confirmed_at" t.datetime "confirmed_at"
t.datetime "confirmation_sent_at" t.datetime "confirmation_sent_at"
t.string "unconfirmed_email" t.string "unconfirmed_email"
t.boolean "hide_no_ssh_key", default: false t.boolean "hide_no_ssh_key", default: false
t.string "website_url", default: "", null: false t.string "website_url", default: "", null: false
t.datetime "last_credential_check_at" t.datetime "last_credential_check_at"
t.datetime "admin_email_unsubscribed_at"
end end
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
......
...@@ -12,9 +12,10 @@ module Gitlab ...@@ -12,9 +12,10 @@ module Gitlab
class << self class << self
def find_by_uid_and_provider(uid, provider) def find_by_uid_and_provider(uid, provider)
# LDAP distinguished name is case-insensitive # LDAP distinguished name is case-insensitive
::User. identity = ::Identity.
where(provider: [provider, :ldap]). where(provider: [provider, :ldap]).
where('lower(extern_uid) = ?', uid.downcase).last where('lower(extern_uid) = ?', uid.downcase).last
identity && identity.user
end end
end end
...@@ -34,7 +35,7 @@ module Gitlab ...@@ -34,7 +35,7 @@ module Gitlab
end end
def find_by_email def find_by_email
model.find_by(email: auth_hash.email) User.find_by(email: auth_hash.email)
end end
def update_user_attributes def update_user_attributes
......
...@@ -27,11 +27,9 @@ module Gitlab ...@@ -27,11 +27,9 @@ module Gitlab
def save def save
unauthorized_to_create unless gl_user unauthorized_to_create unless gl_user
gl_user.save!
if needs_blocking? if needs_blocking?
gl_user.save!
gl_user.block gl_user.block
else
gl_user.save!
end end
log.info "(OAuth) saving user #{auth_hash.email} from login with extern_uid => #{auth_hash.uid}" log.info "(OAuth) saving user #{auth_hash.email} from login with extern_uid => #{auth_hash.uid}"
...@@ -70,24 +68,23 @@ module Gitlab ...@@ -70,24 +68,23 @@ module Gitlab
end end
def find_by_uid_and_provider def find_by_uid_and_provider
model.where(provider: auth_hash.provider, extern_uid: auth_hash.uid).last identity = Identity.find_by(provider: auth_hash.provider, extern_uid: auth_hash.uid)
identity && identity.user
end end
def build_new_user def build_new_user
model.new(user_attributes).tap do |user| user = User.new(user_attributes)
user.skip_confirmation! user.skip_confirmation!
end user.identities.new(extern_uid: auth_hash.uid, provider: auth_hash.provider)
end end
def user_attributes def user_attributes
{ {
extern_uid: auth_hash.uid,
provider: auth_hash.provider,
name: auth_hash.name, name: auth_hash.name,
username: auth_hash.username, username: auth_hash.username,
email: auth_hash.email, email: auth_hash.email,
password: auth_hash.password, password: auth_hash.password,
password_confirmation: auth_hash.password, password_confirmation: auth_hash.password
} }
end end
...@@ -95,10 +92,6 @@ module Gitlab ...@@ -95,10 +92,6 @@ module Gitlab
Gitlab::AppLogger Gitlab::AppLogger
end end
def model
::User
end
def raise_unauthorized_to_create def raise_unauthorized_to_create
raise StandardError.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}") raise StandardError.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}")
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment