Beispiel #1
0
        def wrapper(namespace_name, repo_name, *args, **kwargs):
            response = f(namespace_name, repo_name, *args, **kwargs)

            # Setting session namespace and repository
            session["namespace"] = namespace_name
            session["repository"] = repo_name

            # We run our index and registry on the same hosts for now
            registry_server = urlparse.urlparse(request.url).netloc
            response.headers["X-Docker-Endpoints"] = registry_server

            has_token_request = request.headers.get("X-Docker-Token", "")
            force_grant = add_grant_for_status == response.status_code

            if has_token_request or force_grant:
                grants = []

                if scope == GrantType.READ_REPOSITORY:
                    if force_grant or ReadRepositoryPermission(namespace_name, repo_name).can():
                        grants.append(repository_read_grant(namespace_name, repo_name))
                elif scope == GrantType.WRITE_REPOSITORY:
                    if force_grant or ModifyRepositoryPermission(namespace_name, repo_name).can():
                        grants.append(repository_write_grant(namespace_name, repo_name))

                # Generate a signed token for the user (if any) and the grants (if any)
                if grants or get_authenticated_user():
                    user_context = get_authenticated_user() and get_authenticated_user().username
                    signature = generate_signed_token(grants, user_context)
                    response.headers["WWW-Authenticate"] = signature
                    response.headers["X-Docker-Token"] = signature

            return response
Beispiel #2
0
def identity_from_bearer_token(bearer_header):
    """
    Process a bearer header and return the loaded identity, or raise InvalidJWTException if an
    identity could not be loaded.

    Expects tokens and grants in the format of the Docker registry v2 auth spec:
    https://docs.docker.com/registry/spec/auth/token/
    """
    logger.debug("Validating auth header: %s", bearer_header)

    try:
        payload = decode_bearer_header(bearer_header, instance_keys,
                                       app.config)
    except InvalidBearerTokenException as bte:
        logger.exception("Invalid bearer token: %s", bte)
        raise InvalidJWTException(bte)

    loaded_identity = Identity(payload["sub"], "signed_jwt")

    # Process the grants from the payload
    if "access" in payload:
        try:
            validate(payload["access"], ACCESS_SCHEMA)
        except ValidationError:
            logger.exception("We should not be minting invalid credentials")
            raise InvalidJWTException(
                "Token contained invalid or malformed access grants")

        lib_namespace = app.config["LIBRARY_NAMESPACE"]
        for grant in payload["access"]:
            namespace, repo_name = parse_namespace_repository(
                grant["name"], lib_namespace)

            if "*" in grant["actions"]:
                loaded_identity.provides.add(
                    repository_admin_grant(namespace, repo_name))
            elif "push" in grant["actions"]:
                loaded_identity.provides.add(
                    repository_write_grant(namespace, repo_name))
            elif "pull" in grant["actions"]:
                loaded_identity.provides.add(
                    repository_read_grant(namespace, repo_name))

    default_context = {"kind": "anonymous"}

    if payload["sub"] != ANONYMOUS_SUB:
        default_context = {
            "kind": "user",
            "user": payload["sub"],
        }

    return loaded_identity, payload.get("context", default_context)
Beispiel #3
0
def identity_from_bearer_token(bearer_header):
    """ Process a bearer header and return the loaded identity, or raise InvalidJWTException if an
      identity could not be loaded. Expects tokens and grants in the format of the Docker registry
      v2 auth spec: https://docs.docker.com/registry/spec/auth/token/
  """
    logger.debug('Validating auth header: %s', bearer_header)

    try:
        payload = decode_bearer_header(bearer_header,
                                       instance_keys,
                                       app.config,
                                       metric_queue=metric_queue)
    except InvalidBearerTokenException as bte:
        logger.exception('Invalid bearer token: %s', bte)
        raise InvalidJWTException(bte)

    loaded_identity = Identity(payload['sub'], 'signed_jwt')

    # Process the grants from the payload
    if 'access' in payload:
        try:
            validate(payload['access'], ACCESS_SCHEMA)
        except ValidationError:
            logger.exception('We should not be minting invalid credentials')
            raise InvalidJWTException(
                'Token contained invalid or malformed access grants')

        lib_namespace = app.config['LIBRARY_NAMESPACE']
        for grant in payload['access']:
            namespace, repo_name = parse_namespace_repository(
                grant['name'], lib_namespace)

            if '*' in grant['actions']:
                loaded_identity.provides.add(
                    repository_admin_grant(namespace, repo_name))
            elif 'push' in grant['actions']:
                loaded_identity.provides.add(
                    repository_write_grant(namespace, repo_name))
            elif 'pull' in grant['actions']:
                loaded_identity.provides.add(
                    repository_read_grant(namespace, repo_name))

    default_context = {'kind': 'anonymous'}

    if payload['sub'] != ANONYMOUS_SUB:
        default_context = {
            'kind': 'user',
            'user': payload['sub'],
        }

    return loaded_identity, payload.get('context', default_context)