Add support for temp usernames and an interstitial to confirm username
When a user now logs in for the first time for any external auth (LDAP, JWT, Keystone, Github, Google, Dex), they will be presented with a confirmation screen that affords them the opportunity to change their Quay-assigned username. Addresses most of the user issues around #74
This commit is contained in:
parent
840ea4e768
commit
1e3b354201
18 changed files with 388 additions and 24 deletions
|
@ -11,7 +11,8 @@ from data.database import (User, LoginService, FederatedLogin, RepositoryPermiss
|
|||
Team, Repository, TupleSelector, TeamRole, Namespace, Visibility,
|
||||
EmailConfirmation, Role, db_for_update, random_string_generator,
|
||||
UserRegion, ImageStorageLocation, QueueItem, TeamMemberInvite,
|
||||
ServiceKeyApproval, OAuthApplication, RepositoryBuildTrigger)
|
||||
ServiceKeyApproval, OAuthApplication, RepositoryBuildTrigger,
|
||||
UserPromptKind, UserPrompt)
|
||||
from data.model import (DataModelException, InvalidPasswordException, InvalidRobotException,
|
||||
InvalidUsernameException, InvalidEmailAddressException,
|
||||
TooManyLoginAttemptsException, db_transaction,
|
||||
|
@ -102,6 +103,38 @@ def change_password(user, new_password):
|
|||
notification.delete_notifications_by_kind(user, 'password_required')
|
||||
|
||||
|
||||
def has_user_prompts(user):
|
||||
try:
|
||||
UserPrompt.select().where(UserPrompt.user == user).get()
|
||||
return True
|
||||
except UserPrompt.DoesNotExist:
|
||||
return False
|
||||
|
||||
def has_user_prompt(user, prompt_name):
|
||||
prompt_kind = UserPromptKind.get(name=prompt_name)
|
||||
|
||||
try:
|
||||
UserPrompt.get(user=user, kind=prompt_kind)
|
||||
return True
|
||||
except UserPrompt.DoesNotExist:
|
||||
return False
|
||||
|
||||
|
||||
def create_user_prompt(user, prompt_name):
|
||||
prompt_kind = UserPromptKind.get(name=prompt_name)
|
||||
return UserPrompt.create(user=user, kind=prompt_kind)
|
||||
|
||||
|
||||
def remove_user_prompt(user, prompt_name):
|
||||
prompt_kind = UserPromptKind.get(name=prompt_name)
|
||||
UserPrompt.delete().where(UserPrompt.user == user, UserPrompt.kind == prompt_kind).execute()
|
||||
|
||||
|
||||
def get_user_prompts(user):
|
||||
query = UserPrompt.select().where(UserPrompt.user == user).join(UserPromptKind)
|
||||
return [prompt.kind.name for prompt in query]
|
||||
|
||||
|
||||
def change_username(user_id, new_username):
|
||||
(username_valid, username_issue) = validate_username(new_username)
|
||||
if not username_valid:
|
||||
|
@ -121,6 +154,10 @@ def change_username(user_id, new_username):
|
|||
# Rename the user
|
||||
user.username = new_username
|
||||
user.save()
|
||||
|
||||
# Remove any prompts for username.
|
||||
remove_user_prompt(user, 'confirm_username')
|
||||
|
||||
return user
|
||||
|
||||
|
||||
|
@ -305,11 +342,15 @@ def list_entity_robot_permission_teams(entity_name, include_permissions=False):
|
|||
|
||||
|
||||
def create_federated_user(username, email, service_name, service_ident,
|
||||
set_password_notification, metadata={}, email_required=True):
|
||||
set_password_notification, metadata={},
|
||||
email_required=True, confirm_username=False):
|
||||
new_user = create_user_noverify(username, email, email_required=email_required)
|
||||
new_user.verified = True
|
||||
new_user.save()
|
||||
|
||||
if confirm_username:
|
||||
create_user_prompt(new_user, 'confirm_username')
|
||||
|
||||
service = LoginService.get(LoginService.name == service_name)
|
||||
FederatedLogin.create(user=new_user, service=service,
|
||||
service_ident=service_ident,
|
||||
|
|
Reference in a new issue