Пример #1
0
def validate_signed_grant(auth_header):
    """
    Validates a signed grant as found inside an auth header and returns whether it points to a valid
    grant.
    """
    if not auth_header:
        return ValidateResult(AuthKind.signed_grant, missing=True)

    # Try to parse the token from the header.
    normalized = [part.strip() for part in auth_header.split(" ") if part]
    if normalized[0].lower() != "token" or len(normalized) != 2:
        logger.debug("Not a token: %s", auth_header)
        return ValidateResult(AuthKind.signed_grant, missing=True)

    # Check that it starts with the expected prefix.
    if not normalized[1].startswith(SIGNATURE_PREFIX):
        logger.debug("Not a signed grant token: %s", auth_header)
        return ValidateResult(AuthKind.signed_grant, missing=True)

    # Decrypt the grant.
    encrypted = normalized[1][len(SIGNATURE_PREFIX) :]
    ser = SecureCookieSessionInterface().get_signing_serializer(app)

    try:
        token_data = ser.loads(encrypted, max_age=app.config["SIGNED_GRANT_EXPIRATION_SEC"])
    except BadSignature:
        logger.warning("Signed grant could not be validated: %s", encrypted)
        return ValidateResult(
            AuthKind.signed_grant, error_message="Signed grant could not be validated"
        )

    logger.debug("Successfully validated signed grant with data: %s", token_data)
    return ValidateResult(AuthKind.signed_grant, signed_data=token_data)
Пример #2
0
def validate_oauth_token(token):
    """
    Validates the specified OAuth token, returning whether it points to a valid OAuth token.
    """
    validated = model.oauth.validate_access_token(token)
    if not validated:
        logger.warning("OAuth access token could not be validated: %s", token)
        return ValidateResult(
            AuthKind.oauth,
            error_message="OAuth access token could not be validated")

    if validated.expires_at <= datetime.utcnow():
        logger.warning("OAuth access with an expired token: %s", token)
        return ValidateResult(AuthKind.oauth,
                              error_message="OAuth access token has expired")

    # Don't allow disabled users to login.
    if not validated.authorized_user.enabled:
        return ValidateResult(
            AuthKind.oauth,
            error_message="Granter of the oauth access token is disabled")

    # We have a valid token
    scope_set = scopes_from_scope_string(validated.scope)
    logger.debug("Successfully validated oauth access token with scope: %s",
                 scope_set)
    return ValidateResult(AuthKind.oauth, oauthtoken=validated)
Пример #3
0
def test_apply_context(get_entity, entity_kind, app):
    assert get_authenticated_context() is None

    entity = get_entity()
    args = {}
    args[entity_kind] = entity

    result = ValidateResult(AuthKind.basic, **args)
    result.apply_to_context()

    expected_user = entity if entity_kind == 'user' or entity_kind == 'robot' else None
    if entity_kind == 'oauthtoken':
        expected_user = entity.authorized_user

    if entity_kind == 'appspecifictoken':
        expected_user = entity.user

    expected_token = entity if entity_kind == 'token' else None
    expected_oauth = entity if entity_kind == 'oauthtoken' else None
    expected_appspecifictoken = entity if entity_kind == 'appspecifictoken' else None
    expected_grant = entity if entity_kind == 'signed_data' else None

    assert get_authenticated_context().authed_user == expected_user
    assert get_authenticated_context().token == expected_token
    assert get_authenticated_context().oauthtoken == expected_oauth
    assert get_authenticated_context(
    ).appspecifictoken == expected_appspecifictoken
    assert get_authenticated_context().signed_data == expected_grant
Пример #4
0
def validate_bearer_auth(auth_header):
    """ Validates an OAuth token found inside a basic auth `Bearer` token, returning whether it
      points to a valid OAuth token.
  """
    if not auth_header:
        return ValidateResult(AuthKind.oauth, missing=True)

    normalized = [part.strip() for part in auth_header.split(' ') if part]
    if normalized[0].lower() != 'bearer' or len(normalized) != 2:
        logger.debug('Got invalid bearer token format: %s', auth_header)
        return ValidateResult(AuthKind.oauth, missing=True)

    (_, oauth_token) = normalized
    return validate_oauth_token(oauth_token)
Пример #5
0
def test_valid_app_specific_token(app):
    user = model.user.get_user("devtable")
    app_specific_token = model.appspecifictoken.create_token(user, "some token")
    full_token = model.appspecifictoken.get_full_token_string(app_specific_token)
    token = _token(APP_SPECIFIC_TOKEN_USERNAME, full_token)
    result = validate_basic_auth(token)
    assert result == ValidateResult(AuthKind.basic, appspecifictoken=app_specific_token)
