Beispiel #1
0
def verify_core_token(group_name=None):
    id_token = get_bearer_token(request)
    if not id_token:
        raise OAuthProblem('Missing id token')

    # check if its the rokwire core issuer
    unverified_header, unverified_payload = get_unverified_header_payload(
        id_token)
    ROKWIRE_AUTH_HOST = os.getenv('ROKWIRE_AUTH_HOST', '')
    ROKWIRE_AUTH_KEY_PATH = os.getenv('ROKWIRE_AUTH_KEY_PATH', '')
    issuer = unverified_payload.get('iss')
    kid = unverified_header.get('kid')
    if not kid:
        logger.warning("kid not found. Aborting.")
        raise OAuthProblem('Invalid token')

    if issuer == ROKWIRE_AUTH_HOST:
        keyset = get_keyset(ROKWIRE_AUTH_HOST + ROKWIRE_AUTH_KEY_PATH)
        target_client_ids = re.split(',', (os.getenv('ROKWIRE_AUTH_AUD',
                                                     '')).replace(" ", ""))
        id_info = decode_id_token(id_token, keyset, target_client_ids, kid)
        g.user_token_data = id_info
        g.user_token = id_token
        return {'id_token_valid': True}
    else:
        raise OAuthProblem('invalid core token')
Beispiel #2
0
def validate_claim(
    token_info: Claim,
    dataset_id: DatasetId,
    permissions: List[DatasetPermission],
    organization_id: Optional[OrganizationId] = None,
) -> AuthContext:

    # API v1 does not specify an organization. Additionally, for v1 API
    # compatability, we assume the organization of context is the head
    # organization in the given JWT claim:
    if organization_id is None:
        if token_info.head_organization_node_id is None:
            raise OAuthProblem("Missing organization node id")
        organization_int_id: OrganizationId = OrganizationId(
            token_info.head_organization_id.id
        )
    else:
        organization_int_id = OrganizationId(organization_id)

    dataset_int_id = dataset_id

    if token_info.is_user_claim:
        if token_info.content.node_id is None:
            raise OAuthProblem("Missing user node ID")
        user_node_id = UserNodeId(token_info.content.node_id)
    else:
        user_node_id = SERVICE_USER_NODE_ID

    auth_organization_id = RoleOrganizationId(organization_int_id)
    auth_dataset_id = RoleDatasetId(dataset_int_id)

    if not token_info.has_organization_access(auth_organization_id):
        raise Forbidden

    for permission in permissions:
        if not token_info.has_dataset_access(auth_dataset_id, permission):
            raise Forbidden

    # (invariant):
    # These roles should never be None and are assumed to be valid given the
    # checks above.
    organization_role = token_info.get_role(auth_organization_id)
    dataset_role = token_info.get_role(auth_dataset_id)

    def get_locked():
        for role in token_info.content.roles:
            # we do not pass through the locked field for a wildcard role,
            # since by definition the wildcard means we don't know individual datasets are locked or not
            if role.id == auth_dataset_id and isinstance(role, DatasetRole):
                return role.locked
        return None

    return AuthContext(
        organization_id=organization_int_id,
        dataset_id=dataset_id,
        user_node_id=user_node_id,
        organization_node_id=organization_role.node_id,
        dataset_node_id=dataset_role.node_id,
        locked=get_locked(),
    )
Beispiel #3
0
def auth_token(token, required_scopes):
    db_token = db.session.query(Token) \
        .filter(Token.uuid == token).first()
    if not db_token:
        raise OAuthProblem(TOKEN_NOT_FOUND_MSG)

    if not db_token.is_open:
        raise OAuthProblem(TOKEN_CLOSED_MSG)

    return {'sub': db_token.uuid}
Beispiel #4
0
def check_app_key(api_key, required_scopes):
	if api_key == "":
		raise OAuthProblem('Please provide app token!')
	db = pymysql.connect(db=config('sqlUser'), user=config('sqlUser'), passwd=config('sqlPass'), host='localhost', port=3306)
	cursor=db.cursor(pymysql.cursors.DictCursor)
	sql="SELECT * FROM Core_RESTAPI.v5__vw_App_Keys WHERE 1=1 AND app_key = %s;"
	cursor.execute(sql,(api_key,))
	results=cursor.fetchone()
	cursor.close()
	db.close()
	if not results:
		raise OAuthProblem('App Key Invalid')
	if not api_key == results['app_key']:
		raise OAuthProblem('App Key Invalid')
	if results['locked'] == 1:
		raise OAuthProblem('The account associated with the supplied APP key is locked')
	if results['banned'] == 1:
		raise OAuthProblem('The account associated with the supplied APP key has been banned')
	if results['expired'] == 1:
		raise OAuthProblem('This APP key has expired')
	if results['blocked'] == 1:
		raise OAuthProblem('This APP key has been blocked')
	if results['revoked'] == 1:
		raise OAuthProblem('This APP key has been revoked')
	if results['compromised'] == 1:
		raise OAuthProblem('This APP key has been compromised')
	return {'uid': results}
