Esempio n. 1
0
async def edit_paste(
    request: Request,
    paste_id: str,
    payload: payloads.PastePatch,
) -> Union[UJSONResponse, Dict[str, Optional[Union[str, int,
                                                   datetime.datetime]]]]:
    """Edit a paste on MystBin.
    * Requires authentication.
    """
    author = request.state.user
    if not author:
        return UJSONResponse({"error": "Forbidden"}, status_code=403)

    paste: Union[Record, int] = await request.app.state.db.edit_paste(
        paste_id,
        author["id"],
        payload.new_content,
        payload.new_expires,
        payload.new_nick,
    )
    if not paste or paste == 404:
        return UJSONResponse(
            {"error": "Paste was not found or you are not it's author."},
            status_code=404,
        )

    return UJSONResponse(dict(paste[0]))
Esempio n. 2
0
async def delete_pastes(
    request: Request,
    payload: payloads.PasteDelete,
) -> Union[UJSONResponse, Dict[str, List[str]]]:
    """Deletes pastes on MystBin.
    * Requires authentication.
    """
    # We will filter out the pastes that are authorized and unauthorized, and return a clear response
    response = {"succeeded": [], "failed": []}

    author: Record = request.state.user
    if not author:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    for paste in payload.pastes:
        if await request.app.state.db.ensure_author(paste, author["id"]):
            response["succeeded"].append(paste)
        else:
            response["failed"].append(paste)

    for paste in response["succeeded"]:
        await request.app.state.db.delete_paste(paste,
                                                author["id"],
                                                admin=False)

    return UJSONResponse(response, status_code=200)
Esempio n. 3
0
async def get_bookmarks(request: Request, authorization: str = Depends(auth_model)):
    """Fetches all of the authorized users bookmarks
    * Requires authentication
    """
    if not request.state.user:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    data = await request.app.state.db.get_bookmark(request.state.user['id'])
    return UJSONResponse({"bookmarks": data})
Esempio n. 4
0
async def get_admin_userlist(request: Request):
    """
    Returns a count of how many users there are
    * Requires admin authentication.
    """
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    count = await request.app.state.db.get_admin_usercount()
    return UJSONResponse({"count": count})
Esempio n. 5
0
async def unsubscribe_user(request: Request, user_id: int) -> UJSONResponse:
    """
    Revokes a users subscriber access
    * Requires admin authentication
    """
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    success = await request.app.state.db.toggle_subscription(user_id, False)
    return UJSONResponse({"success": success})
Esempio n. 6
0
async def remove_ban(request: Request, ip: str = None, userid: int = None):
    if not ip and not userid:
        return UJSONResponse({"error": "Bad Request"}, status_code=400)

    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    if await request.app.state.db.unban_user(userid, ip):
        return Response(status_code=204)

    return Response(status_code=400)
Esempio n. 7
0
async def post_ban(request: Request,
                   reason: str,
                   ip: str = None,
                   userid: int = None):
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    data = await request.app.state.db.ban_user(ip=ip,
                                               userid=userid,
                                               reason=reason)
    return UJSONResponse({"success": data})
Esempio n. 8
0
async def delete_bookmark(request: Request, bookmark: payloads.BookmarkPutDelete, authorization: str = Depends(auth_model)) -> Response:
    """Deletes a bookmark on the authorized user's account
    * Requires authentication.
    """
    if not request.state.user:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    if not await request.app.state.db.delete_bookmark(request.state.user['id'], bookmark.paste_id):
        return UJSONResponse({"error": "Bookmark does not exist"}, status_code=400)
    else:
        return Response(status_code=204)
