Skip to content

Commit

Permalink
feat: add authenticated URL delete endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
logan-bobo committed Jun 12, 2024
1 parent 9c9b972 commit 8014a0d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 23 deletions.
28 changes: 28 additions & 0 deletions collision.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"context"
"database/sql"

"url-short/internal/database"
"url-short/internal/shortener"
)

func hashCollisionDetection(DB *database.Queries, url string, count int, requestContext context.Context) (string, error) {
hashURL := shortener.Hash(url, count)
shortURLHash := shortener.Shorten(hashURL)

_, err := DB.SelectURL(requestContext, shortURLHash)

if err == sql.ErrNoRows {
return shortURLHash, nil
}

if err != nil && err != sql.ErrNoRows {
return "", err
}

count++

return hashCollisionDetection(DB, url, count, requestContext)
}
46 changes: 23 additions & 23 deletions handlers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"context"
"crypto/rand"
"database/sql"
"encoding/hex"
Expand All @@ -15,11 +14,10 @@ import (
"strings"
"time"

"url-short/internal/database"
"url-short/internal/shortener"

"github.com/golang-jwt/jwt/v5"
"golang.org/x/crypto/bcrypt"

"url-short/internal/database"
)

type apiConfig struct {
Expand Down Expand Up @@ -114,25 +112,6 @@ func (apiCfg *apiConfig) postLongURL(w http.ResponseWriter, r *http.Request, use
})
}

func hashCollisionDetection(DB *database.Queries, url string, count int, requestContext context.Context) (string, error) {
hashURL := shortener.Hash(url, count)
shortURLHash := shortener.Shorten(hashURL)

_, err := DB.SelectURL(requestContext, shortURLHash)

if err == sql.ErrNoRows {
return shortURLHash, nil
}

if err != nil && err != sql.ErrNoRows {
return "", err
}

count++

return hashCollisionDetection(DB, url, count, requestContext)
}

func (apiCfg *apiConfig) getShortURL(w http.ResponseWriter, r *http.Request) {
query := r.PathValue("shortUrl")

Expand All @@ -147,6 +126,27 @@ func (apiCfg *apiConfig) getShortURL(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, row.LongUrl, http.StatusMovedPermanently)
}

func (apiCfg *apiConfig) deleteShortURL(w http.ResponseWriter, r * http.Request, user database.User) {
query := r.PathValue("shortUrl")

if query == "" {
respondWithError(w, http.StatusBadRequest, "no short url supplied")
return
}

err := apiCfg.DB.DeleteURL(r.Context(), database.DeleteURLParams{
UserID: user.ID,
ShortUrl: query,
})

if err != nil {
respondWithError(w, http.StatusBadRequest, "could not delete short url")
return
}

w.WriteHeader(http.StatusOK)
}

func (apiCfg *apiConfig) postAPIUsers(w http.ResponseWriter, r *http.Request) {
payload := APIUserRequest{}

Expand Down
16 changes: 16 additions & 0 deletions internal/database/urls.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ func main() {
// url management endpoints
mux.HandleFunc("POST /api/v1/data/shorten", apiCfg.authenticationMiddlewear(apiCfg.postLongURL))
mux.HandleFunc("GET /api/v1/{shortUrl}", apiCfg.getShortURL)
mux.HandleFunc("DELETE /api/v1/{shortUrl}", apiCfg.authenticationMiddlewear(apiCfg.deleteShortURL))


// user management endpoints
mux.HandleFunc("POST /api/v1/users", apiCfg.postAPIUsers)
Expand Down
5 changes: 5 additions & 0 deletions sql/queries/urls.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ RETURNING *;
SELECT *
FROM urls
WHERE short_url = $1;

-- name: DeleteURL :exec
DELETE FROM urls
WHERE user_id = $1 AND
short_url = $2;

0 comments on commit 8014a0d

Please sign in to comment.