Beispiel #5
0
def get_bearer_token(request):
    auth_header = request.headers.get('Authorization')
    if not auth_header:
        logger.warning("Request missing Authorization header")
        raise OAuthProblem('Missing authorization header')
    ah_split = auth_header.split()
    if len(ah_split) != 2 or ah_split[0].lower() != 'bearer':
        logger.warning("invalid auth header. expecting 'bearer' and token with space between")
        raise OAuthProblem('Invalid request header')
    _id_token = ah_split[1]
    return _id_token
Beispiel #6
0
def verify_secret(request):
    key = request.headers.get(rokwire_api_key_header)
    if not key:
        logger.warning("Request missing the " + rokwire_api_key_header + " header")
        raise OAuthProblem('Missing API Key')  # missing header means bad request
    # Assumption is that the key is a comma separated list of uuid's
    # This simply turns it in to a list and iterates. If the supplied key is in this list, true is returned
    # Otherwise, an error is raised.
    keys = os.getenv('ROKWIRE_API_KEY').strip().split(',')
    for test_key in keys:
        if key == test_key.strip():  # just in case there are embedded blanks
            return True
    raise OAuthProblem('Invalid API Key') # failed matching means unauthorized in this context.
Beispiel #7
0
def verify_apikey(key, required_scopes=None):
    if not key:
        logger.warning("API key is missing the " + rokwire_api_key_header + " header")
        raise OAuthProblem('Missing API Key')
    # Assumption is that the key is a comma separated list of uuid's
    # This simply turns it in to a list and iterates. If the supplied key is in this list, true is returned
    # Otherwise, an error is raised.
    keys = os.getenv('ROKWIRE_API_KEY').strip().split(',')
    for test_key in keys:
        if key == test_key.strip():  # just in case there are embedded blanks
            return {'token_valid': True}
    else:
        raise OAuthProblem('Invalid API Key')
    def wrapper(*args, **kwargs):
        logger.debug("%s Oauth verification...", request.url)

        authorization = request.headers.get('Authorization')  # type: str

        # check if session authenticated user
        is_authenticated = flask_session.get('is_authenticated')
        user = flask_session.get('user')
        token = flask_session.get('access_token')

        if not authorization and not token:
            logger.info("... No auth provided. Aborting with 401.")
            raise OAuthProblem(description='No authorization token provided')

        if not all([user, is_authenticated, token]):
            if not token:
                try:
                    _, token = authorization.split()  # type: str, str
                except ValueError:
                    raise OAuthProblem(
                        description='Invalid authorization header')

            token_info = fetch_token_info(token_info_url, token)

            user_scopes = set(token_info['scope'])

            logger.debug("... Scopes required: %s", allowed_scopes)
            logger.debug("... User scopes: %s", user_scopes)

            if not allowed_scopes <= user_scopes:
                logger.info(
                    textwrap.dedent("""
                            ... User scopes (%s) do not match the scopes necessary to call endpoint (%s).
                             Aborting with 403.""").replace('\n', ''),
                    user_scopes, allowed_scopes)
                raise OAuthScopeProblem(
                    description=
                    'Provided token doesn\'t have the required scope',
                    required_scopes=allowed_scopes,
                    token_scopes=user_scopes)

            logger.info("... Token authenticated.")

            request.user = token_info.get('uid')
            request.token_info = token_info

            set_token_info(token_info)

        return function(*args, **kwargs)
Beispiel #9
0
def auth(api_key, required_scopes):
    print(trialstreamer.config.API_KEYS)
    print(api_key)
    info = trialstreamer.config.API_KEYS.get(api_key, None)
    if not info:
        raise OAuthProblem('Invalid token')
    return info
Beispiel #10
0
def apikey_auth(token, required_scopes):
    try:
        user = db.find_user_by_authorization(token)
    except NotFoundError:
        raise OAuthProblem("Invalid token")

    return {"uid": user.uid}