Esempio n. 9
0
async def auth_from_discord(
        request: Request) -> Union[Dict[str, str], UJSONResponse]:
    """Allows user to authenticate from Discord OAuth."""
    try:
        data = await request.json()
        code = data.get("code", None)
    except:
        return UJSONResponse({"error": "Bad JSON body passed"},
                             status_code=421)

    if not code:
        return UJSONResponse({"error": "Missing code query"}, status_code=400)

    client_id = request.app.config["apps"]["discord_application_id"]
    client_secret = request.app.config["apps"]["discord_application_secret"]
    url = yarl.URL(
        request.app.config["site"]["frontend_site"]).with_path("/discord_auth")

    data = {
        "client_id": client_id,
        "client_secret": client_secret,
        "grant_type": "authorization_code",
        "code": code,
        "redirect_uri": url,
        "scope": "identify email",
    }
    headers = {"Content-Type": "application/x-www-form-urlencoded"}

    async with request.app.state.client.post(
            "https://discord.com/api/v8/oauth2/token", data=data,
            headers=headers) as resp:
        data = await resp.json()
        token = data["access_token"]

    async with request.app.state.client.get(
            "https://discord.com/api/v8/users/@me",
            headers={"Authorization": f"Bearer {token}"},
    ) as resp:
        resp.raise_for_status()
        data = await resp.json()
        userid = data["id"]
        email = [data["email"]]
        username = f"{data['username']}#{data['discriminator']}"

    if request.state.user is not None:
        token = await request.app.state.db.update_user(
            request.state.user["id"], discord_id=userid, emails=email)
        return {"token": token}

    elif _id := await request.app.state.db.check_email(email):
        token = await request.app.state.db.update_user(_id,
                                                       discord_id=userid,
                                                       emails=email)
        return UJSONResponse({"token": token})
Esempio n. 10
0
async def disconnect_app(request: Request, app: str):
    if app not in ("github", "discord", "google"):
        return Response(status_code=404)

    if not request.state.user:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    if not await request.app.state.db.unlink_account(request.state.user["id"],
                                                     app):
        return UJSONResponse({"error": "Account not linked"}, status_code=400)

    return Response(status_code=204)
Esempio n. 11
0
async def search_bans(request: Request, search: str = None, page: int = 1):
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    if search is not None:
        data = await request.app.state.db.search_bans(search=search)
        if isinstance(data, str):
            return UJSONResponse({"reason": data, "searches": []})

        return UJSONResponse({"reason": None, "searches": data})
    else:
        return UJSONResponse(await request.app.state.db.get_bans(page))
Esempio n. 12
0
async def get_all_pastes(
    request: Request, count: int, page: Optional[int] = 0, oldest_first: bool = False
):
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    if page < 0:
        return UJSONResponse({"error": "Page must be greater than 0"}, status_code=421)
    elif count < 1:
        return UJSONResponse({"error": "Count must be greater than 1"}, status_code=421)

    return UJSONResponse({"pastes": await request.app.state.db.get_all_pastes(page, count, reverse=oldest_first)})
Esempio n. 13
0
async def auth_from_google(
        request: Request) -> Union[Dict[str, str], UJSONResponse]:
    """Allows user to authenticate from Google OAuth."""
    try:
        data = await request.json()
        code = data.get("code", None)
    except:
        return UJSONResponse({"error": "Bad JSON body passed"},
                             status_code=421)

    if not code:
        return UJSONResponse({"error": "Missing code query"}, status_code=400)

    client_id = request.app.config["apps"]["google_application_id"]
    client_secret = request.app.config["apps"]["google_application_secret"]
    url = yarl.URL(
        request.app.config["site"]["frontend_site"]).with_path("/google_auth")

    data = {
        "client_id": client_id,
        "client_secret": client_secret,
        "redirect_uri": url,
        "grant_type": "authorization_code",
        "code": code,
    }
    headers = {"Content-Type": "application/x-www-form-urlencoded"}

    async with request.app.state.client.post(
            "https://oauth2.googleapis.com/token", data=data,
            headers=headers) as resp:
        resp.raise_for_status()
        data = await resp.json()
        token = data["access_token"]

    async with request.app.state.client.get(
            "https://www.googleapis.com/userinfo/v2/me",
            headers={"Authorization": f"Bearer {token}"},
    ) as resp:
        resp.raise_for_status()
        data = await resp.json()
        email = [data["email"]]
        userid = data["id"]

    if request.state.user is not None:
        token = await request.app.state.db.update_user(
            request.state.user["id"], google_id=userid, emails=email)
        return UJSONResponse({"token": token})

    elif _id := await request.app.state.db.check_email(email):
        token = await request.app.state.db.update_user(_id,
                                                       google_id=userid,
                                                       emails=email)
        return UJSONResponse({"token": token})
Esempio n. 14
0
async def subscribe_user(
    request: Request, user_id: int, authorization: str = Depends(auth_model)
) -> UJSONResponse:
    """
    Gives a user subscriber access
    * Requires admin authentication
    """
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    success = await request.app.state.db.toggle_subscription(user_id, True)
    return UJSONResponse({"success": success})
