diff --git a/main.go b/main.go index 913472a..71ca7af 100644 --- a/main.go +++ b/main.go @@ -26,6 +26,7 @@ func run() error { mux.Handle("GET /", routes.ServeFiles(embedFS, "static")) mux.Handle("POST /api/password", routes.CreatePassword(storage, 12*1024, base64.StdEncoding)) mux.Handle("GET /api/password/{id}", routes.GetPassword(storage, base64.StdEncoding)) + mux.Handle("HEAD /api/password/{id}", routes.HasPassword(storage)) address := os.Getenv("PASSED_ADDRESS") if address == "" { diff --git a/routes/has_password.go b/routes/has_password.go new file mode 100644 index 0000000..25f4579 --- /dev/null +++ b/routes/has_password.go @@ -0,0 +1,24 @@ +package routes + +import ( + "net/http" + + "git.1e99.eu/1e99/passed/storage" +) + +func HasPassword(store storage.Store) http.HandlerFunc { + return func(res http.ResponseWriter, req *http.Request) { + id := req.PathValue("id") + found, err := store.HasPassword(id) + if err != nil { + http.Error(res, "", http.StatusInternalServerError) + return + } + + if found { + res.WriteHeader(http.StatusNoContent) + } else { + res.WriteHeader(http.StatusNotFound) + } + } +} diff --git a/storage/ram.go b/storage/ram.go index 87ba129..e19e68d 100644 --- a/storage/ram.go +++ b/storage/ram.go @@ -60,6 +60,14 @@ func (store *ram) GetPassword(id string) ([]byte, error) { return password.password, nil } +func (store *ram) HasPassword(id string) (bool, error) { + store.lock.Lock() + defer store.lock.Unlock() + + _, found := store.passwords[id] + return found, nil +} + func (store *ram) Close() error { store.close <- true return nil @@ -75,7 +83,6 @@ func (store *ram) clearExpired() error { return nil case <-ticker.C: store.lock.Lock() - defer store.lock.Unlock() time := time.Now() for id, password := range store.passwords { @@ -83,6 +90,8 @@ func (store *ram) clearExpired() error { delete(store.passwords, id) } } + + store.lock.Unlock() } } } diff --git a/storage/storage.go b/storage/storage.go index 3d7dac1..a968ab4 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -21,6 +21,7 @@ type entry struct { type Store interface { CreatePassword(password []byte, expiresAt time.Time) (string, error) GetPassword(id string) ([]byte, error) + HasPassword(id string) (bool, error) Close() error }