From 7dc76a674e386d9e0a45c076149044362a34bed2 Mon Sep 17 00:00:00 2001 From: darius Date: Thu, 4 Jul 2024 12:32:48 +0200 Subject: [PATCH] Docs update --- api/docs/openAPI/go.mod | 5 +- api/docs/openAPI/go.sum | 2 + api/docs/openAPI/openApi.go | 14 +++--- api/docs/openAPI/openApiGenericEndpoints.go | 20 ++++++++ api/docs/openAPI/openApiModels.go | 9 ++++ api/docs/openAPI/openApiProjectEndpoints.go | 52 +++++++++++++++++++++ api/docs/openAPI/openApiUserEndpoints.go | 39 ++++++++++++++++ api/handlers/projectHandler.go | 2 +- api/handlers/userHandler.go | 2 + api/types/userTypes.go | 5 ++ database/ent/schema/user.go | 3 +- database/ent/user.go | 5 +- 12 files changed, 144 insertions(+), 14 deletions(-) create mode 100644 api/docs/openAPI/openApiGenericEndpoints.go create mode 100644 api/docs/openAPI/openApiModels.go create mode 100644 api/docs/openAPI/openApiProjectEndpoints.go create mode 100644 api/docs/openAPI/openApiUserEndpoints.go diff --git a/api/docs/openAPI/go.mod b/api/docs/openAPI/go.mod index 5c33d18..5a71a9b 100644 --- a/api/docs/openAPI/go.mod +++ b/api/docs/openAPI/go.mod @@ -2,7 +2,10 @@ module openAPI go 1.22 -require github.com/a-h/rest v0.0.0-20240504113546-6729b3328f85 +require ( + github.com/a-h/respond v0.0.2 + github.com/a-h/rest v0.0.0-20240504113546-6729b3328f85 +) require ( github.com/getkin/kin-openapi v0.124.0 // indirect diff --git a/api/docs/openAPI/go.sum b/api/docs/openAPI/go.sum index b571f5f..7e4dda1 100644 --- a/api/docs/openAPI/go.sum +++ b/api/docs/openAPI/go.sum @@ -1,3 +1,5 @@ +github.com/a-h/respond v0.0.2 h1:mhBwB2XuM+34gfIFs9LuXGfCCbu00rvaCWpTVNHvkPU= +github.com/a-h/respond v0.0.2/go.mod h1:k9UvuVDWmHAb91OsdrqG0xFv7X+HelBpfMJIn9xMYWM= github.com/a-h/rest v0.0.0-20240504113546-6729b3328f85 h1:Lj+OmK3+dKMuR8OdlnUeIrgdt8JkcNlA9isS2Aey5Mg= github.com/a-h/rest v0.0.0-20240504113546-6729b3328f85/go.mod h1:5wH1imbpKnMjll8xpGRdg0Sb0HwH7nYiM5VPm0Zl5Bw= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= diff --git a/api/docs/openAPI/openApi.go b/api/docs/openAPI/openApi.go index 5e563d6..4d65985 100644 --- a/api/docs/openAPI/openApi.go +++ b/api/docs/openAPI/openApi.go @@ -4,7 +4,6 @@ import ( "encoding/json" "github.com/a-h/rest" "log" - "net/http" "os" ) @@ -15,13 +14,12 @@ func main() { api = rest.NewAPI("portfolio") api.StripPkgPaths = []string{"github.com/a-h/rest/example", "github.com/a-h/respond"} - api.Get("/nfc/{uid}"). - HasPathParameter("uid", rest.PathParam{ - Description: "id of the user", - Regexp: `\d+`, - }). - HasDescription("Get nfc data by uid."). - HasResponseModel(http.StatusOK, rest.ModelOf[string]()) + // register models + RegisterModels() + // register endpoints + RegisterGenericEndpoints() + RegisterUserEndpoints() + RegisterProjectEndpoints() // Create the specification. spec, err := api.Spec() diff --git a/api/docs/openAPI/openApiGenericEndpoints.go b/api/docs/openAPI/openApiGenericEndpoints.go new file mode 100644 index 0000000..40dcbf8 --- /dev/null +++ b/api/docs/openAPI/openApiGenericEndpoints.go @@ -0,0 +1,20 @@ +package main + +import ( + "github.com/a-h/respond" + "github.com/a-h/rest" + "net/http" +) + +func RegisterGenericEndpoints() { + + api.Get("/check"). + HasDescription("check for user jwt cookie"). + HasResponseModel(http.StatusOK, rest.ModelOf[string]()). + HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()) + + api.Get("/htmx/canEdit"). + HasDescription("check if user is allowed to edit"). + HasResponseModel(http.StatusOK, rest.ModelOf[string]()) +} diff --git a/api/docs/openAPI/openApiModels.go b/api/docs/openAPI/openApiModels.go new file mode 100644 index 0000000..7eae57c --- /dev/null +++ b/api/docs/openAPI/openApiModels.go @@ -0,0 +1,9 @@ +package main + +// ############## MUST DO ######################## +// local copy of types to fix unintended behaviour +// ############################################### + +func RegisterModels() { + +} diff --git a/api/docs/openAPI/openApiProjectEndpoints.go b/api/docs/openAPI/openApiProjectEndpoints.go new file mode 100644 index 0000000..c6047be --- /dev/null +++ b/api/docs/openAPI/openApiProjectEndpoints.go @@ -0,0 +1,52 @@ +package main + +import ( + "github.com/a-h/respond" + "github.com/a-h/rest" + "net/http" + "portfolio/database/ent" +) + +func RegisterProjectEndpoints() { + api.Post("/project"). + HasDescription("Create project"). + HasResponseModel(http.StatusOK, rest.ModelOf[string]()). + HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnauthorized, rest.ModelOf[string]()) + + api.Patch("/project/{id}"). + HasPathParameter("id", rest.PathParam{ + Description: "id of the project", + Regexp: `\d+`, + }). + HasDescription("Update project by id"). + HasRequestModel(rest.ModelOf[ent.Project]()). + HasResponseModel(http.StatusOK, rest.ModelOf[string]()). + HasResponseModel(http.StatusBadRequest, rest.ModelOf[string]()). + HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnauthorized, rest.ModelOf[string]()) + + api.Patch("/projects"). + HasDescription("Update projects WIP"). + HasResponseModel(http.StatusOK, rest.ModelOf[[]ent.Project]()). + HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnauthorized, rest.ModelOf[string]()) + + api.Get("/project/{id}"). + HasPathParameter("id", rest.PathParam{ + Description: "id of the project", + Regexp: `\d+`, + }). + HasDescription("Get project by id"). + HasResponseModel(http.StatusOK, rest.ModelOf[ent.Project]()). + HasResponseModel(http.StatusBadRequest, rest.ModelOf[string]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()) + + api.Get("/projects"). + HasDescription("Get projects"). + HasResponseModel(http.StatusOK, rest.ModelOf[[]ent.Project]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()) +} diff --git a/api/docs/openAPI/openApiUserEndpoints.go b/api/docs/openAPI/openApiUserEndpoints.go new file mode 100644 index 0000000..8698754 --- /dev/null +++ b/api/docs/openAPI/openApiUserEndpoints.go @@ -0,0 +1,39 @@ +package main + +import ( + "github.com/a-h/respond" + "github.com/a-h/rest" + "net/http" + "portfolio/api/types" + "portfolio/database/ent" +) + +func RegisterUserEndpoints() { + api.Get("/user/{uid}"). + HasPathParameter("id", rest.PathParam{ + Description: "id of the user", + Regexp: `\d+`, + }). + HasDescription("Get user by uid."). + HasResponseModel(http.StatusOK, rest.ModelOf[ent.User]()). + HasResponseModel(http.StatusBadRequest, rest.ModelOf[string]()). + HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()) + + api.Post("/register"). + HasDescription("Register."). + HasRequestModel(rest.ModelOf[ent.User]()). + HasResponseModel(http.StatusCreated, rest.ModelOf[string]()). + HasResponseModel(http.StatusBadRequest, rest.ModelOf[string]()). + HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()) + + api.Post("/login"). + HasDescription("Login."). + HasRequestModel(rest.ModelOf[types.LoginUser]()). + HasResponseModel(http.StatusOK, rest.ModelOf[string]()). + HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()). + HasResponseModel(http.StatusUnauthorized, rest.ModelOf[string]()) + +} diff --git a/api/handlers/projectHandler.go b/api/handlers/projectHandler.go index 1114350..aff27f0 100644 --- a/api/handlers/projectHandler.go +++ b/api/handlers/projectHandler.go @@ -35,7 +35,7 @@ func CreateProjectHandler(w http.ResponseWriter, r *http.Request) { } func UpdateProjectHandler(w http.ResponseWriter, r *http.Request) { - //todo htmx check + _, _, err := jwt.VerifyUser(r) if err != nil { UnauthorizedHandler(w) diff --git a/api/handlers/userHandler.go b/api/handlers/userHandler.go index 1c1d060..0beb8f0 100644 --- a/api/handlers/userHandler.go +++ b/api/handlers/userHandler.go @@ -57,6 +57,7 @@ func GetUserHandler(w http.ResponseWriter, r *http.Request) { User, err := query.GetUser(context.Background(), userID) if err != nil { + UnprocessableEntityHandler(w, err) return } @@ -64,6 +65,7 @@ func GetUserHandler(w http.ResponseWriter, r *http.Request) { err = json.NewEncoder(w).Encode(User) if err != nil { + InternalServerErrorHandler(w, err) return } } diff --git a/api/types/userTypes.go b/api/types/userTypes.go index 7a0066b..cfcae0a 100644 --- a/api/types/userTypes.go +++ b/api/types/userTypes.go @@ -3,3 +3,8 @@ package types type Username struct { Name string } + +type LoginUser struct { + Email string + Password string +} diff --git a/database/ent/schema/user.go b/database/ent/schema/user.go index c602ec6..fb01432 100644 --- a/database/ent/schema/user.go +++ b/database/ent/schema/user.go @@ -18,7 +18,8 @@ func (User) Fields() []ent.Field { Unique(), field.String("email"). Unique(), - field.String("password"), + field.String("password"). + Sensitive(), field.Enum("role"). Values("owner", "admin", "user", "visitor"), } diff --git a/database/ent/user.go b/database/ent/user.go index c57b43b..dbd22a9 100644 --- a/database/ent/user.go +++ b/database/ent/user.go @@ -21,7 +21,7 @@ type User struct { // Email holds the value of the "email" field. Email string `json:"email,omitempty"` // Password holds the value of the "password" field. - Password string `json:"password,omitempty"` + Password string `json:"-"` // Role holds the value of the "role" field. Role user.Role `json:"role,omitempty"` // Edges holds the relations/edges for other nodes in the graph. @@ -165,8 +165,7 @@ func (u *User) String() string { builder.WriteString("email=") builder.WriteString(u.Email) builder.WriteString(", ") - builder.WriteString("password=") - builder.WriteString(u.Password) + builder.WriteString("password=") builder.WriteString(", ") builder.WriteString("role=") builder.WriteString(fmt.Sprintf("%v", u.Role))