Esempio n. 15
0
async def get_things(request: Request) -> UJSONResponse:
    """
    Handle a request to / when the server manages multiple things.
    Handle a GET request.
    :param request -- the request
    :return UJSONResponse
    """
    if request.app.state.mode == "gateway":
        things = request.app.state.things

        descriptions = []
        for idx, thing in tuple(things.get_things()):
            description = thing.as_thing_description()

            description["links"].append({
                "rel":
                "alternate",
                "href":
                f"{get_ws_href(request)}{thing.href}",
            })
            description["base"] = f"{get_http_href(request)}{thing.href}"

            description["securityDefinitions"] = {
                "nosec_sc": {
                    "scheme": "nosec",
                },
            }
            description["security"] = "nosec_sc"

            bak = copy.deepcopy(description)
            descriptions.append(bak)

        return UJSONResponse(descriptions)
    else:
        thing = request.app.state.thing.get_thing()
        description = thing.as_thing_description()

        description["links"].append({
            "rel":
            "alternate",
            "href":
            f"{get_ws_href(request)}{thing.href}",
        })
        description["base"] = f"{get_http_href(request)}{thing.href}"

        description["securityDefinitions"] = {
            "nosec_sc": {
                "scheme": "nosec",
            },
        }
        description["security"] = "nosec_sc"

        return UJSONResponse(description)
Esempio n. 16
0
async def create_bookmark(request: Request, bookmark: payloads.BookmarkPutDelete, authorization: str = Depends(auth_model)) -> Response:
    """Creates a bookmark on the authorized user's account
    * Requires authentication.
    """
    if not request.state.user:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    try:
        await request.app.state.db.create_bookmark(request.state.user['id'], bookmark.paste_id)
        return Response(status_code=201)
    except ValueError as e:
        return UJSONResponse({"error": e.args[0]}, status_code=400)
Esempio n. 17
0
async def get_self(
    request: Request, authorization: str = Depends(auth_model)
) -> Union[UJSONResponse, Dict[str, Union[str, int, bool]]]:
    """Gets the User object of the currently logged in user.
    * Requires authentication.
    """

    user = request.state.user
    if not user:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    return UJSONResponse(responses.User(**user).dict())
Esempio n. 18
0
async def create_rule(rule: RuleInput):
    rule_data = rule.dict()
    rule_data.update({"id": str(uuid.uuid4())})
    try:
        logger.debug(rule_data)
        rule = Rule(**rule_data)
        table.insert(rule_data)
        await re.load_rule(rule)
    except ValidationError as e:
        logger.error(str(e))
        return UJSONResponse(e.json(), status_code=422)

    return UJSONResponse(rule_data)
Esempio n. 19
0
async def get_admin_userlist(request: Request, page: int = 1):
    """
    Returns a list of smaller user objects
    * Requires admin authentication.
    """
    if page < 1:
        return UJSONResponse({"error": "page must be >= 1"}, status_code=400)

    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    data = await request.app.state.db.get_admin_userlist(page)
    return UJSONResponse(data)
Esempio n. 20
0
async def get_paste(request: Request,
                    paste_id: str,
                    password: Optional[str] = None) -> Response:
    """Get a paste from MystBin."""
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    paste = await request.app.state.db.get_paste(paste_id, password)
    if paste is None:
        return Response(status_code=404)

    resp = responses.PasteGetResponse(**paste)
    return UJSONResponse(recursive_hook(resp.dict()))
