Exemplo n.º 1
0
def api_login():
    password = request.form.get("password", None)
    email = request.form.get("email", None)

    def success(the_user):
        login_user(the_user)
        
        return Response(
            response = "Successfully logged in.",
            headers = {"X-CallSuccess": "True"}
        )

    def failure():
        return Response(
            response = "Incorrect email or password.",
            headers = {"X-CallSuccess": "False"}
        )

    # If the user is trying to login by giving us an access_token they got from
    # signing in through google, validate the token.
    access_token = request.form.get("access_token", None)
    if access_token and oauth_enabled:
        # Ask google to verify that they authed the user.
        req = requests.post(
            "https://www.googleapis.com/oauth2/v1/tokeninfo",
            data = { "access_token": access_token }
        )

        if req.status_code != requests.codes.ok:
            return failure()

        # Validate client id is matching to avoid confused deputy attack
        if req.json["audience"] != app.config["GOOGLE_APICLIENT_ID"]:
            raise RuntimeError("Invalid Client ID")

        # Grab the user from the database (here we also check to make sure that
        # this user actually has account on Galah).
        try:
            user = FlaskUser(User.objects.get(email = req.json["email"]))
        except User.DoesNotExist:
            return failure()

        return success(user)
    elif access_token and not oauth_enabled:
        raise RuntimeError("Login via OAuth2 is not configured.")
    
    # If the user is trying to authenticate through Galah...
    if email and password:
        try:
            user = FlaskUser(User.objects.get(email = email))
        except User.DoesNotExist:
            return failure()

        if check_seal(password, deserialize_seal(str(user.seal))):
            return success(user)
        else:
            return failure()
    
    raise RuntimeError("Malformed Request")
Exemplo n.º 2
0
def login():
    form = LoginForm()

    # If the user's input isn't immediately incorrect (validate_on_submit() will
    # not check if the email and password combo is valid, only that it could be
    # valid)
    if form.validate_on_submit():
        # Find the user with the given email
        try:
            user = FlaskUser(User.objects.get(email = form.email.data))
        except User.DoesNotExist:
            user = None

        if oauth_enabled and user and not user.seal:
            flash("You must use R'Mail to login.", category = "error")

            logger.info(
                "User %s has tried to log in via internal auth but their "
                "account does not have a seal.", user.email
            )

            return render_template(
                "login.html", form = form, oauth_enabled = oauth_enabled
            )

        # Check if the entered password is correct
        if not user or \
                not check_seal(form.password.data, deserialize_seal(str(user.seal))):
            flash("Incorrect email or password.", category = "error")

            logger.info(
                "User %s has entered an incorrect email/password pair during "
                "internal auth.", form.email.data
            )
        else:
            login_user(user)

            logger.info(
                "User %s has succesfully logged in via internal auth.",
                user.email
            )

            return redirect(form.redirect_target or url_for("browse_assignments"))
    elif oauth_enabled and request.args.get("type") == "rmail":
        # Login using Google OAuth2
        # Step 1 of two-factor authentication: redirect to AUTH url
        auth_uri = flow.step1_get_authorize_url()
        return redirect(auth_uri)

    return render_template(
        "login.html",
        form = form,
        oauth_enabled = oauth_enabled,
        google_login_heading = app.config["GOOGLE_LOGIN_HEADING"],
        google_login_caption = app.config["GOOGLE_LOGIN_CAPTION"]
    )