Пример #6
0
def test_unicode(app):
    result, kind = validate_credentials("someusername", "some₪code")
    assert kind == CredentialKind.user
    assert not result.auth_valid
    assert result == ValidateResult(
        AuthKind.credentials, error_message="Invalid Username or Password"
    )
Пример #7
0
def test_valid_oauth(app):
    user = model.user.get_user("devtable")
    app = model.oauth.list_applications_for_org(model.user.get_user_or_org("buynlarge"))[0]
    oauth_token, code = model.oauth.create_user_access_token(user, app.client_id, "repo:read")
    token = _token(OAUTH_TOKEN_USERNAME, code)
    result = validate_basic_auth(token)
    assert result == ValidateResult(AuthKind.basic, oauthtoken=oauth_token)
Пример #8
0
def test_invalid_app_specific_token_code(app):
    user = model.user.get_user("devtable")
    app_specific_token = model.appspecifictoken.create_token(user, "some token")
    full_token = app_specific_token.token_name + "something"
    result, kind = validate_credentials(APP_SPECIFIC_TOKEN_USERNAME, full_token)
    assert kind == CredentialKind.app_specific_token
    assert result == ValidateResult(AuthKind.credentials, error_message="Invalid token")
Пример #9
0
def test_invalid_unicode_robot(app):
    token = "“4JPCOLIVMAY32Q3XGVPHC4CBF8SKII5FWNYMASOFDIVSXTC5I5NBU”"
    result, kind = validate_credentials("devtable+somerobot", token)
    assert kind == CredentialKind.robot
    assert not result.auth_valid
    msg = "Could not find robot with specified username"
    assert result == ValidateResult(AuthKind.credentials, error_message=msg)
Пример #10
0
def test_valid_app_specific_token(app):
    user = model.user.get_user("devtable")
    app_specific_token = model.appspecifictoken.create_token(user, "some token")
    full_token = model.appspecifictoken.get_full_token_string(app_specific_token)
    result, kind = validate_credentials(APP_SPECIFIC_TOKEN_USERNAME, full_token)
    assert kind == CredentialKind.app_specific_token
    assert result == ValidateResult(AuthKind.credentials, appspecifictoken=app_specific_token)
Пример #11
0
def test_valid_token(app):
    access_token = model.token.create_delegate_token("devtable", "simple",
                                                     "sometoken")
    result, kind = validate_credentials(ACCESS_TOKEN_USERNAME,
                                        access_token.get_code())
    assert kind == CredentialKind.token
    assert result == ValidateResult(AuthKind.credentials, token=access_token)
Пример #12
0
def test_invalid_unicode_2(app):
    token = "“4JPCOLIVMAY32Q3XGVPHC4CBF8SKII5FWNYMASOFDIVSXTC5I5NBU”".encode("utf-8")
    header = "basic " + b64encode(b"devtable+somerobot:%s" % token).decode("ascii")
    result = validate_basic_auth(header)
    assert result == ValidateResult(
        AuthKind.basic,
        error_message="Could not find robot with username: devtable+somerobot and supplied password.",
    )
Пример #13
0
def test_invalid_unicode_3(app):
    token = "sometoken"
    header = "basic " + b64encode("“devtable+somerobot”:%s" % token)
    result = validate_basic_auth(header)
    assert result == ValidateResult(
        AuthKind.basic,
        error_message="Could not find robot with specified username",
    )
Пример #14
0
def test_invalid_unicode_3(app):
    token = "sometoken"
    auth = "“devtable+somerobot”:" + token
    auth = auth.encode("utf-8")
    header = "basic " + b64encode(auth).decode("ascii")
    result = validate_basic_auth(header)
    assert result == ValidateResult(
        AuthKind.basic, error_message="Could not find robot with specified username",
    )
Пример #15
0
def test_unicode_robot(app):
    robot, _ = model.user.create_robot("somerobot", model.user.get_user("devtable"))
    result, kind = validate_credentials(robot.username, "some₪code")

    assert kind == CredentialKind.robot
    assert not result.auth_valid

    msg = "Could not find robot with username: devtable+somerobot and supplied password."
    assert result == ValidateResult(AuthKind.credentials, error_message=msg)
