Beispiel #1
0
def external_login(request):
    goto = request.GET.get("redirect")
    if not goto:
        return render(request, "error.html",
                      {"message": "Нужен параметр ?redirect"})

    me = authorized_user(request)
    if not me:
        redirect_here_again = quote(reverse("external_login") +
                                    f"?redirect={goto}",
                                    safe="")
        return redirect(reverse("login") + f"?goto={redirect_here_again}")

    # TODO: it would be nice to show "authorize" window here

    payload = {
        "user_slug": me.slug,
        "user_name": me.full_name,
        "user_email": me.email,
        "exp": datetime.utcnow() + settings.JWT_EXP_TIMEDELTA,
    }

    jwt_token = jwt.encode(payload, settings.JWT_PRIVATE_KEY,
                           settings.JWT_ALGORITHM).decode("utf-8")

    # TODO: implement proper url parsing + domain validation + query building
    if "?" in goto:
        goto += f"&jwt={jwt_token}"
    else:
        goto += f"?jwt={jwt_token}"

    return redirect(goto)
Beispiel #2
0
def external_login(request):
    goto = request.GET.get("redirect")
    if not goto:
        return render(request,
                      "error.html", {"message": "Нужен параметр ?redirect"},
                      status=400)

    # check if user is logged in or redirect to login screen
    me = authorized_user(request)
    if not me:
        redirect_here_again = quote(reverse("external_login") +
                                    f"?redirect={goto}",
                                    safe="")
        return redirect(reverse("login") + f"?goto={redirect_here_again}")

    # we only authorize applications we know with the keys we set for them
    app_id = request.GET.get("app_id")
    app = Apps.objects.filter(id=app_id).first()
    if not app:
        return render(
            request,
            "error.html",
            {"message": "Неизвестное приложение, проверьте параметр ?app_id"},
            status=400)

    # check if redirect_url is in the list of allowed urls
    goto_parsed = urlparse(goto)
    goto_path_without_params = f"{goto_parsed.scheme}://{goto_parsed.netloc}{goto_parsed.path}"
    if goto_path_without_params not in app.redirect_urls:
        return render(
            request,
            "error.html", {
                "message":
                f"'{goto}' не находится в списке разрешеных redirect_urls для этого приложения"
            },
            status=400)

    # TODO: show "authorize" window and ask for user's consent here

    # success! issue a new signed JWT
    payload = {
        "user_slug": me.slug,
        "user_name": me.full_name,
        "user_email": me.email,
        "exp": datetime.utcnow() + timedelta(hours=app.jwt_expire_hours),
    }
    jwt_token = jwt.encode(payload,
                           app.jwt_secret,
                           algorithm=app.jwt_algorithm)

    # add ?jwt= to redirect_url and activate the redirect
    goto_params = parse_qsl(goto_parsed.query)
    goto_params += [("jwt", jwt_token)]
    return redirect(f"{goto_path_without_params}?{urlencode(goto_params)}")
Beispiel #3
0
def board(request, board_slug):
    board = get_object_or_404(Board, slug=board_slug)

    if board.is_private:
        me = authorized_user(request)
        if not me:
            return render(request, "board_no_access.html", {
                "board": board
            }, status=401)

    blocks = BoardBlock.objects.filter(board=board)
    feeds = BoardFeed.objects.filter(board=board)
    return render(request, "board.html", {
        "board": board,
        "blocks": blocks,
        "feeds": feeds,
    })
Beispiel #4
0
def external(request):
    goto = request.GET.get("redirect")
    if not goto:
        return render(request, "error.html", {"message": "Нужен параметр ?redirect"})

    me = authorized_user(request)
    if not me:
        redirect_here_again = quote(reverse("external") + f"?redirect={goto}", safe="")
        return redirect(reverse("login") + f"?goto={redirect_here_again}")

    payload = {
        "user_id": me.id,
        "user_name": me.name,
        "exp": datetime.utcnow() + settings.JWT_EXP_TIMEDELTA,
    }
    jwt_token = jwt.encode(payload, settings.JWT_SECRET, settings.JWT_ALGORITHM).decode("utf-8")
    return redirect(f"{goto}?jwt={jwt_token}")
Beispiel #5
0
def patreon_login(request):
    user = authorized_user(request)
    if user:
        return redirect("profile", user.slug)

    state = {}
    goto = request.GET.get("goto")
    if goto:
        state["goto"] = goto

    query_string = urlencode({
        "response_type": "code",
        "client_id": settings.PATREON_CLIENT_ID,
        "redirect_uri": settings.PATREON_REDIRECT_URL,
        "scope": settings.PATREON_SCOPE,
        "state": urlencode(state) if state else "",
    })
    return redirect(f"{settings.PATREON_AUTH_URL}?{query_string}")
Beispiel #6
0
def board(request, board_slug):
    board = get_object_or_404(Board, slug=board_slug)

    if board.is_private:
        me = authorized_user(request)
        if not me:
            return render(request, "board_no_access.html", {
                "board": board
            }, status=401)

    cached_page = cache.get(f"board_{board.slug}")
    if cached_page and board.refreshed_at <= datetime.utcnow() - timedelta(seconds=settings.BOARD_CACHE_SECONDS):
        return cached_page

    blocks = BoardBlock.objects.filter(board=board)
    feeds = BoardFeed.objects.filter(board=board)
    result = render(request, "board.html", {
        "board": board,
        "blocks": blocks,
        "feeds": feeds,
    })
    cache.set(f"board_{board.slug}", result, settings.BOARD_CACHE_SECONDS)
    return result
Beispiel #7
0
def me(request):
    return {"me": authorized_user(request)}