mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 13:29:05 +01:00
Add API endpoints for creating users and jwts
This commit is contained in:
parent
a2f626fb0e
commit
7e468a7b8d
63
api/rest.go
63
api/rest.go
@ -17,6 +17,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ClusterCockpit/cc-backend/auth"
|
"github.com/ClusterCockpit/cc-backend/auth"
|
||||||
|
"github.com/ClusterCockpit/cc-backend/config"
|
||||||
"github.com/ClusterCockpit/cc-backend/graph"
|
"github.com/ClusterCockpit/cc-backend/graph"
|
||||||
"github.com/ClusterCockpit/cc-backend/graph/model"
|
"github.com/ClusterCockpit/cc-backend/graph/model"
|
||||||
"github.com/ClusterCockpit/cc-backend/log"
|
"github.com/ClusterCockpit/cc-backend/log"
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
type RestApi struct {
|
type RestApi struct {
|
||||||
JobRepository *repository.JobRepository
|
JobRepository *repository.JobRepository
|
||||||
Resolver *graph.Resolver
|
Resolver *graph.Resolver
|
||||||
|
Authentication *auth.Authentication
|
||||||
MachineStateDir string
|
MachineStateDir string
|
||||||
OngoingArchivings sync.WaitGroup
|
OngoingArchivings sync.WaitGroup
|
||||||
}
|
}
|
||||||
@ -48,6 +50,12 @@ func (api *RestApi) MountRoutes(r *mux.Router) {
|
|||||||
|
|
||||||
r.HandleFunc("/jobs/metrics/{id}", api.getJobMetrics).Methods(http.MethodGet)
|
r.HandleFunc("/jobs/metrics/{id}", api.getJobMetrics).Methods(http.MethodGet)
|
||||||
|
|
||||||
|
if api.Authentication != nil {
|
||||||
|
r.HandleFunc("/jwt/", api.getJWT).Methods(http.MethodPost)
|
||||||
|
r.HandleFunc("/users/", api.createUser).Methods(http.MethodPost, http.MethodPut)
|
||||||
|
r.HandleFunc("/configuration/", api.updateConfiguration).Methods(http.MethodPost)
|
||||||
|
}
|
||||||
|
|
||||||
if api.MachineStateDir != "" {
|
if api.MachineStateDir != "" {
|
||||||
r.HandleFunc("/machine_state/{cluster}/{host}", api.getMachineState).Methods(http.MethodGet)
|
r.HandleFunc("/machine_state/{cluster}/{host}", api.getMachineState).Methods(http.MethodGet)
|
||||||
r.HandleFunc("/machine_state/{cluster}/{host}", api.putMachineState).Methods(http.MethodPut, http.MethodPost)
|
r.HandleFunc("/machine_state/{cluster}/{host}", api.putMachineState).Methods(http.MethodPut, http.MethodPost)
|
||||||
@ -465,6 +473,61 @@ func (api *RestApi) getJobMetrics(rw http.ResponseWriter, r *http.Request) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *RestApi) getJWT(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
username := r.FormValue("username")
|
||||||
|
me := auth.GetUser(r.Context())
|
||||||
|
if !me.HasRole(auth.RoleAdmin) {
|
||||||
|
if username != me.Username {
|
||||||
|
http.Error(rw, "only admins are allowed to sign JWTs not for themselves", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := api.Authentication.FetchUser(username)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(rw, err.Error(), http.StatusUnprocessableEntity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
jwt, err := api.Authentication.ProvideJWT(user)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(rw, err.Error(), http.StatusUnprocessableEntity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
rw.Write([]byte(jwt))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *RestApi) createUser(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
me := auth.GetUser(r.Context())
|
||||||
|
if !me.HasRole(auth.RoleAdmin) {
|
||||||
|
http.Error(rw, "only admins are allowed to create new users", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
username, password, role := r.FormValue("username"), r.FormValue("password"), r.FormValue("role")
|
||||||
|
if len(password) == 0 && role != auth.RoleApi {
|
||||||
|
http.Error(rw, "only API users are allowed to have a blank password (login will be impossible)", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := api.Authentication.AddUser(username + ":" + role + ":" + password); err != nil {
|
||||||
|
http.Error(rw, err.Error(), http.StatusUnprocessableEntity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *RestApi) updateConfiguration(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
key, value := r.FormValue("key"), r.FormValue("value")
|
||||||
|
if err := config.UpdateConfig(key, value, r.Context()); err != nil {
|
||||||
|
http.Error(rw, err.Error(), http.StatusUnprocessableEntity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (api *RestApi) putMachineState(rw http.ResponseWriter, r *http.Request) {
|
func (api *RestApi) putMachineState(rw http.ResponseWriter, r *http.Request) {
|
||||||
if api.MachineStateDir == "" {
|
if api.MachineStateDir == "" {
|
||||||
http.Error(rw, "not enabled", http.StatusNotFound)
|
http.Error(rw, "not enabled", http.StatusNotFound)
|
||||||
|
@ -296,8 +296,9 @@ func main() {
|
|||||||
|
|
||||||
// Initialize sub-modules...
|
// Initialize sub-modules...
|
||||||
|
|
||||||
authentication := &auth.Authentication{}
|
var authentication *auth.Authentication
|
||||||
if !programConfig.DisableAuthentication {
|
if !programConfig.DisableAuthentication {
|
||||||
|
authentication = &auth.Authentication{}
|
||||||
if d, err := time.ParseDuration(programConfig.SessionMaxAge); err != nil {
|
if d, err := time.ParseDuration(programConfig.SessionMaxAge); err != nil {
|
||||||
authentication.SessionMaxAge = d
|
authentication.SessionMaxAge = d
|
||||||
}
|
}
|
||||||
@ -398,6 +399,7 @@ func main() {
|
|||||||
JobRepository: jobRepo,
|
JobRepository: jobRepo,
|
||||||
Resolver: resolver,
|
Resolver: resolver,
|
||||||
MachineStateDir: programConfig.MachineStateDir,
|
MachineStateDir: programConfig.MachineStateDir,
|
||||||
|
Authentication: authentication,
|
||||||
}
|
}
|
||||||
|
|
||||||
handleGetLogin := func(rw http.ResponseWriter, r *http.Request) {
|
handleGetLogin := func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
Loading…
Reference in New Issue
Block a user