Пример #16
0
def test_invalid_unicode_2(app):
    token = '“4JPCOLIVMAY32Q3XGVPHC4CBF8SKII5FWNYMASOFDIVSXTC5I5NBU”'
    header = 'basic ' + b64encode('devtable+somerobot:%s' % token)
    result = validate_basic_auth(header)
    assert result == ValidateResult(
        AuthKind.basic,
        error_message=
        'Could not find robot with username: devtable+somerobot and supplied password.'
    )
Пример #17
0
def test_valid_oauth(app):
    user = model.user.get_user("devtable")
    app = model.oauth.list_applications_for_org(
        model.user.get_user_or_org("buynlarge"))[0]
    oauth_token, code = model.oauth.create_access_token_for_testing(
        user, app.client_id, "repo:read")
    result, kind = validate_credentials(OAUTH_TOKEN_USERNAME, code)
    assert kind == CredentialKind.oauth_token
    assert result == ValidateResult(AuthKind.oauth, oauthtoken=oauth_token)
Пример #18
0
def test_invalid_unicode_robot_2(app):
    user = model.user.get_user("devtable")
    robot, password = model.user.create_robot("somerobot", user)

    token = "“4JPCOLIVMAY32Q3XGVPHC4CBF8SKII5FWNYMASOFDIVSXTC5I5NBU”"
    result, kind = validate_credentials("devtable+somerobot", token)
    assert kind == CredentialKind.robot
    assert not result.auth_valid
    msg = "Could not find robot with username: devtable+somerobot and supplied password."
    assert result == ValidateResult(AuthKind.credentials, error_message=msg)
Пример #19
0
def validate_basic_auth(auth_header):
    """ Validates the specified basic auth header, returning whether its credentials point
      to a valid user or token.
  """
    if not auth_header:
        return ValidateResult(AuthKind.basic, missing=True)

    logger.debug("Attempt to process basic auth header")

    # Parse the basic auth header.
    assert isinstance(auth_header, basestring)
    credentials, err = _parse_basic_auth_header(auth_header)
    if err is not None:
        logger.debug("Got invalid basic auth header: %s", auth_header)
        return ValidateResult(AuthKind.basic, missing=True)

    auth_username, auth_password_or_token = credentials
    result, _ = validate_credentials(auth_username, auth_password_or_token)
    return result.with_kind(AuthKind.basic)
Пример #20
0
def test_valid_robot_for_disabled_user(app):
    user = model.user.get_user("devtable")
    user.enabled = False
    user.save()

    robot, password = model.user.create_robot("somerobot", user)
    result, kind = validate_credentials(robot.username, password)
    assert kind == CredentialKind.robot

    err = "This user has been disabled. Please contact your administrator."
    assert result == ValidateResult(AuthKind.credentials, error_message=err)
Пример #21
0
def test_valid_grant():
    header = 'token ' + generate_signed_token({'a': 'b'}, {'c': 'd'})
    expected = ValidateResult(AuthKind.signed_grant,
                              signed_data={
                                  'grants': {
                                      'a': 'b',
                                  },
                                  'user_context': {
                                      'c': 'd'
                                  },
                              })
    assert validate_signed_grant(header) == expected
Пример #22
0
def test_valid_app_specific_token_for_disabled_user(app):
    user = model.user.get_user("devtable")
    user.enabled = False
    user.save()

    app_specific_token = model.appspecifictoken.create_token(user, "some token")
    full_token = model.appspecifictoken.get_full_token_string(app_specific_token)
    result, kind = validate_credentials(APP_SPECIFIC_TOKEN_USERNAME, full_token)
    assert kind == CredentialKind.app_specific_token

    err = "This user has been disabled. Please contact your administrator."
    assert result == ValidateResult(AuthKind.credentials, error_message=err)
Пример #23
0
def test_valid_grant():
    header = "token " + generate_signed_token({"a": "b"}, {"c": "d"})
    expected = ValidateResult(
        AuthKind.signed_grant,
        signed_data={
            "grants": {
                "a": "b",
            },
            "user_context": {"c": "d"},
        },
    )
    assert validate_signed_grant(header) == expected
