コード例 #1
0
def email_login_code(request):
    email = request.GET.get("email")
    code = request.GET.get("code")
    if not email or not code:
        return redirect("login")

    goto = request.GET.get("goto")
    email = email.lower().strip()
    code = code.lower().strip()

    user = Code.check_code(recipient=email, code=code)
    session = Session.create_for_user(user)

    if not user.is_email_verified:
        # save 1 click and verify email
        user.is_email_verified = True
        user.save()

    if user.deleted_at:
        # cancel user deletion
        user.deleted_at = None
        user.save()

    redirect_to = reverse("profile", args=[user.slug]) if not goto else goto
    response = redirect(redirect_to)
    return set_session_cookie(response, user, session)
コード例 #2
0
ファイル: auth.py プロジェクト: maxlipsky/vas3k.club
def debug_dev_login(request):
    if not settings.DEBUG:
        raise AccessDenied(title="Эта фича доступна только при DEBUG=true")

    user, is_created = User.objects.get_or_create(
        slug="dev",
        defaults=dict(
            patreon_id="123456",
            membership_platform_type=User.MEMBERSHIP_PLATFORM_PATREON,
            email="*****@*****.**",
            full_name="Senior 23 y.o. Developer",
            company="FAANG",
            position="Team Lead конечно",
            balance=10000,
            membership_started_at=datetime.utcnow(),
            membership_expires_at=datetime.utcnow() +
            timedelta(days=365 * 100),
            created_at=datetime.utcnow(),
            updated_at=datetime.utcnow(),
            is_email_verified=True,
            moderation_status=User.MODERATION_STATUS_APPROVED,
            roles=["god"],
        ),
    )

    if is_created:
        Post.upsert_user_intro(user, "Очень плохое интро", is_visible=True)

    session = Session.create_for_user(user)

    return set_session_cookie(redirect("profile", user.slug), user, session)
コード例 #3
0
ファイル: auth.py プロジェクト: DmitryKhitrin/vas3k.club
def debug_random_login(request):
    if not settings.DEBUG:
        raise AccessDenied(title="Эта фича доступна только при DEBUG=true")

    slug = "random_" + random_string()
    user, is_created = User.objects.get_or_create(
        slug=slug,
        defaults=dict(
            patreon_id=random_string(),
            membership_platform_type=User.MEMBERSHIP_PLATFORM_PATREON,
            email=slug + "@random.dev",
            full_name="%s %d y.o. Developer" % (random.choice(["Максим", "Олег"]), random.randint(18, 101)),
            company="Acme Corp.",
            position=random.choice(["Подниматель пингвинов", "Опускатель серверов", "Коллектор пивных бутылок"]),
            balance=10000,
            membership_started_at=datetime.utcnow(),
            membership_expires_at=datetime.utcnow() + timedelta(days=365 * 100),
            created_at=datetime.utcnow(),
            updated_at=datetime.utcnow(),
            is_email_verified=True,
            moderation_status=User.MODERATION_STATUS_APPROVED,
        ),
    )

    if is_created:
        Post.upsert_user_intro(user, "Интро как интро, аппрув прошло :Р", is_visible=True)

    session = Session.create_for_user(user)

    return set_session_cookie(redirect("profile", user.slug), user, session)
コード例 #4
0
def debug_login(request, user_slug):
    if not (settings.DEBUG or settings.TESTS_RUN):
        raise AccessDenied(title="Эта фича доступна только при DEBUG=true")

    user = get_object_or_404(User, slug=user_slug)
    session = Session.create_for_user(user)

    return set_session_cookie(redirect("profile", user.slug), user, session)