Esempio n. 21
0
async def get_paste(request: Request,
                    paste_id: str,
                    password: Optional[str] = None) -> UJSONResponse:
    """Get a paste from MystBin."""
    paste = await request.app.state.db.get_paste(paste_id, password)
    if paste is None:
        return UJSONResponse({"error": "Not Found"}, status_code=404)

    if paste["has_password"] and not paste["password_ok"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    resp = responses.PasteGetResponse(**paste)
    return UJSONResponse(recursive_hook(resp.dict()))
Esempio n. 22
0
async def get_any_user(request: Request,
                       user_id: int) -> Union[UJSONResponse, Dict[str, str]]:
    """Returns the User object of the passed user_id.
    * Requires admin authentication.
    """
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    data: Optional[Union[Record, int]] = await request.app.state.db.get_user(
        user_id=user_id)
    if data:
        return UJSONResponse(dict(data))
    return UJSONResponse({"error": "The given user was not found"},
                         status_code=400)
Esempio n. 23
0
async def create_lead(lead: LeadModel, request: Request, token: str):
    logger.info(
        f"""request: {request.json()}, headers: {dict(request.headers)},  token: {token}, ip:
                {request.client.host}""")
    result, processed = await LeadService.execute(str(token), lead)
    logger.info(f"response: {result}, processed: {processed}")
    if processed:
        return UJSONResponse(status_code=status.HTTP_201_CREATED,
                             content={
                                 "status": "ok",
                                 "message": "Batch Accepted!"
                             })
    return UJSONResponse(status_code=status.HTTP_400_BAD_REQUEST,
                         content=result)
Esempio n. 24
0
async def unban_user(
    request: Request,
    user_id: int,
    ip: str = None,
) -> UJSONResponse:
    """
    Unbans a user from the service
    * Requires admin authentication
    """
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    success = await request.app.state.db.unban_user(user_id, ip)
    return UJSONResponse({"success": success})
Esempio n. 25
0
async def get_server_stats(request: Request):
    if not request.state.user or not request.state.user["admin"]:
        return UJSONResponse({"error": "Unauthorized"}, status_code=401)

    data = {
        "memory": PROC.memory_full_info().uss / 1024 ** 2,
        "memory_percent": PROC.memory_percent(memtype="uss"),
        "cpu_percent": PROC.cpu_percent(),
        "uptime": (datetime.datetime.utcnow() - START_TIME).total_seconds(),
        "total_pastes": await request.app.state.db.get_paste_count(),
        "requests": request.app.state.request_stats["total"],
        "latest_request": request.app.state.request_stats["latest"].isoformat(),
    }

    return UJSONResponse(data, status_code=200)
Esempio n. 26
0
async def get_all_pastes(
    request: Request,
    limit: Optional[int] = None,
) -> Union[UJSONResponse, Dict[str, List[Dict[str, str]]]]:
    """Get all pastes for a specified author.
    * Requires authentication.
    """
    user = request.state.user
    if not user:
        return UJSONResponse({"error": "Forbidden"}, status_code=403)

    pastes = await request.app.state.db.get_all_user_pastes(user["id"], limit)
    pastes = [dict(entry) for entry in pastes]

    return UJSONResponse({"pastes": pastes})
Esempio n. 27
0
async def extract(data: BodyExtract):
    """
    Face extraction/embeddings endpoint accept json with
    parameters in following format:

       - **images**: dict containing either links or data lists. (*required*)
       - **max_size**: Resize all images to this proportions. Default: [640,480] (*optional*)
       - **threshold**: Detection threshold. Default: 0.6 (*optional*)
       - **return_face_data**: Return face crops encoded in base64. Default: False (*optional*)
       - **extract_embedding**: Extract face embeddings (otherwise only detect faces). Default: True (*optional*)
       - **extract_ga**: Extract gender/age. Default: False (*optional*)
       - **api_ver**: Output data serialization format. Currently only version "1" is supported (*optional*)
       \f

       :return:
       List[List[dict]]
    """

    images = jsonable_encoder(data.images)
    output = await processing.embed(images,
                                    max_size=data.max_size,
                                    return_face_data=data.return_face_data,
                                    extract_embedding=data.extract_embedding,
                                    threshold=data.threshold,
                                    extract_ga=data.extract_ga,
                                    api_ver=data.api_ver)

    return UJSONResponse(output)
Esempio n. 28
0
async def get_properties(thing: Thing = Depends(get_thing)) -> UJSONResponse:
    """
    Handle a request to /properties.
    :param thing -- the thing this request is for"
    :return: UJSONResponse
    """
    return UJSONResponse(await thing.get_properties())
Esempio n. 29
0
async def get_actions(thing: Thing = Depends(get_thing)) -> UJSONResponse:
    """
    Handle a request to /actions.
    :param thing-- the thing this request is for
    :return UJSONResponse
    """
    return UJSONResponse(await thing.get_action_descriptions())
Esempio n. 30
0
async def invoke_action(
    action_name: str,
    message: typing.Dict[str, typing.Any],
    thing: Thing = Depends(get_thing)
) -> UJSONResponse:
    """
    Handle a POST request.
    :param thing -- the thing this request is for
    :param action_name -- name of the action from the URL path
    :param message -- the request body
    :return UJSONResponse
    """
    response = {}
    for name, action_params in message.items():
        if name != action_name:
            continue

        input_ = None
        if "input" in action_params:
            input_ = action_params["input"]

        action = await thing.perform_action(name, input_)
        if action:
            response.update(await action.as_action_description())

            # Start the action
            asyncio.create_task(perform_action(action))

    return UJSONResponse(response, status_code=201)