Add login endpoint

This commit is contained in:
Torjus Håkestad 2022-01-19 22:25:19 +01:00
parent 88784363a6
commit e1ed7cce66
2 changed files with 85 additions and 5 deletions

46
http.go
View File

@ -13,7 +13,9 @@ import (
) )
type HTTPServer struct { type HTTPServer struct {
store FileStore Files FileStore
Users UserStore
Auth *AuthService
config *ServerConfig config *ServerConfig
Logger *zap.SugaredLogger Logger *zap.SugaredLogger
AccessLogger *zap.SugaredLogger AccessLogger *zap.SugaredLogger
@ -26,7 +28,9 @@ func NewHTTPServer(cfg *ServerConfig) *HTTPServer {
Logger: zap.NewNop().Sugar(), Logger: zap.NewNop().Sugar(),
AccessLogger: zap.NewNop().Sugar(), AccessLogger: zap.NewNop().Sugar(),
} }
srv.store = NewMemoryFileStore() srv.Files = NewMemoryFileStore()
srv.Users = NewMemoryUserStore()
srv.Auth = NewAuthService(srv.Users, []byte("test1235"))
r := chi.NewRouter() r := chi.NewRouter()
r.Use(middleware.RealIP) r.Use(middleware.RealIP)
@ -35,6 +39,7 @@ func NewHTTPServer(cfg *ServerConfig) *HTTPServer {
r.Get("/", srv.HandlerIndex) r.Get("/", srv.HandlerIndex)
r.Post("/api/file", srv.HandlerAPIFilePost) r.Post("/api/file", srv.HandlerAPIFilePost)
r.Get("/api/file/{id}", srv.HandlerAPIFileGet) r.Get("/api/file/{id}", srv.HandlerAPIFileGet)
r.Post("/api/login", srv.HandlerAPILogin)
srv.Handler = r srv.Handler = r
return srv return srv
@ -57,7 +62,7 @@ func (s *HTTPServer) HandlerAPIFilePost(w http.ResponseWriter, r *http.Request)
s.processMultiPartFormUpload(w, r) s.processMultiPartFormUpload(w, r)
return return
} }
err := s.store.Store(f) err := s.Files.Store(f)
if err != nil { if err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
s.Logger.Warnw("Error storing file.", "req_id", reqID, "error", err, "id", f.ID, "remote_addr", r.RemoteAddr) s.Logger.Warnw("Error storing file.", "req_id", reqID, "error", err, "id", f.ID, "remote_addr", r.RemoteAddr)
@ -87,7 +92,7 @@ func (s *HTTPServer) HandlerAPIFileGet(w http.ResponseWriter, r *http.Request) {
return return
} }
f, err := s.store.Get(id) f, err := s.Files.Get(id)
if err != nil { if err != nil {
// TODO: LOG // TODO: LOG
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
@ -126,7 +131,7 @@ func (s *HTTPServer) processMultiPartFormUpload(w http.ResponseWriter, r *http.R
Body: ff, Body: ff,
} }
if err := s.store.Store(f); err != nil { if err := s.Files.Store(f); err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
s.Logger.Warnw("Error storing file.", "req_id", reqID, "error", err, "id", f.ID, "remote_addr", r.RemoteAddr) s.Logger.Warnw("Error storing file.", "req_id", reqID, "error", err, "id", f.ID, "remote_addr", r.RemoteAddr)
return return
@ -143,3 +148,34 @@ func (s *HTTPServer) processMultiPartFormUpload(w http.ResponseWriter, r *http.R
s.Logger.Warnw("Error encoding response to client.", "req_id", reqID, "error", err, "remote_addr", r.RemoteAddr) s.Logger.Warnw("Error encoding response to client.", "req_id", reqID, "error", err, "remote_addr", r.RemoteAddr)
} }
} }
func (s *HTTPServer) HandlerAPILogin(w http.ResponseWriter, r *http.Request) {
reqID := middleware.GetReqID(r.Context())
expectedRequest := struct {
Username string `json:"username"`
Password string `json:"password"`
}{}
decoder := json.NewDecoder(r.Body)
defer r.Body.Close()
if err := decoder.Decode(&expectedRequest); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
token, err := s.Auth.Login(expectedRequest.Username, expectedRequest.Password)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
response := struct {
Token string `json:"token"`
}{
Token: token,
}
encoder := json.NewEncoder(w)
if err := encoder.Encode(&response); err != nil {
s.Logger.Infow("Error encoding json response to client.", "req_id", reqID, "error", err, "remote_addr", r.RemoteAddr)
}
}

View File

@ -96,4 +96,48 @@ func TestHandlers(t *testing.T) {
} }
}) })
}) })
t.Run("HandlerAPILogin", func(t *testing.T) {
// TODO: Add test
username := "admin"
password := "admin"
user := &gpaste.User{Username: username}
if err := user.SetPassword(password); err != nil {
t.Fatalf("Error setting user password: %s", err)
}
if err := hs.Users.Store(user); err != nil {
t.Fatalf("Error storing user: %s", err)
}
requestData := struct {
Username string `json:"username"`
Password string `json:"password"`
}{
Username: username,
Password: password,
}
body := new(bytes.Buffer)
encoder := json.NewEncoder(body)
if err := encoder.Encode(&requestData); err != nil {
t.Fatalf("Error encoding request body: %s", err)
}
rr := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodPost, "/api/login", body)
hs.Handler.ServeHTTP(rr, req)
responseData := struct {
Token string `json:"token"`
}{}
decoder := json.NewDecoder(rr.Body)
if err := decoder.Decode(&responseData); err != nil {
t.Fatalf("Error decoding response: %s", err)
}
if err := hs.Auth.ValidateToken(responseData.Token); err != nil {
t.Fatalf("Unable to validate received token: %s", err)
}
})
} }