Ejemplo n.º 1
0
def create():
    """Displays the view for creating a new snippet. Requires a logged in user.

    User will enter a title and body for the snippet. Title is reqired. The
    values are then stored in the database and associated with the logged in user.
    """

    if request.method == "POST":
        title = request.form.get("title", None)
        body = request.form.get("body", None)
        error = None

        if not title:
            error = "Title is required."

        if error is not None:
            flash(error)
        else:
            db = get_db()
            db.run_query(
                "INSERT INTO snippet (title, body, author_id)" +
                " VALUES (%s, %s, %s)", (title, body, g.user["id"]))
            return redirect(url_for("snippets.index"))

    return render_template("snippets/create.html")
 def test__get_db(self):
     fresh_db = None
     with captured_output():
         with self.app_context:
             fresh_db = psql_db.get_db()
             fresh_db.load_schema()
     self.assertIsNotNone(self.db)
Ejemplo n.º 3
0
def edit(id):
    """
    Displays the entirety of a snippet for the end user to edit. Requires a logged
    in user

    Args:
        id (int): database id number for the snippet
    """
    snippet = get_snippet(id)

    if request.method == "POST":
        title = request.form.get("title", None)
        body = request.form.get("body", None)
        error = None

        if not title:
            error = "Title is required."

        if error is not None:
            flash(error)
        else:
            db = get_db()
            db.run_query(
                "UPDATE snippet SET title = %s, body = %s" + " WHERE id = %s",
                (title, body, id))
            return redirect(url_for("snippets.index"))

    return render_template("snippets/edit.html", snippet=snippet)
    def test__close_db(self):
        # the close_db method interacts with Flask's g object, which lives
        # within the request_context rather than the app_context
        with captured_output():
            with self.app.test_request_context() as trc:
                trc.g.db = psql_db.get_db()
                trc.g.db.open_connection()
                psql_db.close_db()

        self.assertNotEqual(self.db.conn.closed, 0)
Ejemplo n.º 5
0
def index():
    """Queries database for all snippets, which are passed to index.html and displayed"""

    db = get_db()
    snippets = db.run_query(
        "SELECT s.id, title, body, created, author_id, username"
        " FROM snippet s JOIN users u ON s.author_id = u.id"
        " ORDER BY created DESC")
    if not snippets:
        snippets = []
    return render_template("snippets/index.html", snippets=snippets)
Ejemplo n.º 6
0
def delete(id):
    """
    Deletes a snippet from the database. Requires a logged in user

    Args:
        id (int): database id number for the snippet
    """
    # First query db to make sure snippet exists. get_snippet aborts unless a snippet is found
    get_snippet(id)
    db = get_db()
    db.run_query("DELETE FROM snippet WHERE id = %s", (id, ))
    return redirect(url_for("snippets.index"))
Ejemplo n.º 7
0
    def setUp(self):
        self.app = create_app(testing="instance.config.TestConfig")

        # create a test client
        self.client = self.app.test_client()
        self.app.testing = True

        self.app_context = self.app.app_context()
        # psql_db.init_app(self.app)
        with captured_output():
            with self.app_context:
                self.db = psql_db.get_db()
                self.db.load_schema()
def login():
    """
    Checks user credentials from the login form. Takes the username and
    password from the login form, and queries against the DB. If a valid
    user is found, verifies that the password hash matches the expected value.

    If the inputs are valid, query the database for the associated
    user_id and store the information in g.user. Also set the session's
    user_id to the id of the user that just logged in.

    If user_id in the session is `None`, g.user is set to None
    """
    if request.method == "POST":
        username = request.form.get("username", None)
        password = request.form.get("password", None)
        db = get_db()
        error = None
        # Query the database for a user and return all columns
        # User is unique (primary key), so a single row is returned
        user = db.run_query("SELECT * FROM users WHERE username = %s",
                            (username, ))

        if not user:
            error = "Incorrect username."
        elif len(user) > 1:
            # Should never happen if users are added via register, but catch anyways
            error = "Duplicate users -- login failed"
        else:
            user = user[0]
            g.user = user

            # check_password_hash is a flask built-in
            if not check_password_hash(user["password"], password):
                error = "Incorrect password."

        if error is None:
            # session is a dictionary that stores data across requests
            # When validation succeeds, the user's `id` is stored in
            # a new session.
            session.clear()
            session["user_id"] = user["id"]
            return redirect(url_for("index"))

            # Now that the user's `id` is stored in the session,
            # it will be available on subsequent requests.
            # At the beginning of each request, if a user is logged in
            # their information should be loaded and available to views

        flash(error)

    return render_template("users/login.html")
