Commit 21adddaf authored by Sebastián Arcila Valenzuela's avatar Sebastián Arcila Valenzuela Committed by Bob Van Landuyt

Link existing user accounts to new Smartcards Identities

There a two scenarios in which it is needed:

* When an existing user logins for the first time with a smartcard
* When an existing user with an smartcard gets its certificate reissue
parent 7d08cc22
...@@ -4,6 +4,10 @@ type: reference ...@@ -4,6 +4,10 @@ type: reference
# Smartcard authentication **(PREMIUM ONLY)** # Smartcard authentication **(PREMIUM ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33669) in GitLab 12.6,
if a user has a pre-existing username and password, they can still use that to log
in by default. However, this can be disabled.
GitLab supports authentication using smartcards. GitLab supports authentication using smartcards.
## Authentication methods ## Authentication methods
......
---
title: Link user accounts to new Smartcards identities on login
merge_request: 20059
author:
type: fixed
...@@ -42,12 +42,28 @@ module Gitlab ...@@ -42,12 +42,28 @@ module Gitlab
return unless valid? return unless valid?
user = find_user user = find_user
user ||= create_identity_for_existing_user
user ||= create_user if allow_signup? user ||= create_user if allow_signup?
user user
end end
private private
def find_user
raise NotImplementedError,
"#{self.class.name} does not implement #{__method__}"
end
def create_identity_for_existing_user
raise NotImplementedError,
"#{self.class.name} does not implement #{__method__}"
end
def create_user
raise NotImplementedError,
"#{self.class.name} does not implement #{__method__}"
end
def valid? def valid?
self.class.store.verify(@certificate) if @certificate self.class.store.verify(@certificate) if @certificate
end end
......
...@@ -16,13 +16,13 @@ module Gitlab ...@@ -16,13 +16,13 @@ module Gitlab
User.find_by_smartcard_identity(subject, issuer) User.find_by_smartcard_identity(subject, issuer)
end end
def create_user def create_identity_for_existing_user
user = User.find_by_email(email) User.find_by_email(email).tap do |user|
if user create_smartcard_identity_for(user) if user
create_smartcard_identity_for(user)
return user
end end
end
def create_user
user_params = { user_params = {
name: common_name, name: common_name,
username: username, username: username,
......
...@@ -21,6 +21,10 @@ module Gitlab ...@@ -21,6 +21,10 @@ module Gitlab
identity&.user identity&.user
end end
def create_identity_for_existing_user
# TODO: create new identity for existing users as part of https://gitlab.com/gitlab-org/gitlab/issues/36808
end
def create_user def create_user
user_params = { user_params = {
name: ldap_user.name, name: ldap_user.name,
......
...@@ -18,11 +18,10 @@ describe Gitlab::Auth::Smartcard::Certificate do ...@@ -18,11 +18,10 @@ describe Gitlab::Auth::Smartcard::Certificate do
shared_examples 'a new smartcard identity' do shared_examples 'a new smartcard identity' do
it 'creates smartcard identity' do it 'creates smartcard identity' do
expect { subject }.to change { SmartcardIdentity.count }.from(0).to(1) expect { subject }.to change { SmartcardIdentity.count }.by(1)
identity = SmartcardIdentity.first identity = SmartcardIdentity.find_by(subject: subject_dn, issuer: issuer_dn)
expect(identity.subject).to eql(subject_dn) expect(identity).not_to be_nil
expect(identity.issuer).to eql(issuer_dn)
end end
end end
...@@ -63,6 +62,28 @@ describe Gitlab::Auth::Smartcard::Certificate do ...@@ -63,6 +62,28 @@ describe Gitlab::Auth::Smartcard::Certificate do
end end
end end
context 'user exists but it is using a new smartcard' do
let_it_be(:user) { create(:user, email: 'gitlab-user@random-corp.org') }
let_it_be(:old_identity) do
create(:smartcard_identity,
subject: 'old_subject',
issuer: 'old_issuer_dn',
user: user)
end
it_behaves_like 'an existing user'
it_behaves_like 'a new smartcard identity'
it 'keeps both identities for the user' do
subject
new_identity = SmartcardIdentity.find_by(subject: subject_dn, issuer: issuer_dn)
expect(user.smartcard_identities).to contain_exactly(new_identity, old_identity)
end
end
context 'user and smartcard identity do not exist' do context 'user and smartcard identity do not exist' do
let(:user) { create(:user) } let(:user) { create(:user) }
......
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