Make V2 login errors more descriptive

If login fails, we now call validate again to get the reason for the failure, and then surface it to the user of the CLI. This allows for more actionable responses, such as:

$ docker login 10.0.2.2:5000
Username (devtable): devtable
Password:

Error response from daemon: Get http://10.0.2.2:5000/v2/: unauthorized: Client login with unencrypted passwords is disabled. Please generate an encrypted password in the user admin panel for use here.
This commit is contained in:
Joseph Schorr 2017-03-16 17:06:05 -04:00
parent 651666b60b
commit 95e1cf6673
2 changed files with 17 additions and 8 deletions

View file

@ -146,3 +146,12 @@ class Unsupported(V2RegistryException):
'The operation is unsupported.',
detail,
405)
class InvalidLogin(V2RegistryException):
def __init__(self, message=None):
super(InvalidLogin, self).__init__('UNAUTHORIZED',
message or 'Specified credentials are invalid',
{},
401)

View file

@ -6,12 +6,12 @@ from flask import request, jsonify, abort
from app import app, userevents, instance_keys
from auth.auth_context import get_authenticated_user, get_validated_token, get_validated_oauth_token
from auth.decorators import process_auth
from auth.decorators import process_basic_auth
from auth.permissions import (ModifyRepositoryPermission, ReadRepositoryPermission,
CreateRepositoryPermission, AdministerRepositoryPermission)
from auth.process import process_auth
from endpoints.v2 import v2_bp
from endpoints.decorators import anon_protect
from endpoints.v2 import v2_bp
from endpoints.v2.errors import InvalidLogin
from data.interfaces.v2 import pre_oci_model as model
from util.cache import no_cache
from util.names import parse_namespace_repository, REPOSITORY_NAME_REGEX
@ -34,10 +34,10 @@ def get_scope_regex():
@v2_bp.route('/auth')
@process_auth
@process_basic_auth
@no_cache
@anon_protect
def generate_registry_jwt():
def generate_registry_jwt(auth_result):
"""
This endpoint will generate a JWT conforming to the Docker Registry v2 Auth Spec:
https://docs.docker.com/registry/spec/auth/token/
@ -57,11 +57,11 @@ def generate_registry_jwt():
oauthtoken = get_validated_oauth_token()
logger.debug('Authenticated OAuth token: %s', oauthtoken)
auth_credentials_sent = bool(request.headers.get('authorization', ''))
auth_header = request.headers.get('authorization', '')
auth_credentials_sent = bool(auth_header)
if auth_credentials_sent and not user and not token:
# The auth credentials sent for the user are invalid.
logger.debug('Invalid auth credentials')
abort(401)
raise InvalidLogin(auth_result.error_message)
access = []
user_event_data = {