Beispiel #11
0
def apikey_auth(token, required_scopes):
    validate = TOKEN_DB.get(token, None)
    if not validate:
        log('Invalid token', 'critical')
        raise OAuthProblem('Invalid token!')
    log(f'User Logged: {validate}')
    return validate
def basic_auth(username, password, required_scopes=None):
    if username == USER_DB.get('username') and password == USER_DB.get(
            'password'):
        return {'sub': 'admin'}
    else:
        raise OAuthProblem('Invalid username or password')
    return None
Beispiel #13
0
def apikey_auth(token, required_scopes):
    info = TOKEN_DB.get(token, None)

    if not info:
        raise OAuthProblem('Invalid token')

    return info
Beispiel #14
0
def get_keyset(request_url):
    keyset_resp = requests.get(request_url)
    if keyset_resp.status_code != 200:
        logger.warning("bad status getting keyset. status code = %s" %
                       keyset_resp.status_code)
        raise OAuthProblem('Invalid token')
    keyset = keyset_resp.json()
    return keyset
def apikey_auth(apikey, required_scopes=None):
    """ Simple function to validate an API key and retrieve the user's information in the process """
    api_user = User.query.filter_by(api_token=apikey).first()

    if api_user is None:
        raise OAuthProblem('Invalid API key')

    return api_user
Beispiel #16
0
def authorize(group_name=None):

    if 'user_token_data' not in g:
        raise OAuthProblem('Token data not available for authorization. Most likely an authentication error.')
    else:
        id_info = g.user_token_data

        if group_name is not None:
            # So we are to check is a group membership is required.
            if uiucedu_is_member_of in id_info:
                is_member_of = id_info[uiucedu_is_member_of]
                print("is_member_of" + str(is_member_of))
                if group_name not in is_member_of:
                    logger.warning("user is not a member of the group " + group_name)
                    raise OAuthProblem('Invalid token')
            else:
                logger.warning(uiucedu_is_member_of + " field is not present in the ID Token")
                raise OAuthProblem('Invalid token')
Beispiel #17
0
        def wrapper(request):
            authorized_domains = Config.get_allowed_email_domains().split()
            if "token_info" in request.context.values:
                token_info = request.context.values["token_info"]

                if not int(token_info["expires_in"]) > 0:
                    raise OAuthProblem(
                        description="Authorization token has expired")
                if json.loads(token_info["email_verified"]) is not True:
                    raise OAuthProblem(
                        description="User's email is not verified")
                if self.testing_403 or not any(
                        token_info["email"].endswith("@" + ad)
                        for ad in authorized_domains):
                    raise Forbidden(
                        description=
                        "User is not authorized to access this resource")
            return function(request)
Beispiel #18
0
def verify_apikey(token, required_scopes):
    """Helper function to verify provided TOKEN with REQUIRED_SCOPES."""
    config = current_app.config
    TOKEN_DB = config["api_tokens"]
    info = TOKEN_DB.get(token, None)
    if not info:
        raise OAuthProblem(
            "Invalid token provided, please authorize with CORRECT Api-key!")
    return info
def apikey_auth(token, required_scopes):
    # info = TOKEN_DB.get(token, None)
    user = db.session.query(TolidUser) \
        .filter(TolidUser.api_key == token) \
        .one_or_none()

    if user is None:
        raise OAuthProblem('Invalid api-key token')

    return {"user": user.name, "uid": user.user_id}
Beispiel #20
0
def get_unverified_header_payload(id_token):
    try:
        # We need to get both the header and the payload initially as unverified since we have to
        # check their issuer, key id and a few other items before we can figure out how to unpack them
        unverified_header = jwt.get_unverified_header(id_token)
        unverified_payload = jwt.decode(id_token, verify=False)
    except jwt.exceptions.PyJWTError as jwte:
        logger.warning("jwt error on get unverified header. message = %s" %
                       jwte)
        raise OAuthProblem('Invalid token')
    return unverified_header, unverified_payload