コード例 #5
0
def email_login(request):
    if request.method != "POST":
        return redirect("login")

    goto = request.POST.get("goto")
    email_or_login = request.POST.get("email_or_login")
    if not email_or_login:
        return redirect("login")

    email_or_login = email_or_login.strip()

    if "|-" in email_or_login:
        # secret_hash login
        email_part, secret_hash_part = email_or_login.split("|-", 1)
        user = User.objects.filter(email=email_part,
                                   secret_hash=secret_hash_part).first()
        if not user:
            return render(
                request, "error.html", {
                    "title":
                    "Такого юзера нет 🤔",
                    "message":
                    "Пользователь с таким кодом не найден. "
                    "Попробуйте авторизоваться по обычной почте или юзернейму.",
                })

        session = Session.create_for_user(user)
        redirect_to = reverse("profile", args=[user.slug
                                               ]) if not goto else goto
        response = redirect(redirect_to)
        return set_session_cookie(response, user, session)
    else:
        # email/nickname login
        user = User.objects.filter(
            Q(email=email_or_login.lower()) | Q(slug=email_or_login)).first()
        if not user:
            return render(
                request, "error.html", {
                    "title":
                    "Такого юзера нет 🤔",
                    "message":
                    "Пользователь с такой почтой не найден в списке членов Клуба. "
                    "Попробуйте другую почту или никнейм. "
                    "Если совсем ничего не выйдет, напишите нам, попробуем помочь.",
                })

        code = Code.create_for_user(user=user,
                                    recipient=user.email,
                                    length=settings.AUTH_CODE_LENGTH)
        async_task(send_auth_email, user, code)
        async_task(notify_user_auth, user, code)

        return render(request, "auth/email.html", {
            "email": user.email,
            "goto": goto,
        })
コード例 #6
0
    def authorise(self):
        if not self.user:
            raise ValueError('Missed `user` property to use this method')

        session = Session.create_for_user(self.user)
        self.cookies["token"] = session.token
        self.cookies["token"]["expires"] = datetime.utcnow() + timedelta(days=30)
        self.cookies["token"]['httponly'] = True
        self.cookies["token"]['secure'] = True

        return self
コード例 #7
0
def patreon_oauth_callback(request):
    code = request.GET.get("code")
    if not code:
        return render(request, "error.html", {
            "title": "Что-то сломалось между нами и патреоном",
            "message": "Так бывает. Попробуйте залогиниться еще раз"
        })

    try:
        auth_data = patreon.fetch_auth_data(code)
        user_data = patreon.fetch_user_data(auth_data["access_token"])
    except PatreonException as ex:
        if "invalid_grant" in str(ex):
            return render(request, "error.html", {
                "title": "Тут такое дело 😭",
                "message": "Авторизация патреона — говно. "
                           "Она не сразу понимает, что вы стали патроном и отдаёт "
                           "статус «отказано» в первые несколько минут, а иногда и часов. "
                           "Я уже написал им в саппорт, но пока вам надо немного подождать и авторизоваться снова. "
                           "Если долго не будет пускать — напишите мне в личку на патреоне."
            })

        return render(request, "error.html", {
            "message": "Не получилось загрузить ваш профиль с серверов патреона. "
                       "Попробуйте еще раз, наверняка оно починится. "
                       f"Но если нет, то вот текст ошибки, с которым можно пожаловаться мне в личку:",
            "data": str(ex)
        })

    membership = patreon.parse_active_membership(user_data)
    if not membership:
        return render(request, "error.html", {
            "title": "Надо быть патроном, чтобы состоять в Клубе",
            "message": "Кажется, вы не патроните <a href=\"https://www.patreon.com/join/vas3k\">@vas3k</a>. "
                       "А это одно из основных требований для входа в Клуб.<br><br>"
                       "Ещё иногда бывает, что ваш банк отказывает патреону в снятии денег. "
                       "Проверьте, всё ли там у них в порядке."
        })

    now = datetime.utcnow()

    # get user by patreon_id or email
    user = User.objects.filter(Q(patreon_id=membership.user_id) | Q(email=membership.email.lower())).first()
    if not user:
        # user is new, create it
        try:
            user = User.objects.create(
                patreon_id=membership.user_id,
                email=membership.email.lower(),
                full_name=membership.full_name[:120],
                avatar=upload_image_from_url(membership.image) if membership.image else None,
                membership_platform_type=User.MEMBERSHIP_PLATFORM_PATREON,
                membership_started_at=membership.started_at,
                membership_expires_at=membership.expires_at,
                balance=membership.lifetime_support_cents / 100,
                created_at=now,
                updated_at=now,
                is_email_verified=False,
            )
        except IntegrityError:
            return render(request, "error.html", {
                "title": "💌 Придётся войти через почту",
                "message": "Пользователь с таким имейлом уже зарегистрирован, но не через патреон. "
                           "Чтобы защититься от угона аккаунтов через подделку почты на патреоне, "
                           "нам придётся сейчас попросить вас войти через почту."
            })
    else:
        # user exists
        if user.deleted_at:
            return render(request, "error.html", {
                "title": "💀 Аккаунт был удалён",
                "message": "Войти через этот патреон больше не получится"
            })

        # update membership dates
        user.balance = membership.lifetime_support_cents / 100  # TODO: remove when the real money comes in
        if membership.expires_at > user.membership_expires_at:
            user.membership_expires_at = membership.expires_at

    user.membership_platform_data = {
        "access_token": auth_data["access_token"],
        "refresh_token": auth_data["refresh_token"],
    }
    user.save()

    # create a new session token to authorize the user
    session = Session.create_for_user(user)
    redirect_to = reverse("profile", args=[user.slug])
    state = request.GET.get("state")
    if state:
        state_dict = dict(parse_qsl(state))
        if "goto" in state_dict:
            redirect_to = state_dict["goto"]

    response = redirect(redirect_to)
    return set_session_cookie(response, user, session)
