diff --git a/deployments/docker-compose.prod.yml b/deployments/docker-compose.prod.yml index d7be8ee..74848a0 100644 --- a/deployments/docker-compose.prod.yml +++ b/deployments/docker-compose.prod.yml @@ -22,6 +22,7 @@ services: app: image: "${SERVER_IMAGE:-ghcr.io/wwi21seb-projekt/server-alpha:main}" # It's possible to specify the image to use in the environment, default is the latest image from the github container registry + user: ${UID}:${GID} restart: unless-stopped # Restart the container unless it was stopped by the user depends_on: - db @@ -34,18 +35,19 @@ services: - DB_NAME=${DB_NAME} - DB_USER=${DB_USER} - DB_PASS=${DB_PASS} - - JWT_PRIVATE_KEY=${JWT_PRIVATE_KEY} - - JWT_PUBLIC_KEY=${JWT_PUBLIC_KEY} - MAILGUN_API_KEY=${MAILGUN_API_KEY} ports: - "${APP_PORT}:8080" + volumes: + - ${PWD}/private_key.pem:/private_key.pem + - ${PWD}/public_key.pem:/public_key.pem networks: - traefik_proxy - default labels: - "traefik.enable=true" - "traefik.http.routers.alpha.entrypoints=websecure" - - "traefik.http.routers.alpha.rule=Host(`alpha.c930.net`)" + - "traefik.http.routers.alpha.rule=Host(`server-alpha.tech`)" - "traefik.http.routers.alpha.tls=true" - "traefik.http.routers.alpha.tls.certresolver=default" - "traefik.http.routers.alpha.middlewares=secHeaders@file" diff --git a/internal/routing/handlers/user_handler.go b/internal/routing/handlers/user_handler.go index b840873..a25d2d5 100644 --- a/internal/routing/handlers/user_handler.go +++ b/internal/routing/handlers/user_handler.go @@ -522,12 +522,14 @@ func (handler *UserHandler) Subscribe(w http.ResponseWriter, r *http.Request) { var subscriptionId uuid.UUID if err := rows.Scan(&subscriptionId); err != nil { if !errors.Is(err, pgx.ErrNoRows) { - utils.WriteAndLogError(w, schemas.SubscriptionAlreadyExists, http.StatusConflict, err) + utils.WriteAndLogError(w, schemas.DatabaseError, http.StatusInternalServerError, err) return } - utils.WriteAndLogError(w, schemas.DatabaseError, http.StatusInternalServerError, err) - return + } + if subscriptionId != uuid.Nil { + utils.WriteAndLogError(w, schemas.SubscriptionAlreadyExists, http.StatusConflict, errors.New("subscription already exists")) + return } // Subscribe the user @@ -594,8 +596,8 @@ func (handler *UserHandler) Unsubscribe(w http.ResponseWriter, r *http.Request) } // Unsubscribe the user - queryString = "DELETE FROM alpha_schema.subscriptions WHERE subscriber_id = $1 AND subscribee_id = $2" - if _, err := tx.Exec(transactionCtx, queryString, jwtUserId, subscribeeId); err != nil { + queryString = "DELETE FROM alpha_schema.subscriptions WHERE subscription_id = $1" + if _, err := tx.Exec(transactionCtx, queryString, subscriptionId); err != nil { if errors.Is(err, pgx.ErrNoRows) { utils.WriteAndLogError(w, schemas.SubscriptionNotFound, http.StatusNotFound, errors.New("subscription not found")) return diff --git a/internal/routing/router.go b/internal/routing/router.go index 3f34a62..513f687 100644 --- a/internal/routing/router.go +++ b/internal/routing/router.go @@ -74,7 +74,7 @@ func InitRouter(databaseMgr managers.DatabaseMgr, mailMgr managers.MailMgr, jwtM }) // Initialize user routes - r.Route("/api/users", userRouter(&databaseMgr, &jwtMgr, &mailMgr)) + r.Route("/api/users", userRouter(&databaseMgr, jwtMgr, &mailMgr)) // Initialize feed routes r.Route("/api/feed", func(r chi.Router) { @@ -97,16 +97,18 @@ func InitRouter(databaseMgr managers.DatabaseMgr, mailMgr managers.MailMgr, jwtM return r } -func userRouter(databaseMgr *managers.DatabaseMgr, jwtMgr *managers.JWTMgr, mailMgr *managers.MailMgr) func(chi.Router) { +func userRouter(databaseMgr *managers.DatabaseMgr, jwtMgr managers.JWTMgr, mailMgr *managers.MailMgr) func(chi.Router) { return func(r chi.Router) { - userHdl := handlers.NewUserHandler(databaseMgr, jwtMgr, mailMgr) + userHdl := handlers.NewUserHandler(databaseMgr, &jwtMgr, mailMgr) r.Post("/", userHdl.RegisterUser) - r.Put("/", userHdl.ChangeTrivialInformation) - r.Patch("/", userHdl.ChangePassword) + r.With(jwtMgr.JWTMiddleware).Get("/", userHdl.SearchUsers) + r.With(jwtMgr.JWTMiddleware).Put("/", userHdl.ChangeTrivialInformation) + r.With(jwtMgr.JWTMiddleware).Patch("/", userHdl.ChangePassword) r.Post("/login", userHdl.LoginUser) r.Post("/refresh", userHdl.RefreshToken) r.Post("/{username}/activate", userHdl.ActivateUser) r.Delete("/{username}/activate", userHdl.ResendToken) + r.With(jwtMgr.JWTMiddleware).Get("/{username}", userHdl.HandleGetUserRequest) } } diff --git a/internal/routing/router_test.go b/internal/routing/router_test.go index 5014b06..faec61e 100644 --- a/internal/routing/router_test.go +++ b/internal/routing/router_test.go @@ -147,7 +147,7 @@ func TestUserRegistration(t *testing.T) { // Assert that the response status code is 201 and the response body contains the expected values expect := httpexpect.Default(t, server.URL) - request := expect.POST("/api/v1/users").WithJSON(tc.user) + request := expect.POST("/api/users").WithJSON(tc.user) response := request.Expect().Status(tc.status) response.JSON().IsEqual(tc.responseBody) @@ -210,7 +210,7 @@ func TestUserLogin(t *testing.T) { // Assert that the response status code is 200 and the response body contains the expected values expect := httpexpect.Default(t, server.URL) - request := expect.POST("/api/v1/users/login").WithJSON(tc.user) + request := expect.POST("/api/users/login").WithJSON(tc.user) request.Expect().Status(tc.status) if err := poolMock.ExpectationsWereMet(); err != nil { diff --git a/internal/utils/url_keys.go b/internal/utils/url_keys.go index b387751..6909626 100644 --- a/internal/utils/url_keys.go +++ b/internal/utils/url_keys.go @@ -1,7 +1,7 @@ package utils const ( - SubscriptionIdKey = "subscription_id" + SubscriptionIdKey = "subscriptionId" UsernameKey = "username" UsernameParamKey = "username" OffsetParamKey = "offset"