Beispiel #21
0
def decode_id_token(id_token, keyset, target_client_ids, kid):
    matching_jwks = [
        key_dict for key_dict in keyset['keys'] if key_dict['kid'] == kid
    ]
    if len(matching_jwks) != 1:
        logger.warning("should have exactly one match for kid = %s" % kid)
        raise OAuthProblem('Invalid token')
    jwk = matching_jwks[0]
    pub_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(jwk))
    try:
        id_info = jwt.decode(id_token,
                             key=pub_key,
                             audience=target_client_ids,
                             verify=True)
    except jwt.exceptions.PyJWTError as jwte:
        logger.warning("jwt error on decode. message = %s" % jwte)
        raise OAuthProblem('Invalid token')
    if not id_info:
        logger.warning("id_info was not returned from decode")
        raise OAuthProblem('Invalid token')
    return id_info
Beispiel #22
0
def authenticate(group_name=None, internal_token_only=False):

    should_use_security_token_auth = False
    app = flask.current_app
    if request.endpoint in app.view_functions:
        view_func = app.view_functions[request.endpoint]
        should_use_security_token_auth = getattr(view_func, '_use_security_token_auth', False)
    # print("should use security token auth = %s" % should_use_security_token_auth)

    auth_header = request.headers.get('Authorization')
    if not auth_header:
        logger.warning("Request missing Authorization header")
        raise OAuthProblem('Missing authorization header')
    ah_split = auth_header.split()
    if len(ah_split) != 2 or ah_split[0].lower() != 'bearer':
        logger.warning("invalid auth header. expecting 'bearer' and token with space between")
        raise OAuthProblem('Invalid request header')
    _id_token = ah_split[1]
    id_info = verify_userauth(_id_token, group_name, internal_token_only)

    return id_info
Beispiel #23
0
def check_auth_key(api_key, required_scopes):
	if api_key == "":
		raise OAuthProblem('Please provide app token!')
	db = pymysql.connect(db=config('sqlUser'), user=config('sqlUser'), passwd=config('sqlPass'), host='localhost', port=3306)
	cursor=db.cursor(pymysql.cursors.DictCursor)
	sql="SELECT * FROM Core_RESTAPI.v5__vw_Auth_Keys WHERE 1=1 AND auth_key = %s;"
	cursor.execute(sql,(api_key,))
	authresults=cursor.fetchone()
	cursor.close()
	db.close()
	if not authresults:
		raise OAuthProblem('Auth Key Invalid')
	if authresults['blocked'] == 1:
		raise OAuthProblem('This Auth key has been blocked')
	if authresults['expired'] == 1:
		raise OAuthProblem('This Auth key has expired')
	if authresults['revoked'] == 1:
		raise OAuthProblem('This Auth key has been revoked')
	if authresults['compromised'] == 1:
		raise OAuthProblem('This Auth key has been compromised')
	app_key=authresults['app_key']

	get_appresults=check_app_key(app_key,'')
	appresults=get_appresults['uid']

	return {'uid': {'app': appresults, 'auth': authresults}}
Beispiel #24
0
def verify_userauth_coretoken(group_name=None):
    id_token = get_bearer_token(request)
    if not id_token:
        raise OAuthProblem('Missing id token')

    # check which token auth verify to use
    unverified_header, unverified_payload = get_unverified_header_payload(
        id_token)

    isAnonymous = unverified_payload.get('anonymous')
    if isAnonymous == True:
        return verify_core_token(group_name)
    return verify_core_userauth(id_token, group_name)
Beispiel #25
0
def authorize(group_name=None):

    if 'user_token_data' not in g:
        raise OAuthProblem(
            'Token data not available for authorization. Most likely an authentication error.'
        )
    else:
        id_info = g.user_token_data

        if group_name is not None:
            ROKWIRE_AUTH_HOST = os.getenv('ROKWIRE_AUTH_HOST', '')

            # So we are to check is a group membership is required.
            # Get the membership check keys based on issuer
            if id_info['iss'] == ROKWIRE_AUTH_HOST:
                is_member_of_key = is_member_of_claim
            else:
                is_member_of_key = uiucedu_is_member_of

            # check if the group_name is list or string
            if isinstance(group_name, str):
                # make group name as list
                group_name = [group_name]

            is_authorize = False
            if is_member_of_key in id_info:
                is_member_of = id_info[is_member_of_key]
                if is_member_of_key == is_member_of_claim:
                    is_member_of = is_member_of.split(',')
                for name in group_name:
                    if id_info['iss'] != ROKWIRE_AUTH_HOST:
                        name = ROKWIRE_GROUPS_MAP[name]
                    if name in is_member_of:
                        is_authorize = True
                        break

            if is_authorize is False:
                logger.warning("User not authorized.")
                raise OAuthProblem('Invalid token')
