0

I have looked over this code multiple times, looking for misplaced variable names or attempts to hash the wrong thing. I have tested my code multiple times in many ways and I can't get it to fail. The only thing I can think of is that my username and password validation is more strict than the tests created for check50. If that is the error, I can roll back my validation just so I can submit my code (even though adding such validation is one of the personal touches recommended by the assignment itself). If that's not the error, but you see something I'm missing, I am forever grateful for direction.

enter image description here

@app.route("/register", methods=["GET", "POST"])
def register():
    """Register user"""
    # Forget any user_id
    session.clear()
    if request.method == "POST":
        username=request.form.get("username")
        password=request.form.get("password")
        confirmation=request.form.get("confirmation")

        # Ensure username, password and confirmation was submitted
        if not username:
            return apology("must provide username", 400)
        elif not password:
            return apology("must provide password", 400)
        elif not confirmation:
            return apology("must confirm password", 400)

        # Password and Confirmation must match
        if password != confirmation:
            return apology("password and confirmation must match", 400)

        # Source: http://emailregex.com/
        match = re.search(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", username)
        if not match:
            return apology("username must be in the format of a valid email address <callname>@<domain>.<domainExtension>", 400)

        # Validate password to be 8 characters, 1 UPPERCASE, 1 lowercase, 1 number
        match = re.search(r"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])([A-z0-9]+){8,}$", password)
        if not match:
            return apology("password must be at least 8 characters in length, and include at least one uppercase, one lowercase, and one number - no special characters.", 403)

        hashed = generate_password_hash(password)

        result = db.execute("INSERT INTO users (username, hash) VALUES (:username, :hashed)", username=username, hashed=hashed)
        if not result:
            return apology("The username is already taken", 400)

        # Query database for username
        rows = db.execute("SELECT * FROM users WHERE username = :username", username=username)
        if len(rows) != 1 :
            return apology("There was an error processing your request. Please try again.", 503)

        # Remember which user has logged in
        session["user_id"] = rows[0]["id"]

        # establish transaction history
        db.execute("INSERT INTO transactions (type, symbol, price, quantity, user_id) VALUES ('open', '$$$$', :amount, 1, :userid)", amount=float(rows[0]["cash"]), userid=session["user_id"])

        # Redirect user to home page
        return redirect("/")
    else:
        return render_template("register.html")
0

The custom validation looks like the problem, since those are the only tests that would execute that code. It is highly unlikely that the autograder will use username/password in the formats the code requires. Have you tried to roll it back and run check50?

| improve this answer | |
  • Rolling back solves the problem; however, I feel that check50 needs to be updated to handle such modifications, since such modifications are encouraged by the assignment itself. – wlh May 28 '18 at 15:23
  • Fair point. To be pedantic, the user name restriction is not suggested in the assignment. – DinoCoderSaurus May 29 '18 at 11:49
  • Perhaps. Email addresses though are a very common way to ensure unique usernames, something mentioned in the lectures. But I get that it would be nightmarish to test for all possible forms of contrived username and password formats. So it's all good. – wlh May 29 '18 at 12:55
0

To complete this question, upon consultation with DinoCoderSaurus in the comments, I removed validation of username and password using regex for email and password complexity, respectively. To prevent SQL injection, I added a call to re.escape on user entered values.

##### NOTE: ESCAPE USERNAME VALUE TO PREVENT SQL INJECTION ######
escaped = re.escape(username)

    ##### NOTE: I REMOVED VALIDATION THAT WAS BREAKING CHECK50 #####
    # Source: http://emailregex.com/
    # isValid = re.search(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", username)
    # if not isValid:
    #    return apology("username an only include letters, numbers, or _.-+#@", 400)

    # Validate password to be 8 characters, 1 UPPERCASE, 1 lowercase, 1 number
    # isValid = re.search(r"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])([A-z0-9]+){6,}$", password)
    # if not isValid:
    #    return apology("password must be at least 6 characters in length, and include at least one uppercase, one lowercase, and one number - no special characters.", 400)

##### NOTE, HASHING PREVENTS SQL INJECTION, SINCE THE VALUE IS TRANSFORMED ######
# generate hash and insert, if fails, then duplicate username
hashed = generate_password_hash(password)
| improve this answer | |
-1

I'm having the same problem with my check50 and I'm unsure where I'm going wrong here Here is my code:

@app.route("/register", methods=["GET", "POST"])
def register():
"""Register user"""

# Forget any user_id
session.clear()

 # User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
    #TODO
    #Make sure username was submitted
    if not request.form.get("username"):
        return apology("Please provide a username")

    #Make sure password was submitted
    if not request.form.get("password"):
        return apology("Please provide a password")

    #Make sure password is confirmed
    if not request.form.get("confirmation"):
        return apology("Please confirm your password")

    #Make sure password and confirmation match
    #If not matching return apology
    elif request.form.get("password") != request.form.get("confirmation"):
        return apology("Password and Confirmation passwords do not match!")

    #encrypt password
    hash = generate_password_hash(request.form.get("password"))

    # INSERT query database for username, make sure username is unique
    new_user = db.execute("INSERT INTO users (username, hash) VALUES(:username,:hash)",username = request.form.get("username"),hash=hash)
    if not new_user:
        return apology("Username already exists. Please provide a different username.")

    # Remember which user has logged in
    session["user_id"] = new_user

    # Redirect user to home page
    flash('Successfully registered!')
    return redirect("index.html")

# User reached route via GET (as by clicking a link or via redirect)
else:
    return render_template("register.html")
| improve this answer | |
  • It's not best practice to include your own question as an answer to my question above. In my case, I resolved the problem by submitting a version of the program without the constraints that require username to be an email and password to be complex, though such constraints are real-world methods. For your problem, it could be that you are not returning the proper http status code when there is an error on the form. iana.org/assignments/http-status-codes/http-status-codes.xhtml – wlh Aug 26 '18 at 16:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .