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:
Joseph Schorr 2016-09-08 18:43:50 -04:00
parent 840ea4e768
commit 1e3b354201
18 changed files with 388 additions and 24 deletions

View file

@ -66,7 +66,7 @@ def handle_invite_code(invite_code, user):
return True
def user_view(user):
def user_view(user, previous_username=None):
def org_view(o, user_admin=True):
admin_org = AdministerOrganizationPermission(o.username)
org_response = {
@ -105,7 +105,7 @@ def user_view(user):
'avatar': avatar.get_data_for_user(user),
}
user_admin = UserAdminPermission(user.username)
user_admin = UserAdminPermission(previous_username if previous_username else user.username)
if user_admin.can():
user_response.update({
'can_create_repo': True,
@ -117,6 +117,7 @@ def user_view(user):
'invoice_email_address': user.invoice_email_address,
'preferred_namespace': not (user.stripe_id is None),
'tag_expiration': user.removed_tag_expiration_s,
'prompts': model.user.get_user_prompts(user),
})
analytics_metadata = user_analytics.get_user_analytics_metadata(user)
@ -217,7 +218,7 @@ class User(ApiResource):
'UserView': {
'type': 'object',
'description': 'Describes a user',
'required': ['verified', 'anonymous', 'avatar'],
'required': ['anonymous', 'avatar'],
'properties': {
'verified': {
'type': 'boolean',
@ -283,6 +284,7 @@ class User(ApiResource):
""" Update a users details such as password or email. """
user = get_authenticated_user()
user_data = request.get_json()
previous_username = None
try:
if 'password' in user_data:
@ -324,19 +326,29 @@ class User(ApiResource):
else:
model.user.update_email(user, new_email, auto_verify=not features.MAILING)
if ('username' in user_data and user_data['username'] != user.username and
features.USER_RENAME):
new_username = user_data['username']
if model.user.get_user_or_org(new_username) is not None:
# Username already used
raise request_error(message='Username is already in use')
# Check for username rename. A username can be renamed if the feature is enabled OR the user
# currently has a confirm_username prompt.
if 'username' in user_data:
confirm_username = model.user.has_user_prompt(user, 'confirm_username')
new_username = user_data.get('username')
previous_username = user.username
model.user.change_username(user.id, new_username)
rename_allowed = features.USER_RENAME or confirm_username
username_changing = new_username and new_username != previous_username
if rename_allowed and username_changing:
if model.user.get_user_or_org(new_username) is not None:
# Username already used.
raise request_error(message='Username is already in use')
user = model.user.change_username(user.id, new_username)
elif confirm_username:
model.user.remove_user_prompt(user, 'confirm_username')
except model.user.InvalidPasswordException, ex:
raise request_error(exception=ex)
return user_view(user)
return user_view(user, previous_username=previous_username)
@show_if(features.USER_CREATION)
@show_if(features.DIRECT_LOGIN)