Пример #24
0
def validate_session_cookie(auth_header_unusued=None):
    """ Attempts to load a user from a session cookie. """
    if current_user.is_anonymous:
        return ValidateResult(AuthKind.cookie, missing=True)

    try:
        # Attempt to parse the user uuid to make sure the cookie has the right value type
        UUID(current_user.get_id())
    except ValueError:
        logger.debug('Got non-UUID for session cookie user: %s',
                     current_user.get_id())
        return ValidateResult(AuthKind.cookie,
                              error_message='Invalid session cookie format')

    logger.debug('Loading user from cookie: %s', current_user.get_id())
    db_user = current_user.db_user()
    if db_user is None:
        return ValidateResult(AuthKind.cookie,
                              error_message='Could not find matching user')

    # Don't allow disabled users to login.
    if not db_user.enabled:
        logger.debug('User %s in session cookie is disabled', db_user.username)
        return ValidateResult(AuthKind.cookie,
                              error_message='User account is disabled')

    # Don't allow organizations to "login".
    if db_user.organization:
        logger.debug('User %s in session cookie is in-fact organization',
                     db_user.username)
        return ValidateResult(AuthKind.cookie,
                              error_message='Cannot login to organization')

    return ValidateResult(AuthKind.cookie, user=db_user)
Пример #25
0
def test_valid_token(app):
    access_token = model.token.create_delegate_token("devtable", "simple",
                                                     "sometoken")
    token = _token(ACCESS_TOKEN_USERNAME, access_token.get_code())
    result = validate_basic_auth(token)
    assert result == ValidateResult(AuthKind.basic, token=access_token)
Пример #26
0
def test_valid_robot(app):
    robot, password = model.user.create_robot("somerobot",
                                              model.user.get_user("devtable"))
    token = _token(robot.username, password)
    result = validate_basic_auth(token)
    assert result == ValidateResult(AuthKind.basic, robot=robot)
Пример #27
0
def test_valid_user(app):
    token = _token("devtable", "password")
    result = validate_basic_auth(token)
    assert result == ValidateResult(AuthKind.basic,
                                    user=model.user.get_user("devtable"))
Пример #28
0
from auth.credentials import (ACCESS_TOKEN_USERNAME, OAUTH_TOKEN_USERNAME,
                              APP_SPECIFIC_TOKEN_USERNAME)
from auth.validateresult import AuthKind, ValidateResult
from data import model

from test.fixtures import *


def _token(username, password):
    assert isinstance(username, basestring)
    assert isinstance(password, basestring)
    return 'basic ' + b64encode('%s:%s' % (username, password))


@pytest.mark.parametrize('token, expected_result', [
    ('', ValidateResult(AuthKind.basic, missing=True)),
    ('someinvalidtoken', ValidateResult(AuthKind.basic, missing=True)),
    ('somefoobartoken', ValidateResult(AuthKind.basic, missing=True)),
    ('basic ', ValidateResult(AuthKind.basic, missing=True)),
    ('basic some token', ValidateResult(AuthKind.basic, missing=True)),
    ('basic sometoken', ValidateResult(AuthKind.basic, missing=True)),
    (_token(APP_SPECIFIC_TOKEN_USERNAME, 'invalid'),
     ValidateResult(AuthKind.basic, error_message='Invalid token')),
    (_token(ACCESS_TOKEN_USERNAME, 'invalid'),
     ValidateResult(AuthKind.basic, error_message='Invalid access token')),
    (_token(OAUTH_TOKEN_USERNAME, 'invalid'),
     ValidateResult(
         AuthKind.basic,
         error_message='OAuth access token could not be validated')),
    (_token('devtable', 'invalid'),
     ValidateResult(AuthKind.basic,
Пример #29
0
def test_invalid_unicode(app):
    token = "\xebOH"
    header = "basic " + b64encode(token)
    result = validate_basic_auth(header)
    assert result == ValidateResult(AuthKind.basic, missing=True)
Пример #30
0
from auth.validateresult import AuthKind, ValidateResult
from data import model

from test.fixtures import *


def _token(username, password):
    assert isinstance(username, basestring)
    assert isinstance(password, basestring)
    return "basic " + b64encode("%s:%s" % (username, password))


@pytest.mark.parametrize(
    "token, expected_result",
    [
        ("", ValidateResult(AuthKind.basic, missing=True)),
        ("someinvalidtoken", ValidateResult(AuthKind.basic, missing=True)),
        ("somefoobartoken", ValidateResult(AuthKind.basic, missing=True)),
        ("basic ", ValidateResult(AuthKind.basic, missing=True)),
        ("basic some token", ValidateResult(AuthKind.basic, missing=True)),
        ("basic sometoken", ValidateResult(AuthKind.basic, missing=True)),
        (
            _token(APP_SPECIFIC_TOKEN_USERNAME, "invalid"),
            ValidateResult(AuthKind.basic, error_message="Invalid token"),
        ),
        (
            _token(ACCESS_TOKEN_USERNAME, "invalid"),
            ValidateResult(AuthKind.basic,
                           error_message="Invalid access token"),
        ),
        (