mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 13:29:05 +01:00
first iteraton of implementing ip-secured enpoint
This commit is contained in:
parent
38f58047f2
commit
6393035e55
@ -20,6 +20,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/auth"
|
"github.com/ClusterCockpit/cc-backend/internal/auth"
|
||||||
|
"github.com/ClusterCockpit/cc-backend/internal/config"
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/graph"
|
"github.com/ClusterCockpit/cc-backend/internal/graph"
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/graph/model"
|
"github.com/ClusterCockpit/cc-backend/internal/graph/model"
|
||||||
"github.com/ClusterCockpit/cc-backend/internal/importer"
|
"github.com/ClusterCockpit/cc-backend/internal/importer"
|
||||||
@ -75,6 +76,8 @@ func (api *RestApi) MountRoutes(r *mux.Router) {
|
|||||||
r.HandleFunc("/jobs/delete_job/", api.deleteJobByRequest).Methods(http.MethodDelete)
|
r.HandleFunc("/jobs/delete_job/", api.deleteJobByRequest).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/jobs/delete_job/{id}", api.deleteJobById).Methods(http.MethodDelete)
|
r.HandleFunc("/jobs/delete_job/{id}", api.deleteJobById).Methods(http.MethodDelete)
|
||||||
r.HandleFunc("/jobs/delete_job_before/{ts}", api.deleteJobBefore).Methods(http.MethodDelete)
|
r.HandleFunc("/jobs/delete_job_before/{ts}", api.deleteJobBefore).Methods(http.MethodDelete)
|
||||||
|
r.HandleFunc("/secured/addProject/{id}/{project}", api.secureUpdateUser).Methods(http.MethodPost)
|
||||||
|
r.HandleFunc("/secured/addRole/{id}/{role}", api.secureUpdateUser).Methods(http.MethodPost)
|
||||||
|
|
||||||
if api.Authentication != nil {
|
if api.Authentication != nil {
|
||||||
r.HandleFunc("/jwt/", api.getJWT).Methods(http.MethodGet)
|
r.HandleFunc("/jwt/", api.getJWT).Methods(http.MethodGet)
|
||||||
@ -103,6 +106,11 @@ type DeleteJobApiResponse struct {
|
|||||||
Message string `json:"msg"`
|
Message string `json:"msg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateUserApiResponse model
|
||||||
|
type UpdateUserApiResponse struct {
|
||||||
|
Message string `json:"msg"`
|
||||||
|
}
|
||||||
|
|
||||||
// StopJobApiRequest model
|
// StopJobApiRequest model
|
||||||
type StopJobApiRequest struct {
|
type StopJobApiRequest struct {
|
||||||
// Stop Time of job as epoch
|
// Stop Time of job as epoch
|
||||||
@ -1043,6 +1051,77 @@ func (api *RestApi) updateUser(rw http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *RestApi) secureUpdateUser(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if user := auth.GetUser(r.Context()); user != nil && !user.HasRole(auth.RoleApi) {
|
||||||
|
handleError(fmt.Errorf("missing role: %v", auth.GetRoleString(auth.RoleApi)), http.StatusForbidden, rw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If nothing declared in config: deny all request to this endpint
|
||||||
|
if config.Keys.ApiAllowedAddrs == nil || len(config.Keys.ApiAllowedAddrs) == 0 {
|
||||||
|
handleError(fmt.Errorf("denied by default policy!"), http.StatusForbidden, rw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// IP CHECK HERE (WIP)
|
||||||
|
// Probably better as private routine
|
||||||
|
IPAddress := r.Header.Get("X-Real-Ip")
|
||||||
|
if IPAddress == "" {
|
||||||
|
IPAddress = r.Header.Get("X-Forwarded-For")
|
||||||
|
}
|
||||||
|
if IPAddress == "" {
|
||||||
|
IPAddress = r.RemoteAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also This
|
||||||
|
ipOk := false
|
||||||
|
for _, a := range config.Keys.ApiAllowedAddrs {
|
||||||
|
if a == IPAddress {
|
||||||
|
ipOk = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if IPAddress == "" || ipOk == false {
|
||||||
|
handleError(fmt.Errorf("unknown ip: %v", IPAddress), http.StatusForbidden, rw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// IP CHECK END
|
||||||
|
|
||||||
|
// Get Values
|
||||||
|
id := mux.Vars(r)["id"]
|
||||||
|
newproj := mux.Vars(r)["project"]
|
||||||
|
newrole := mux.Vars(r)["role"]
|
||||||
|
|
||||||
|
// TODO: Handle anything but roles...
|
||||||
|
if newrole != "" {
|
||||||
|
if err := api.Authentication.AddRole(r.Context(), id, newrole); err != nil {
|
||||||
|
handleError(errors.New(err.Error()), http.StatusUnprocessableEntity, rw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rw.Header().Add("Content-Type", "application/json")
|
||||||
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
json.NewEncoder(rw).Encode(UpdateUserApiResponse{
|
||||||
|
Message: fmt.Sprintf("Successfully added role %s to %s", newrole, id),
|
||||||
|
})
|
||||||
|
|
||||||
|
} else if newproj != "" {
|
||||||
|
if err := api.Authentication.AddProject(r.Context(), id, newproj); err != nil {
|
||||||
|
handleError(errors.New(err.Error()), http.StatusUnprocessableEntity, rw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rw.Header().Add("Content-Type", "application/json")
|
||||||
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
json.NewEncoder(rw).Encode(UpdateUserApiResponse{
|
||||||
|
Message: fmt.Sprintf("Successfully added project %s to %s", newproj, id),
|
||||||
|
})
|
||||||
|
|
||||||
|
} else {
|
||||||
|
handleError(errors.New("Not Add [role|project]?"), http.StatusBadRequest, rw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (api *RestApi) updateConfiguration(rw http.ResponseWriter, r *http.Request) {
|
func (api *RestApi) updateConfiguration(rw http.ResponseWriter, r *http.Request) {
|
||||||
rw.Header().Set("Content-Type", "text/plain")
|
rw.Header().Set("Content-Type", "text/plain")
|
||||||
key, value := r.FormValue("key"), r.FormValue("value")
|
key, value := r.FormValue("key"), r.FormValue("value")
|
||||||
|
@ -69,6 +69,9 @@ type ProgramConfig struct {
|
|||||||
// Address where the http (or https) server will listen on (for example: 'localhost:80').
|
// Address where the http (or https) server will listen on (for example: 'localhost:80').
|
||||||
Addr string `json:"addr"`
|
Addr string `json:"addr"`
|
||||||
|
|
||||||
|
// Addresses from which the /secured/* API endpoints can be reached
|
||||||
|
ApiAllowedAddrs []string `json:"apiAllowedAddrs"`
|
||||||
|
|
||||||
// Drop root permissions once .env was read and the port was taken.
|
// Drop root permissions once .env was read and the port was taken.
|
||||||
User string `json:"user"`
|
User string `json:"user"`
|
||||||
Group string `json:"group"`
|
Group string `json:"group"`
|
||||||
|
Loading…
Reference in New Issue
Block a user