refactor and documentation
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"git.oblat.lv/alex/triggerssmith/internal/acl"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/server"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
// @Tags acl/resources
|
||||
// @Produce json
|
||||
// @Success 200 {object} getResourcesResponse
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/resources [get]
|
||||
func (h *aclAdminHandler) getResources(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
@@ -23,10 +24,10 @@ func (h *aclAdminHandler) getResources(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -49,9 +50,9 @@ func (h *aclAdminHandler) getResources(w http.ResponseWriter, r *http.Request) {
|
||||
// @Produce json
|
||||
// @Param resourceId path int true "Resource ID" example(1)
|
||||
// @Success 200 {object} getResourceResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/resources/{resourceId} [get]
|
||||
func (h *aclAdminHandler) getResource(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
@@ -59,7 +60,7 @@ func (h *aclAdminHandler) getResource(w http.ResponseWriter, r *http.Request) {
|
||||
resourceIDStr := chi.URLParam(r, "resourceId")
|
||||
resourceID, err := strconv.Atoi(resourceIDStr)
|
||||
if err != nil || resourceID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-id", "Invalid resource ID", "Resource ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-id", "Invalid resource ID", "Resource ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -67,12 +68,12 @@ func (h *aclAdminHandler) getResource(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
case acl.ErrResourceNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+resourceIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+resourceIDStr, r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -89,16 +90,16 @@ func (h *aclAdminHandler) getResource(w http.ResponseWriter, r *http.Request) {
|
||||
// @Produce json
|
||||
// @Param request body createResourceRequest true "Resource"
|
||||
// @Success 201 {object} createResourceResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 409 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 409 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/resources [post]
|
||||
func (h *aclAdminHandler) createResource(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var req createResourceRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/invalid-request-body", "Invalid request body", "Body is not valid JSON", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/invalid-request-body", "Invalid request body", "Body is not valid JSON", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -108,14 +109,14 @@ func (h *aclAdminHandler) createResource(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
case acl.ErrInvalidResourceKey:
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-key", "Invalid resource key", "Resource key must be non-empty", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-key", "Invalid resource key", "Resource key must be non-empty", r)
|
||||
case acl.ErrResourceAlreadyExists:
|
||||
writeProblem(w, http.StatusConflict, "/errors/acl/resource-already-exists", "Resource already exists", "Resource '"+req.Key+"' already exists", r)
|
||||
server.WriteProblem(w, http.StatusConflict, "/errors/acl/resource-already-exists", "Resource already exists", "Resource '"+req.Key+"' already exists", r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -134,24 +135,24 @@ func (h *aclAdminHandler) createResource(w http.ResponseWriter, r *http.Request)
|
||||
// @Param resourceId path int true "Resource ID" example(1)
|
||||
// @Param request body updateResourceRequest true "Resource"
|
||||
// @Success 200 {object} updateResourceResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 409 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 409 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/resources/{resourceId} [patch]
|
||||
func (h *aclAdminHandler) updateResource(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var req updateResourceRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/invalid-request-body", "Invalid request body", "Body is not valid JSON", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/invalid-request-body", "Invalid request body", "Body is not valid JSON", r)
|
||||
return
|
||||
}
|
||||
|
||||
resourceIDStr := chi.URLParam(r, "resourceId")
|
||||
resourceID, err := strconv.Atoi(resourceIDStr)
|
||||
if err != nil || resourceID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-id", "Invalid resource ID", "Resource ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-id", "Invalid resource ID", "Resource ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -161,16 +162,16 @@ func (h *aclAdminHandler) updateResource(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
case acl.ErrInvalidResourceKey:
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-key", "Invalid resource key", "Resource key must be non-empty", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-key", "Invalid resource key", "Resource key must be non-empty", r)
|
||||
case acl.ErrResourceNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+resourceIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+resourceIDStr, r)
|
||||
case acl.ErrSameResourceKey:
|
||||
writeProblem(w, http.StatusConflict, "/errors/acl/resource-key-already-exists", "Resource key already exists", "Resource key '"+req.Key+"' already exists", r)
|
||||
server.WriteProblem(w, http.StatusConflict, "/errors/acl/resource-key-already-exists", "Resource key already exists", "Resource key '"+req.Key+"' already exists", r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -186,10 +187,10 @@ func (h *aclAdminHandler) updateResource(w http.ResponseWriter, r *http.Request)
|
||||
// @Produce json
|
||||
// @Param resourceId path int true "Resource ID" example(1)
|
||||
// @Success 200
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 409 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 409 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/resources/{resourceId} [delete]
|
||||
func (h *aclAdminHandler) deleteResource(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
@@ -197,7 +198,7 @@ func (h *aclAdminHandler) deleteResource(w http.ResponseWriter, r *http.Request)
|
||||
resourceIDStr := chi.URLParam(r, "resourceId")
|
||||
resourceID, err := strconv.Atoi(resourceIDStr)
|
||||
if err != nil || resourceID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-id", "Invalid resource ID", "Resource ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-id", "Invalid resource ID", "Resource ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -207,14 +208,14 @@ func (h *aclAdminHandler) deleteResource(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "acl service is not initialized", r)
|
||||
case acl.ErrResourceNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+resourceIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+resourceIDStr, r)
|
||||
case acl.ErrResourceInUse:
|
||||
writeProblem(w, http.StatusConflict, "/errors/acl/resource-in-use", "Resource in use", "Resource "+resourceIDStr+" is in use", r)
|
||||
server.WriteProblem(w, http.StatusConflict, "/errors/acl/resource-in-use", "Resource in use", "Resource "+resourceIDStr+" is in use", r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"git.oblat.lv/alex/triggerssmith/internal/acl"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/server"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
// @Tags acl/roles
|
||||
// @Produce json
|
||||
// @Success 200 {array} getRolesResponse
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles [get]
|
||||
func (h *aclAdminHandler) getRoles(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
@@ -22,10 +23,10 @@ func (h *aclAdminHandler) getRoles(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -48,16 +49,16 @@ func (h *aclAdminHandler) getRoles(w http.ResponseWriter, r *http.Request) {
|
||||
// @Produce json
|
||||
// @Param roleId path int true "Role ID" example(1)
|
||||
// @Success 200 {object} getRoleResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles/{roleId} [get]
|
||||
func (h *aclAdminHandler) getRole(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
roleIDStr := chi.URLParam(r, "roleId")
|
||||
roleID, err := strconv.Atoi(roleIDStr)
|
||||
if err != nil || roleID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -65,12 +66,12 @@ func (h *aclAdminHandler) getRole(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -86,16 +87,16 @@ func (h *aclAdminHandler) getRole(w http.ResponseWriter, r *http.Request) {
|
||||
// @Produce json
|
||||
// @Param roleId path int true "Role ID" example(1)
|
||||
// @Success 200 {array} getRoleUsersResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles/{roleId}/users [get]
|
||||
func (h *aclAdminHandler) getRoleUsers(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
roleIDStr := chi.URLParam(r, "roleId")
|
||||
roleID, err := strconv.Atoi(roleIDStr)
|
||||
if err != nil || roleID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -103,17 +104,17 @@ func (h *aclAdminHandler) getRoleUsers(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(role.Users) == 0 {
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-has-no-users", "Role has no users", "Role has no users", r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-has-no-users", "Role has no users", "Role has no users", r)
|
||||
return
|
||||
}
|
||||
var respUsers getRoleUsersResponse
|
||||
@@ -132,33 +133,33 @@ func (h *aclAdminHandler) getRoleUsers(w http.ResponseWriter, r *http.Request) {
|
||||
// @Produce json
|
||||
// @Param roleId path int true "Role ID" example(1)
|
||||
// @Success 200 {array} getRoleResourcesResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles/{roleId}/resources [get]
|
||||
func (h *aclAdminHandler) getRoleResources(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
roleIDStr := chi.URLParam(r, "roleId")
|
||||
roleID, err := strconv.Atoi(roleIDStr)
|
||||
if err != nil || roleID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
role, err := h.a.GetRoleByID(uint(roleID))
|
||||
if err != nil {
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(role.Resources) == 0 {
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-has-no-users", "Role has no users", "Role has no users", r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-has-no-users", "Role has no users", "Role has no users", r)
|
||||
return
|
||||
}
|
||||
var respResources getRoleResourcesResponse
|
||||
@@ -177,16 +178,16 @@ func (h *aclAdminHandler) getRoleResources(w http.ResponseWriter, r *http.Reques
|
||||
// @Produce json
|
||||
// @Param request body createRoleRequest true "Role"
|
||||
// @Success 201 {object} createRoleResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 409 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 409 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles [post]
|
||||
func (h *aclAdminHandler) createRole(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var req createRoleRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/invalid-request-body", "Invalid request body", "Body is not valid JSON", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/invalid-request-body", "Invalid request body", "Body is not valid JSON", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -195,13 +196,13 @@ func (h *aclAdminHandler) createRole(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Error("Failed to create role", "error", err.Error())
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrInvalidRoleName:
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-name", "Invalid role name", "Role name must be non-empty", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-name", "Invalid role name", "Role name must be non-empty", r)
|
||||
case acl.ErrRoleAlreadyExists:
|
||||
writeProblem(w, http.StatusConflict, "/errors/acl/role-already-exists", "Role already exists", "Role '"+req.Name+"' already exists", r)
|
||||
server.WriteProblem(w, http.StatusConflict, "/errors/acl/role-already-exists", "Role already exists", "Role '"+req.Name+"' already exists", r)
|
||||
default:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -220,24 +221,24 @@ func (h *aclAdminHandler) createRole(w http.ResponseWriter, r *http.Request) {
|
||||
// @Param roleId path int true "Role ID" example(1)
|
||||
// @Param request body updateRoleRequest true "Role"
|
||||
// @Success 200 {object} updateRoleResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 409 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 409 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles/{roleId} [patch]
|
||||
func (h *aclAdminHandler) updateRole(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var req updateRoleRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/invalid-request-body", "Invalid request body", "Body is not valid JSON", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/invalid-request-body", "Invalid request body", "Body is not valid JSON", r)
|
||||
return
|
||||
}
|
||||
|
||||
roleIDStr := chi.URLParam(r, "roleId")
|
||||
roleID, err := strconv.Atoi(roleIDStr)
|
||||
if err != nil || roleID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -246,15 +247,15 @@ func (h *aclAdminHandler) updateRole(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Error("Failed to update role", "error", err.Error())
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrInvalidRoleName:
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-name", "Invalid role name", "Role name must be non-empty", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-name", "Invalid role name", "Role name must be non-empty", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
case acl.ErrSameRoleName:
|
||||
writeProblem(w, http.StatusConflict, "/errors/acl/role-name-already-exists", "Role name already exists", "Role '"+req.Name+"' already exists", r)
|
||||
server.WriteProblem(w, http.StatusConflict, "/errors/acl/role-name-already-exists", "Role name already exists", "Role '"+req.Name+"' already exists", r)
|
||||
default:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -270,17 +271,17 @@ func (h *aclAdminHandler) updateRole(w http.ResponseWriter, r *http.Request) {
|
||||
// @Produce json
|
||||
// @Param roleId path int true "Role ID" example(1)
|
||||
// @Success 204
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 409 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 409 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles/{roleId} [delete]
|
||||
func (h *aclAdminHandler) deleteRole(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
roleIDStr := chi.URLParam(r, "roleId")
|
||||
roleID, err := strconv.Atoi(roleIDStr)
|
||||
if err != nil || roleID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -289,13 +290,13 @@ func (h *aclAdminHandler) deleteRole(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Error("Failed to delete role", "error", err.Error())
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
case acl.ErrRoleInUse:
|
||||
writeProblem(w, http.StatusConflict, "/errors/acl/role-in-use", "Role in use", "Role "+roleIDStr+" is assigned to at least one user and cannot be deleted", r)
|
||||
server.WriteProblem(w, http.StatusConflict, "/errors/acl/role-in-use", "Role in use", "Role "+roleIDStr+" is assigned to at least one user and cannot be deleted", r)
|
||||
default:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -309,37 +310,37 @@ func (h *aclAdminHandler) deleteRole(w http.ResponseWriter, r *http.Request) {
|
||||
// @Param roleId path int true "Role ID" example(1)
|
||||
// @Param request body assignResourceToRoleRequest true "Resource"
|
||||
// @Success 201
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 409 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 409 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles/{roleId}/resources [post]
|
||||
func (h *aclAdminHandler) assignResourceToRole(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
roleIDStr := chi.URLParam(r, "roleId")
|
||||
roleID, err := strconv.Atoi(roleIDStr)
|
||||
if err != nil || roleID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
var req assignResourceToRoleRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-request-body", "Invalid request body", "Invalid JSON body", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-request-body", "Invalid request body", "Invalid JSON body", r)
|
||||
return
|
||||
}
|
||||
if err := h.a.AssignResourceToRole(uint(roleID), req.ResourceID); err != nil {
|
||||
slog.Error("Failed to assign resource to role", "error", err.Error())
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
case acl.ErrResourceNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+strconv.Itoa(int(req.ResourceID)), r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+strconv.Itoa(int(req.ResourceID)), r)
|
||||
case acl.ErrResourceAlreadyAssigned:
|
||||
writeProblem(w, http.StatusConflict, "/errors/acl/resource-already-assigned", "Resource already assigned", "Resource with ID "+strconv.Itoa(int(req.ResourceID))+" is already assigned to role with ID "+roleIDStr, r)
|
||||
server.WriteProblem(w, http.StatusConflict, "/errors/acl/resource-already-assigned", "Resource already assigned", "Resource with ID "+strconv.Itoa(int(req.ResourceID))+" is already assigned to role with ID "+roleIDStr, r)
|
||||
default:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -352,37 +353,37 @@ func (h *aclAdminHandler) assignResourceToRole(w http.ResponseWriter, r *http.Re
|
||||
// @Param roleId path int true "Role ID" example(1)
|
||||
// @Param resId path int true "Resource ID" example(1)
|
||||
// @Success 204
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/roles/{roleId}/resources/{resId} [delete]
|
||||
func (h *aclAdminHandler) removeResourceFromRole(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
roleIDStr := chi.URLParam(r, "roleId")
|
||||
roleID, err := strconv.Atoi(roleIDStr)
|
||||
if err != nil || roleID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
resourceIDStr := chi.URLParam(r, "resId")
|
||||
resourceID, err := strconv.Atoi(resourceIDStr)
|
||||
if err != nil || resourceID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-id", "Invalid resource ID", "Resource ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-resource-id", "Invalid resource ID", "Resource ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
if err := h.a.RemoveResourceFromRole(uint(roleID), uint(resourceID)); err != nil {
|
||||
slog.Error("Failed to remove resource from role", "error", err.Error())
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-not-found", "Role not found", "No role with ID "+roleIDStr, r)
|
||||
case acl.ErrResourceNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+strconv.Itoa(int(resourceID)), r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/resource-not-found", "Resource not found", "No resource with ID "+strconv.Itoa(int(resourceID)), r)
|
||||
case acl.ErrRoleResourceNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/role-resource-not-found", "Role resource not found", "No role-resource pair with role ID "+roleIDStr+" and resource ID "+strconv.Itoa(int(resourceID)), r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/role-resource-not-found", "Role resource not found", "No role-resource pair with role ID "+roleIDStr+" and resource ID "+strconv.Itoa(int(resourceID)), r)
|
||||
default:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"git.oblat.lv/alex/triggerssmith/internal/acl"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/server"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
@@ -15,30 +16,30 @@ import (
|
||||
// @Produce json
|
||||
// @Param userId path int true "User ID" example(1)
|
||||
// @Success 200 {object} getUserRolesResponse
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/users/{userId}/roles [get]
|
||||
func (h *aclAdminHandler) getUserRoles(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
userIDStr := chi.URLParam(r, "userId")
|
||||
userID, err := strconv.Atoi(userIDStr)
|
||||
if err != nil {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-user-id", "Invalid user ID", "User ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-user-id", "Invalid user ID", "User ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
roles, err := h.a.GetUserRoles(uint(userID))
|
||||
if err != nil {
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrUserNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/user-not-found", "User not found", "User not found", r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/user-not-found", "User not found", "User not found", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/no-role-found", "No role found", "No role found for user "+strconv.Itoa(userID), r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/no-role-found", "No role found", "No role found for user "+strconv.Itoa(userID), r)
|
||||
default:
|
||||
slog.Error("unexpected server error", "error", err.Error())
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -55,37 +56,37 @@ func (h *aclAdminHandler) getUserRoles(w http.ResponseWriter, r *http.Request) {
|
||||
// @Param userId path int true "User ID" example(1)
|
||||
// @Param body body assignRoleToUserRequest true "Role ID"
|
||||
// @Success 201
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 409 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 409 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/users/{userId}/roles [post]
|
||||
func (h *aclAdminHandler) assignRoleToUser(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
userIDStr := chi.URLParam(r, "userId")
|
||||
userID, err := strconv.Atoi(userIDStr)
|
||||
if err != nil || userID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-user-id", "Invalid user ID", "User ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-user-id", "Invalid user ID", "User ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
var req assignRoleToUserRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-request-body", "Invalid request body", "Invalid JSON body", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-request-body", "Invalid request body", "Invalid JSON body", r)
|
||||
return
|
||||
}
|
||||
if err := h.a.AssignRoleToUser(req.RoleID, uint(userID)); err != nil {
|
||||
slog.Error("Failed to assign role to user", "error", err.Error())
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrUserNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/user-not-found", "User not found", "User not found", r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/user-not-found", "User not found", "User not found", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/no-role-found", "No role found", "No role found for user "+strconv.Itoa(userID), r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/no-role-found", "No role found", "No role found for user "+strconv.Itoa(userID), r)
|
||||
case acl.ErrRoleAlreadyAssigned:
|
||||
writeProblem(w, http.StatusConflict, "/errors/acl/role-already-assigned", "Role already assigned", "Role with ID "+strconv.Itoa(int(req.RoleID))+" is already assigned to user "+strconv.Itoa(userID), r)
|
||||
server.WriteProblem(w, http.StatusConflict, "/errors/acl/role-already-assigned", "Role already assigned", "Role with ID "+strconv.Itoa(int(req.RoleID))+" is already assigned to user "+strconv.Itoa(userID), r)
|
||||
default:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -98,22 +99,22 @@ func (h *aclAdminHandler) assignRoleToUser(w http.ResponseWriter, r *http.Reques
|
||||
// @Param userId path int true "User ID" example(1)
|
||||
// @Param roleId path int true "Role ID" example(1)
|
||||
// @Success 204
|
||||
// @Failure 400 {object} ProblemDetails
|
||||
// @Failure 404 {object} ProblemDetails
|
||||
// @Failure 500 {object} ProblemDetails
|
||||
// @Failure 400 {object} server.ProblemDetails
|
||||
// @Failure 404 {object} server.ProblemDetails
|
||||
// @Failure 500 {object} server.ProblemDetails
|
||||
// @Router /api/acl/users/{userId}/roles/{roleId} [delete]
|
||||
func (h *aclAdminHandler) removeRoleFromUser(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
userIDStr := chi.URLParam(r, "userId")
|
||||
userID, err := strconv.Atoi(userIDStr)
|
||||
if err != nil || userID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-user-id", "Invalid user ID", "User ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-user-id", "Invalid user ID", "User ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
roleIDStr := chi.URLParam(r, "roleId")
|
||||
roleID, err := strconv.Atoi(roleIDStr)
|
||||
if err != nil || roleID < 0 {
|
||||
writeProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
server.WriteProblem(w, http.StatusBadRequest, "/errors/acl/invalid-role-id", "Invalid role ID", "Role ID must be positive integer", r)
|
||||
return
|
||||
}
|
||||
err = h.a.RemoveRoleFromUser(uint(roleID), uint(userID))
|
||||
@@ -121,15 +122,15 @@ func (h *aclAdminHandler) removeRoleFromUser(w http.ResponseWriter, r *http.Requ
|
||||
slog.Error("Failed to remove role from user", "error", err.Error())
|
||||
switch err {
|
||||
case acl.ErrNotInitialized:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "ACL service is not initialized", r)
|
||||
case acl.ErrUserNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/user-not-found", "User not found", "User not found", r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/user-not-found", "User not found", "User not found", r)
|
||||
case acl.ErrRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/no-role-found", "No role found", "No role found for user "+strconv.Itoa(userID), r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/no-role-found", "No role found", "No role found for user "+strconv.Itoa(userID), r)
|
||||
case acl.ErrUserRoleNotFound:
|
||||
writeProblem(w, http.StatusNotFound, "/errors/acl/user-role-not-found", "User role not found", "User "+strconv.Itoa(userID)+" does not have role "+strconv.Itoa(roleID), r)
|
||||
server.WriteProblem(w, http.StatusNotFound, "/errors/acl/user-role-not-found", "User role not found", "User "+strconv.Itoa(userID)+" does not have role "+strconv.Itoa(roleID), r)
|
||||
default:
|
||||
writeProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
server.WriteProblem(w, http.StatusInternalServerError, "/errors/internal-server-error", "Internal Server Error", "unexpected error", r)
|
||||
}
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
|
||||
Reference in New Issue
Block a user