예제 #1
0
def reset_password(token):
    """Users can reset their password with a token.
    The token is valid once and for a limited time."""

    data = decode_email_token(token)
    posted_data = request.get_json()

    if data:
        # First try to validate the token
        with db.connect() as session:
            _uuid = data["uuid"] if "uuid" in data else None

            token = (session.query(Token).filter(~Token.blacklisted).filter(
                Token.token_expire > datetime.utcnow()).filter(
                    Token.token == _uuid).first())

            if not token:
                return {
                    "success": False,
                    "message": "You already used this link, or it's too old.",
                }

            # See if there's posted data. If so, validate the token
            # it should not be blacklisted or expired.
            if posted_data:
                # Then it should contain a new password, so set the password
                # for the user contained in the token.
                user = session.query(User).get(data["id"])
                pw = posted_data["new_password"]
                if not validate_password(pw):
                    return {
                        "success":
                        False,
                        "message":
                        ("Your password should be eight characters long "
                         "and contain a lowercase, uppercase, number "
                         " and one of these : '#$%&/*+?!-_='")
                    }
                user.hash_password(pw)
                token.blacklisted = True

                return {
                    "success": True,
                    "message": "Cool. Password has been set.",
                    "data": token.get_data()
                }

        # If no posted data, stay on the page, and return
        # json with message to set new password.
        return {
            "success": True,
            "message": "Please fill out a new password.",
        }

    # No bad tokens allowed.
    else:
        return {
            "success": False,
            "message": "Not a valid link to reset password."
        }
예제 #2
0
def forgot_password():
    content = request.get_json(silent=True)

    with db.connect() as session:
        user = (session.query(User).filter_by(
            username=content["username"]).first())

        if user and content["email"] == user.email:

            data = user.get_data()
            data["uuid"] = str(uuid4())

            # Store token in database
            expiry_date = datetime.utcnow() + timedelta(seconds=600)
            token = Token(token=data["uuid"],
                          token_expire=expiry_date,
                          token_type="PW_RESET",
                          blacklisted=False)
            session.add(token)

            # Create and send email
            token = encode_email_token(data)
            url = url_for("reset_password", token=token, _external=True)

            send_forgot_email(url, content["email"])

            return {"succes": True, "message": "Reset request sent."}

        return {"success": False, "message": "Nope. Didn't work! :("}
예제 #3
0
def verify_refresh_auth(value):
    """
    Use basic auth to verify user's refresh token.

    Returns Boolean
    """
    user = None

    # Decode the authorization string
    decoded = base64.b64decode(value.encode("utf-8"))
    # Unpack decoded string
    user_id, token = decoded.decode("utf-8").split(":")

    # Query the user by username
    with db.connect() as session:
        user = session.query(User).get(user_id)

        if user:
            # Verify the refresh token, just like a password,
            # however once verified the refresh token will be
            # set to NULL.
            if user.verify_refresh_token(token):
                session.expunge(user)
                g.user = user
                return True

    return False
예제 #4
0
def register():
    """Register new user."""

    content = request.get_json(silent=True)

    username, password = content["username"], content["password"]
    if ((not (username and password))
            or (("username" == "") or ("password" == ""))):
        return {
            "success": False,
            "message": "You should fill out a username and a password."
        }

    if not validate_password(content["password"]):
        return {
            "success":
            False,
            "message": ("Your password should be eight characters long "
                        "and contain a lowercase, uppercase, number "
                        " and one of these : '#$%&/*+?!-_='")
        }

    with db.connect() as session:
        if session.query(User).filter_by(username=content["username"]).first():
            return {
                "success": False,
                "message": "This username already exists. Somebody beat you."
            }

    pw = content.pop("password")
    user = User(registered_date=datetime.utcnow(), **content)
    user.hash_password(pw)

    send_registration_email(content)

    with db.connect() as session:
        session.add(user)

    return {
        "success": True,
        "message": "Got it, thanks! Now first verify your email!"
    }
    def generate_refresh_token(self, expire_seconds=3600*24):

        token = str(uuid4())

        try:
            with db.connect() as session:
                user = session.query(User).get(self.user_id)
                user.refresh_token_hashed = hashpw(
                    token.encode("utf-8"), gensalt())

                td = timedelta(seconds=expire_seconds)
                user.refresh_token_expire = datetime.utcnow() + td
        except Exception:
            return None

        return token
    def verify_token(token, secret):
        """Verify JWT"""

        try:
            d = jwt.decode(token, secret, algorithms=["HS256"])
        except jwt.ExpiredSignatureError:
            return None
        except jwt.InvalidSignatureError:
            return None
        except jwt.InvalidTokenError:
            return None

        with db.connect() as session:
            user = session.query(User).get(d["id"])
            session.expunge(user)

        return user
예제 #7
0
def verify_basic_auth(value):
    """Use basic auth to authenticate user."""

    user = None

    decoded = base64.b64decode(value.encode("utf-8"))
    username, password = decoded.decode("utf-8").split(":")

    with db.connect() as session:
        user = session.query(User).filter_by(username=username).first()
        if user:
            if user.verify_password(password):
                session.expunge(user)
                g.user = user
                return True

    return False
예제 #8
0
def verify_email(token):
    try:
        data = decode_email_token(token)

        with db.connect() as session:
            q = session.query(User).filter_by(username=data["username"])
            user = q.first()

            if user and user.confirmed:
                return redirect(app.config["STATIC_URL"] + "/auth/confirmed",
                                307)

            elif user and (user.email == data["email"]):
                q.update({
                    "confirmed": True,
                    "confirmed_date": datetime.utcnow()
                })
                return redirect(app.config["STATIC_URL"] + "/auth/confirmed",
                                307)
            else:
                abort(400)
    except Exception:
        abort(400)