Beispiel #26
0
def token_info(access_token) -> dict:

    token = access_token
    jsonurl = urlopen("https://" + AUTH0_DOMAIN + "/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}
    for key in jwks["keys"]:
        if key["kid"] == unverified_header["kid"]:
            rsa_key = {
                "kty": key["kty"],
                "kid": key["kid"],
                "use": key["use"],
                "n": key["n"],
                "e": key["e"]
            }
    if rsa_key:
        try:
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer="https://" + AUTH0_DOMAIN + "/")
        except jwt.ExpiredSignatureError:
            raise OAuthProblem('Token is expired', 401)

        except jwt.JWTClaimsError:
            raise OAuthProblem(
                'Invalid claims. Please check the audience and issuer', 401)

        except Exception:
            raise OAuthProblem('Invaid token - unable to parse authentication',
                               401)

        _request_ctx_stack.top.current_user = payload

    return {'uid': payload['sub'], 'scope': payload['scope']}
def verify_githubauth(token_str):
    id_info = None
    if not token_str:
        logger.warning("Request missing id token")
        raise OAuthProblem('Missing id token')
    try:
        access_token = {
            'access_token': token_str,
            'token_type': 'bearer',
            'scope': ['']
        }
        github = OAuth2Session(GITHUB_CLIENT_ID, token=access_token)
        resp = github.get('https://api.github.com/user')
        if resp.status_code == 200:
            id_info = resp.json()
            print(id_info)
        else:
            logger.warning("The token provides is invalid")
            raise OAuthProblem('Invalid token')
    except:
        logger.warning("The token provides is invalid")
        raise OAuthProblem('Invalid token')

    return id_info
Beispiel #28
0
def info_from_ApiKeyAuth(api_key, required_scopes):
    """
    Check and retrieve authentication information from api_key.
    Returned value will be passed in 'token_info' parameter of your operation function, if there is one.
    'sub' or 'uid' will be set in 'user' parameter of your operation function, if there is one.

    :param api_key API key provided by Authorization header
    :type api_key: str
    :param required_scopes Always None. Used for other authentication method
    :type required_scopes: None
    :return: Information attached to provided api_key or None if api_key is invalid or does not allow access to called API
    :rtype: dict | None
    """

    info = TOKEN_DB.get(api_key, None)
    current_app.logger.debug("{} -- {} -- {}".format(info, api_key, TOKEN_DB))
    if not info:
        raise OAuthProblem('Invalid token')

    return info
Beispiel #29
0
def authorize_search(organization_id: int, trace_id: TraceId,
                     token_info: Claim):

    if not token_info.is_user_claim:
        raise OAuthProblem("Requires a user claim")

    if not token_info.has_organization_access(
            RoleOrganizationId(organization_id)):
        raise Forbidden

    user_id = UserId(token_info.content.node_id)

    datasets = PennsieveApiClient.get().get_datasets(
        headers=dict(**auth_header(), **with_trace_id_header(trace_id)))

    return SearchDatabase(
        db=current_app.config["db"],
        organization_id=organization_id,
        user_id=user_id,
        datasets=datasets,
    )
Beispiel #30
0
    async def _extract_token(self, token: str) -> Dict[str, Any]:
        if token == "null":
            return {"sub": self._default_user_id}
        try:
            unverified_header = jwt.get_unverified_header(token)
        except jwt.JWTError as e:
            raise OAuthProblem(
                description=
                "Invalid header: %s. Use an RS256 signed JWT Access Token." %
                e)
        if unverified_header["alg"] != "RS256":
            raise OAuthProblem(
                description=
                "Invalid algorithm %s. Use an RS256 signed JWT Access Token." %
                unverified_header["alg"])

        kids = await self.kids()
        try:
            rsa_key = kids[unverified_header["kid"]]
        except KeyError:
            raise OAuthProblem(
                description="Unable to find the matching Auth0 RSA public key")
        try:
            return jwt.decode(
                token,
                rsa_key,
                algorithms=["RS256"],
                audience=self._audience,
                issuer="https://%s/" % self._domain,
            )
        except jwt.ExpiredSignatureError as e:
            raise OAuthProblem(description="JWT expired: %s" % e)
        except jwt.JWTClaimsError as e:
            raise OAuthProblem(description="invalid claims: %s" % e)
        except jwt.JWTError as e:
            raise OAuthProblem(
                description="Unable to parse the authentication token: %s" % e)