示例#1
0
def ensure_root_dyn_token() -> None:
    """
    Create a dynamic app token owned by root, if none exist.
    """
    root = User.objects.get(character_id=0)
    if (token.Token.objects(owner=root,
                            token_type=token.Token.TokenType.dyn).count() > 0):
        return
    root_dyn_token = token.create_dynamic_app_token(root,
                                                    comments="Primary token")
    logging.info(
        "No dynamic app token owned by root, created one: %r",
        token.to_jwt(root_dyn_token),
    )
示例#2
0
async def post_token_use_from_per(
        tkn: Token = Depends(from_authotization_header), ):
    """
    Authenticates an application permanent token and returns a user token tied
    to the owner of that app token.
    """
    if tkn.token_type != Token.TokenType.per:
        raise HTTPException(
            status.HTTP_401_UNAUTHORIZED,
            detail="Must use a permanent app token for this path.",
        )
    assert_has_clearance(tkn.owner, "sni.create_use_token")
    user_token = create_user_token(
        tkn,
        User.objects.get(character_id=0),
    )
    user_token_str = to_jwt(user_token)
    return PostUseFromPerOut(user_token=user_token_str)
示例#3
0
async def post_token_per(
        data: PostTokenPerIn,
        tkn: Token = Depends(from_authotization_header_nondyn),
):
    """
    Creates a new permanent app token. Must be called with a permanent app
    token, and the owner must have a clearance level of 10.
    """
    assert_has_clearance(tkn.owner, "sni.create_per_token")
    if tkn.token_type != Token.TokenType.per:
        raise HTTPException(status.HTTP_401_UNAUTHORIZED)
    new_token = create_permanent_app_token(
        tkn.owner,
        callback=data.callback,
        comments=data.comments,
        parent=tkn,
    )
    return PostTokenPerOut(tkn=to_jwt(new_token))
示例#4
0
async def get_callback_esi(code: str, state: str):
    """
    ESI callback. You should not manually call this.

    Upon receiving a notification from EVE SSO, SNI redirects the client to the
    appropriate frontend callback, with the state code and user token in URL
    parameters.

    Reference:
        `OAuth 2.0 for Web Based Applications <https://docs.esi.evetech.net/docs/sso/web_based_sso_flow.html>`_
    """
    logging.info("Received callback from ESI for state %s", state)

    state_code: StateCode = StateCode.objects.get(uuid=state)
    state_code.delete()

    try:
        esi_response = get_access_token_from_callback_code(code)
        access_token = decode_access_token(esi_response.access_token)
        save_esi_tokens(esi_response)
    except EsiTokenError:
        return token_manipulation_error_response()

    usr: User = User.objects.get(character_id=access_token.character_id)
    if state_code.inviting_corporation is not None:
        usr.corporation = state_code.inviting_corporation
        usr.clearance_level = -1
        usr.save()

    if not is_authorized_to_login(usr):
        return not_authorized_to_login_response(usr.character_name,
                                                usr.character_id)
    if not token_has_enough_scopes(access_token, usr):
        return not_enough_scopes_response(
            usr.character_name,
            usr.character_id,
            list(usr.cumulated_mandatory_esi_scopes()),
            access_token.scp,
        )

    user_token = create_user_token(state_code.app_token, usr)
    user_jwt_str = to_jwt(user_token)
    logging.info("Issuing token %s to app %s", user_jwt_str,
                 state_code.app_token.uuid)

    if state_code.app_token.callback is None:
        return {
            "created_on": user_token.created_on,
            "expires_on": user_token.expires_on,
            "jwt": user_jwt_str,
            "owner": {
                "character_id": user_token.owner.character_id,
                "character_name": user_token.owner.character_name,
                "clearance_level": user_token.owner.clearance_level,
            },
        }

    request = requests.Request(
        "GET",
        state_code.app_token.callback,
        params={
            "state_code": str(state_code.uuid),
            "user_token": user_jwt_str,
        },
    )
    url = request.prepare().url
    if url is None:
        logging.error(
            "Failed to redirect user to %s",
            state_code.app_token.callback,
        )
        return PlainTextResponse(
            f"Failed to redirect to {state_code.app_token.callback}")
    return RedirectResponse(url=url)