Ejemplo n.º 9
0
def view(id):
    """
    Displays the entirety of a snippet for the end user to view. Also has a
    POST request option, where the user can click an 'edit' button to edit the
    snippet.

    Args:
        id (int): database id number for the snippet
    """
    snippet = get_snippet(id, check_author=False)

    if request.method == "POST":
        db = get_db()
        db.run_query(
            "UPDATE snippet SET title = %s, body = %s" + " WHERE id = %s",
            (snippet["title"], snippet["body"], id))
        return redirect(url_for("snippets.index"))

    return render_template("snippets/view.html", snippet=snippet)
def register():
    """
    Checks user credentials from the registration form. Takes the username and
    password from the form, and queries against the DB. If a user is found,
    returns an error message. Otherwise, adds a new user to the database and stores
    their password hash.

    Redirects to the login form if successful. Otherwise redirects to the registration
    page.
    """
    if request.method == "POST":
        # `request.form` is a special dictionary that maps form
        # keys and their values
        username = request.form.get("username", None)
        password = request.form.get("password", None)
        db = get_db()
        error = None

        if not username:
            error = "Username is required."
        elif not password:
            error = "Password is required."
        elif db.run_query("SELECT id FROM users WHERE username = %s",
                          (username, )) is not None:
            error = f"User {username} is already registered."

        if error is None:
            db.run_query(
                "INSERT INTO users (username, password) VALUES (%s, %s)",
                # Password is hashed for security
                (username, generate_password_hash(password)))
            # `redirect` generates a redirect response to the URL
            return redirect(url_for("users.login"))

        # `flash()` stores messages that can be retrieved when
        # rendering the template (HTML)
        flash(error)

    # `render_template()` renders a template containing the HTML
    return render_template("users/register.html")
Ejemplo n.º 11
0
def get_snippet(id, check_author=True):
    """Queries the database for a specific snippet, based on the snippet id.

    This function is designed as a helper function for the 'view', 'edit', and
    'delete' views defined below. Each of the views will reference a specific snippet
    and the associated snippet id will be fed to this function.

    Throws errors if the snippet doesn't exist or if there are duplicate snippets.
    Also has an argument that governs whether the author id needs to match the id of
    the logged in user.

    Args:
        id (int): database id number for the snippet
        check_author (bool): optional input that govens whether the author id needs to match
            the id of the logged in user before return a snippet

    Returns:
        snippet (RealDictCursor): a snippet from the database
    """
    snippet = get_db().run_query(
        "SELECT s.id, title, body, created, author_id, username" +
        " FROM snippet s JOIN users u ON s.author_id = u.id" +
        " WHERE s.id = %s", (id, ))

    if snippet is None:
        # abort() will raise a special exception that returns a
        # HTTP status code. 404 == 'Not Found'
        abort(404, f"Snippet id {id} doesn't exist.")
    elif len(snippet) > 1:
        # should never happen, but...
        abort(404, f"Duplicate snippets with id {id}.")
    else:
        snippet = snippet[0]

    if check_author and snippet["author_id"] != g.user["id"]:
        abort(403)

    return snippet
def load_logged_in_user():
    """
    Checks user credentials from the session.
    If the inputs are valid, query the database for the associated
    user_id and store the information in g.user.

    If user_id in the session is `None`, g.user is set to None
    """
    user_id = session.get("user_id")

    if user_id is None:
        g.user = None
    else:
        print(f"User ID: {user_id}")
        db = get_db()
        user = db.run_query("SELECT * FROM users WHERE id = %s", (user_id, ))
        print(user)

        if user is None:
            g.user = None
        elif len(user) == 1:
            user = user[0]
            g.user = user