feature/users #1
							
								
								
									
										46
									
								
								http.go
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								http.go
									
									
									
									
									
								
							| @@ -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) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								http_test.go
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								http_test.go
									
									
									
									
									
								
							| @@ -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) | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user