Exemplo n.º 3
0
def api_login():
    password = request.form.get("password", None)
    email = request.form.get("email", None)

    def success(the_user):
        login_user(the_user)

        return Response(response="Successfully logged in.",
                        headers={"X-CallSuccess": "True"})

    def failure():
        return Response(response="Incorrect email or password.",
                        headers={"X-CallSuccess": "False"})

    # If the user is trying to login by giving us an access_token they got from
    # signing in through google, validate the token.
    access_token = request.form.get("access_token", None)
    if access_token and oauth_enabled:
        # Ask google to verify that they authed the user.
        req = requests.post("https://www.googleapis.com/oauth2/v1/tokeninfo",
                            data={"access_token": access_token})

        if req.status_code != requests.codes.ok:
            return failure()

        # Validate client id is matching to avoid confused deputy attack
        if req.json["audience"] != app.config["GOOGLE_APICLIENT_ID"]:
            raise RuntimeError("Invalid Client ID")

        # Grab the user from the database (here we also check to make sure that
        # this user actually has account on Galah).
        try:
            user = FlaskUser(User.objects.get(email=req.json["email"]))
        except User.DoesNotExist:
            return failure()

        return success(user)
    elif access_token and not oauth_enabled:
        raise RuntimeError("Login via OAuth2 is not configured.")

    # If the user is trying to authenticate through Galah...
    if email and password:
        try:
            user = FlaskUser(User.objects.get(email=email))
        except User.DoesNotExist:
            return failure()

        if check_seal(password, deserialize_seal(str(user.seal))):
            return success(user)
        else:
            return failure()

    raise RuntimeError("Malformed Request")
Exemplo n.º 4
0
def api_login():
    def success(the_user):
        login_user(the_user)

        return Response(response="Successfully logged in.",
                        headers={"X-CallSuccess": "True"})

    def failure():
        return Response(response="Incorrect email or password.",
                        headers={"X-CallSuccess": "False"})

    # If the user is trying to login by giving us an access_token they got from
    # signing in through google, validate the token.
    access_token = request.form.get("access_token", None)
    if access_token and oauth_enabled:
        # Ask google to verify that they authed the user.
        req = requests.post("https://www.googleapis.com/oauth2/v1/tokeninfo",
                            data={"access_token": access_token})

        req_json = req.json()

        email = req_json.get("email", "unknown")

        if req.status_code != requests.codes.ok:
            logger.info("Invalid OAuth2 login by %s.", email)

            return failure()

        # Validate client id is matching to avoid confused deputy attack
        if req_json["audience"] != app.config["GOOGLE_APICLIENT_ID"]:
            logger.error("Non-matching audience field detected for user %s.",
                         email)

            return failure()

        # Grab the user from the database (here we also check to make sure that
        # this user actually has account on Galah).
        try:
            user = FlaskUser(User.objects.get(email=req_json["email"]))
        except User.DoesNotExist:
            logger.info(
                "User %s signed in via OAuth2 but a Galah account does not "
                "exist for that user.", email)

            return failure()

        logger.info("User %s successfully signed in with OAuth2.", email)

        return success(user)
    elif access_token and not oauth_enabled:
        logger.warning(
            "Attempted login via OAuth2 but OAuth2 is not configured.")

        return failure()

    # If the user is trying to authenticate through Galah...
    password = request.form.get("password", None)
    email = request.form.get("email", None)
    if email and password:
        try:
            user = FlaskUser(User.objects.get(email=email))
        except User.DoesNotExist:
            logger.info(
                "User %s tried to sign in via internal auth but a Galah "
                "account does not exist for that user.", email)

            return failure()

        if check_seal(password, deserialize_seal(str(user.seal))):
            logger.info(
                "User %s succesfully authenticated with internal auth.", email)

            return success(user)
        else:
            logger.info(
                "User %s tried to sign in via internal auth but an invalid "
                "password was given.", email)

            return failure()

    logger.warning("Malformed request.")

    return failure()
