package apiservices import ( "encoding/json" "net/http" "gitea.local/admin/hspguard/internal/config" "gitea.local/admin/hspguard/internal/repository" "gitea.local/admin/hspguard/internal/util" "gitea.local/admin/hspguard/internal/web" "github.com/go-chi/chi/v5" "github.com/google/uuid" ) type ApiServicesHandler struct { repo *repository.Queries cfg *config.AppConfig } func New(repo *repository.Queries, cfg *config.AppConfig) *ApiServicesHandler { return &ApiServicesHandler{ repo, cfg, } } func (h *ApiServicesHandler) RegisterRoutes(router chi.Router) { router.Post("/api-services/create", h.Add) } type AddServiceRequest struct { Name string `json:"name"` RedirectUris []string `json:"redirect_uris"` Scopes []string `json:"scopes"` GrantTypes []string `json:"grant_types"` } func (h *ApiServicesHandler) Add(w http.ResponseWriter, r *http.Request) { userId, ok := util.GetRequestUserId(r.Context()) if !ok { web.Error(w, "failed to get user id from auth session", http.StatusInternalServerError) return } user, err := h.repo.FindUserId(r.Context(), uuid.MustParse(userId)) if err != nil { web.Error(w, "user with provided id does not exist", http.StatusUnauthorized) return } if !user.IsAdmin { web.Error(w, "you cannot create api services", http.StatusForbidden) return } var req AddServiceRequest decoder := json.NewDecoder(r.Body) if err := decoder.Decode(&req); err != nil { web.Error(w, "failed to parse request body", http.StatusBadRequest) return } if req.Name == "" { web.Error(w, "name is required for an api service", http.StatusBadRequest) return } clientId, err := util.GenerateClientID() if err != nil { web.Error(w, "failed to generate client id", http.StatusInternalServerError) return } clientSecret, err := util.GenerateClientSecret() if err != nil { web.Error(w, "failed to generate client secret", http.StatusInternalServerError) return } hashSecret, err := util.HashPassword(clientSecret) if err != nil { web.Error(w, "failed to create client secret", http.StatusInternalServerError) return } service, err := h.repo.CreateApiService(r.Context(), repository.CreateApiServiceParams{ ClientID: clientId, ClientSecret: hashSecret, Name: req.Name, RedirectUris: req.RedirectUris, Scopes: req.Scopes, GrantTypes: req.GrantTypes, }) if err != nil { web.Error(w, "failed to create new api service", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json; charset=utf-8") service.ClientSecret = clientSecret encoder := json.NewEncoder(w) if err := encoder.Encode(service); err != nil { web.Error(w, "failed to encode response", http.StatusInternalServerError) } }