コード例 #8
0
ファイル: patreon.py プロジェクト: thelebster/vas3k.club
def patreon_oauth_callback(request):
    code = request.GET.get("code")
    if not code:
        return render(
            request,
            "error.html", {
                "title": "Что-то сломалось между нами и патреоном",
                "message": "Так бывает. Попробуйте залогиниться еще раз"
            },
            status=500)

    try:
        auth_data = patreon.fetch_auth_data(code)
        user_data = patreon.fetch_user_data(auth_data["access_token"])
    except PatreonException as ex:
        if "invalid_grant" in str(ex):
            return render(
                request,
                "error.html", {
                    "title":
                    "Тут такое дело 😭",
                    "message":
                    "Авторизация патреона — говно. "
                    "Она не сразу понимает, что вы стали патроном и отдаёт "
                    "статус «отказано» в первые несколько минут, а иногда и часов. "
                    "Я уже написал им в саппорт, но пока вам надо немного подождать и авторизоваться снова. "
                    "Если долго не будет пускать — напишите мне в личку на патреоне."
                },
                status=503)

        return render(
            request,
            "error.html", {
                "message":
                "Не получилось загрузить ваш профиль с серверов патреона. "
                "Попробуйте еще раз, наверняка оно починится. "
                f"Но если нет, то вот текст ошибки, с которым можно пожаловаться мне в личку:",
                "data":
                str(ex)
            },
            status=504)

    membership = patreon.parse_active_membership(user_data)
    if not membership:
        return render(
            request,
            "error.html", {
                "title":
                "Надо быть патроном, чтобы состоять в Клубе",
                "message":
                "Кажется, вы не патроните <a href=\"https://www.patreon.com/join/vas3k\">@vas3k</a>. "
                "А это одно из основных требований для входа в Клуб.<br><br>"
                "Ещё иногда бывает, что ваш банк отказывает патреону в снятии денег. "
                "Проверьте, всё ли там у них в порядке."
            },
            status=402)

    now = datetime.utcnow()

    # get user by patreon_id or email
    user = User.objects.filter(
        Q(patreon_id=membership.user_id)
        | Q(email=membership.email.lower())).first()
    if not user:
        # user is new, do not allow patreon users to register
        return render(
            request,
            "error.html", {
                "title":
                "🤕 Регистрироваться через Патреон больше нельзя",
                "message":
                "Возможность входа через Патреон осталась только для легаси-юзеров, "
                "но создавать новые аккаунты в Клубе через него больше нельзя. "
                "Через Патреон регистрируется очень много виртуалов и прочих анонимов, "
                "так как им это дешево. Мы же устали их ловить и выгонять, "
                "потому решили полностью прикрыть регистрацию."
            },
            status=400)

    else:
        # user exists
        if user.deleted_at:
            return render(
                request,
                "error.html", {
                    "title": "💀 Аккаунт был удалён",
                    "message": "Войти через этот патреон больше не получится"
                },
                status=404)

        # update membership dates
        user.balance = membership.lifetime_support_cents / 100
        if membership.expires_at > user.membership_expires_at:
            user.membership_expires_at = membership.expires_at

    user.membership_platform_data = {
        "access_token": auth_data["access_token"],
        "refresh_token": auth_data["refresh_token"],
    }
    user.save()

    # create a new session token to authorize the user
    session = Session.create_for_user(user)
    redirect_to = reverse("profile", args=[user.slug])
    state = request.GET.get("state")
    if state:
        state_dict = dict(parse_qsl(state))
        if "goto" in state_dict:
            redirect_to = state_dict["goto"]

    response = redirect(redirect_to)
    return set_session_cookie(response, user, session)