Exemplo n.º 5
0
def api_login():
    def success(the_user):
        login_user(the_user)

        return Response(
            response = "Successfully logged in.",
            headers = {"X-CallSuccess": "True"}
        )

    def failure():
        return Response(
            response = "Incorrect email or password.",
            headers = {"X-CallSuccess": "False"}
        )

    # If the user is trying to login by giving us an access_token they got from
    # signing in through google, validate the token.
    access_token = request.form.get("access_token", None)
    if access_token and oauth_enabled:
        # Ask google to verify that they authed the user.
        req = requests.post(
            "https://www.googleapis.com/oauth2/v1/tokeninfo",
            data = { "access_token": access_token }
        )

        req_json = req.json()

        email = req_json.get("email", "unknown")

        if req.status_code != requests.codes.ok:
            logger.info("Invalid OAuth2 login by %s.", email)

            return failure()

        # Validate client id is matching to avoid confused deputy attack
        if req_json["audience"] != app.config["GOOGLE_APICLIENT_ID"]:
            logger.error(
                "Non-matching audience field detected for user %s.", email
            )

            return failure()

        # Grab the user from the database (here we also check to make sure that
        # this user actually has account on Galah).
        try:
            user = FlaskUser(User.objects.get(email = req_json["email"]))
        except User.DoesNotExist:
            logger.info(
                "User %s signed in via OAuth2 but a Galah account does not "
                "exist for that user.", email
            )

            return failure()

        logger.info("User %s successfully signed in with OAuth2.", email)

        return success(user)
    elif access_token and not oauth_enabled:
        logger.warning("Attempted login via OAuth2 but OAuth2 is not configured.")

        return failure()

    # If the user is trying to authenticate through Galah...
    password = request.form.get("password", None)
    email = request.form.get("email", None)
    if email and password:
        try:
            user = FlaskUser(User.objects.get(email = email))
        except User.DoesNotExist:
            logger.info(
                "User %s tried to sign in via internal auth but a Galah "
                "account does not exist for that user.", email
            )

            return failure()

        if check_seal(password, deserialize_seal(str(user.seal))):
            logger.info(
                "User %s succesfully authenticated with internal auth.", email
            )

            return success(user)
        else:
            logger.info(
                "User %s tried to sign in via internal auth but an invalid "
                "password was given.", email
            )

            return failure()

    logger.warning("Malformed request.")

    return failure()
Exemplo n.º 6
0
def login():
    form = LoginForm()

    # Authentication details to be passed to the rendering engine.
    authentication_details = {
        "cas_enabled": cas_enabled,
        "cas_login_caption": app.config["CAS_LOGIN_CAPTION"],
        "cas_login_heading": app.config["CAS_LOGIN_HEADING"],
        "oauth_enabled": oauth_enabled,
        "google_login_caption": app.config["GOOGLE_LOGIN_CAPTION"],
        "google_login_heading": app.config["GOOGLE_LOGIN_HEADING"]
    }

    # If the user's input isn't immediately incorrect (validate_on_submit() will
    # not check if the email and password combo is valid, only that it could be
    # valid)
    if form.validate_on_submit():
        # Find the user with the given email
        try:
            user = FlaskUser(User.objects.get(email = form.email.data))
        except User.DoesNotExist:
            user = None

        if oauth_enabled and user and not user.seal:
            flash("You must use R'Mail to login.", category = "error")

            logger.info(
                "User %s has tried to log in via internal auth but their "
                "account does not have a seal.", user.email
            )

            return render_template(
                "login.html", form = form, **authentication_details
            )

        # Check if the entered password is correct
        if not user or \
                not check_seal(form.password.data, deserialize_seal(str(user.seal))):
            flash("Incorrect email or password.", category = "error")

            logger.info(
                "User %s has entered an incorrect email/password pair during "
                "internal auth.", form.email.data
            )
        else:
            login_user(user)

            logger.info(
                "User %s has succesfully logged in via internal auth.",
                user.email
            )

            return redirect(form.redirect_target or url_for("browse_assignments"))
    elif oauth_enabled and request.args.get("type") == "google":
        # Login using Google OAuth2
        # Step 1 of two-factor authentication: redirect to AUTH url
        auth_uri = flow.step1_get_authorize_url()
        return redirect(auth_uri)
    elif cas_enabled and request.args.get("type") == "cas":
        # Login using CAS
        # Step 1 of CAS dance: redirect to authentication url
        auth_uri = cas_server.login(cas_service)
        return redirect(auth_uri)
    elif cas_enabled and request.args.get("ticket") is not None:
        # Since CAS Authentication doesn't support redirect_uri arguments,
        # the ticket will be sent the login function so let's handle it here.
        cas_validate(request.args.get("ticket"))

    return render_template(
        "login.html",
        form = form,
        **authentication_details
    )