From 3f73542c6430b71ffbb468b9a1ae8a71ad8b8fb3 Mon Sep 17 00:00:00 2001 From: darius Date: Mon, 24 Jun 2024 15:23:38 +0200 Subject: [PATCH] Project Add, Update, Get, Get many added --- api/apiRoutes.go | 10 +++- api/handlers/errorHandlers.go | 9 +++ api/handlers/projectHandler.go | 104 +++++++++++++++++++++++++++++++++ api/handlers/userHandler.go | 4 +- api/service/jwt/verify.go | 13 +++++ database/ent/migrate/schema.go | 6 +- database/ent/user/user.go | 3 +- 7 files changed, 141 insertions(+), 8 deletions(-) diff --git a/api/apiRoutes.go b/api/apiRoutes.go index f528da7..561ca67 100644 --- a/api/apiRoutes.go +++ b/api/apiRoutes.go @@ -15,11 +15,17 @@ func ApiRoutes() *http.ServeMux { mux.HandleFunc("GET /check", handlers.CheckRoleHandler) //user - mux.HandleFunc("GET /user/{id}", handlers.GetUser) + mux.HandleFunc("GET /user/{id}", handlers.GetUserHandler) //auth mux.HandleFunc("POST /login", handlers.Login) - mux.HandleFunc("POST /register", handlers.CreateUser) + mux.HandleFunc("POST /register", handlers.CreateUserHandler) + + //Project + mux.HandleFunc("POST /project", handlers.CreateProjectHandler) + mux.HandleFunc("PATCH /project/{id}", handlers.UpdateProjectHandler) + mux.HandleFunc("GET /project/{id}", handlers.GetProjectHandler) + mux.HandleFunc("GET /projects", handlers.GetProjectsHandler) return mux } diff --git a/api/handlers/errorHandlers.go b/api/handlers/errorHandlers.go index 0e982a9..0ad00dd 100644 --- a/api/handlers/errorHandlers.go +++ b/api/handlers/errorHandlers.go @@ -44,3 +44,12 @@ func UnauthorizedHandler(w http.ResponseWriter) { } return } + +func NotImplementedHandler(w http.ResponseWriter) { + w.WriteHeader(http.StatusNotImplemented) //set http status + _, err := w.Write([]byte("WORK IN PROGRESS")) + if err != nil { + return + } + return +} diff --git a/api/handlers/projectHandler.go b/api/handlers/projectHandler.go index 5ac8282..4500d3f 100644 --- a/api/handlers/projectHandler.go +++ b/api/handlers/projectHandler.go @@ -1 +1,105 @@ package handlers + +import ( + "context" + "encoding/json" + "net/http" + "portfolio/api/service/jwt" + "portfolio/database/ent" + "portfolio/database/query" + "strconv" +) + +func CreateProjectHandler(w http.ResponseWriter, r *http.Request) { + + id, _, err := jwt.VerifyUser(r) + if err != nil { + UnauthorizedHandler(w) + return + } + + var p *ent.Project + + err = json.NewDecoder(r.Body).Decode(&p) + if err != nil { + InternalServerErrorHandler(w, err) + return + } + + err = query.CreateProject(context.Background(), *p, id) + if err != nil { + UnprocessableEntityHandler(w, err) + return + } +} + +func UpdateProjectHandler(w http.ResponseWriter, r *http.Request) { + + _, _, err := jwt.VerifyUser(r) + if err != nil { + UnauthorizedHandler(w) + return + } + + var p *ent.Project + + projectID, err := strconv.Atoi(r.PathValue("id")) + if err != nil { + BadRequestHandler(w) + } + + p, err = query.GetFullProject(context.Background(), projectID) + if err != nil { + UnprocessableEntityHandler(w, err) + return + } + + err = json.NewDecoder(r.Body).Decode(&p) + if err != nil { + InternalServerErrorHandler(w, err) + return + } + + err = query.UpdateProject(context.Background(), *p, projectID) + if err != nil { + UnprocessableEntityHandler(w, err) + return + } +} + +func GetProjectHandler(w http.ResponseWriter, r *http.Request) { + + projectID, err := strconv.Atoi(r.PathValue("id")) + if err != nil { + BadRequestHandler(w) + } + + p, err := query.GetProject(context.Background(), projectID) + if err != nil { + UnprocessableEntityHandler(w, err) + return + } + + w.Header().Set("Content-Type", "application/json") + + err = json.NewEncoder(w).Encode(p) + if err != nil { + return + } +} + +func GetProjectsHandler(w http.ResponseWriter, r *http.Request) { + + p, err := query.GetProjects(context.Background()) + if err != nil { + UnprocessableEntityHandler(w, err) + return + } + + w.Header().Set("Content-Type", "application/json") + + err = json.NewEncoder(w).Encode(p) + if err != nil { + return + } +} diff --git a/api/handlers/userHandler.go b/api/handlers/userHandler.go index 100ae5d..1c1d060 100644 --- a/api/handlers/userHandler.go +++ b/api/handlers/userHandler.go @@ -12,7 +12,7 @@ import ( "strconv" ) -func CreateUser(w http.ResponseWriter, r *http.Request) { +func CreateUserHandler(w http.ResponseWriter, r *http.Request) { var u *ent.User @@ -48,7 +48,7 @@ func CreateUser(w http.ResponseWriter, r *http.Request) { } -func GetUser(w http.ResponseWriter, r *http.Request) { +func GetUserHandler(w http.ResponseWriter, r *http.Request) { userID, err := strconv.Atoi(r.PathValue("id")) if err != nil { diff --git a/api/service/jwt/verify.go b/api/service/jwt/verify.go index 8e1c365..a121f51 100644 --- a/api/service/jwt/verify.go +++ b/api/service/jwt/verify.go @@ -2,11 +2,24 @@ package jwt import ( _ "context" + "fmt" "github.com/golang-jwt/jwt/v5" + "net/http" "os" "strconv" ) +func VerifyUser(r *http.Request) (int, string, error) { + bearerToken := r.Header.Get("Authorization") + jwtToken := "" + if len(bearerToken) > 7 { + jwtToken = bearerToken[len("Bearer "):] + } else { + return 0, "", fmt.Errorf("token empty") + } + return VerifyJWT(jwtToken) +} + // VerifyJWT verify JWT token and returns user object func VerifyJWT(authToken string) (int, string, error) { //get jwt secret from environment diff --git a/database/ent/migrate/schema.go b/database/ent/migrate/schema.go index d9bc151..8fb697a 100644 --- a/database/ent/migrate/schema.go +++ b/database/ent/migrate/schema.go @@ -26,7 +26,7 @@ var ( // TeamsColumns holds the columns for the "teams" table. TeamsColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "name", Type: field.TypeString}, + {Name: "name", Type: field.TypeString, Unique: true}, } // TeamsTable holds the schema information for the "teams" table. TeamsTable = &schema.Table{ @@ -38,9 +38,9 @@ var ( UsersColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, {Name: "name", Type: field.TypeString, Unique: true}, - {Name: "email", Type: field.TypeString}, + {Name: "email", Type: field.TypeString, Unique: true}, {Name: "password", Type: field.TypeString}, - {Name: "role", Type: field.TypeEnum, Enums: []string{"admin", "user", "visitor"}}, + {Name: "role", Type: field.TypeEnum, Enums: []string{"owner", "admin", "user", "visitor"}}, } // UsersTable holds the schema information for the "users" table. UsersTable = &schema.Table{ diff --git a/database/ent/user/user.go b/database/ent/user/user.go index 13149f9..3bd6b62 100644 --- a/database/ent/user/user.go +++ b/database/ent/user/user.go @@ -73,6 +73,7 @@ type Role string // Role values. const ( + RoleOwner Role = "owner" RoleAdmin Role = "admin" RoleUser Role = "user" RoleVisitor Role = "visitor" @@ -85,7 +86,7 @@ func (r Role) String() string { // RoleValidator is a validator for the "role" field enum values. It is called by the builders before save. func RoleValidator(r Role) error { switch r { - case RoleAdmin, RoleUser, RoleVisitor: + case RoleOwner, RoleAdmin, RoleUser, RoleVisitor: return nil default: return fmt.Errorf("user: invalid enum value for role field: %q", r)