diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 6b89fa6b..e61fd2fa 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -1285,6 +1285,88 @@ func generateApikey(ctx context.Context, userInfo User) (User, error) { return userInfo, nil } +func handleUpdateUser(resp http.ResponseWriter, request *http.Request) { + cors := handleCors(resp, request) + if cors { + return + } + + userInfo, err := handleApiAuthentication(resp, request) + if err != nil { + log.Printf("Api authentication failed in apigen: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + body, err := ioutil.ReadAll(request.Body) + if err != nil { + log.Println("Failed reading body") + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Missing field: user_id"}`))) + return + } + + type newUserStruct struct { + Role string `json:"role"` + UserId string `json:"user_id"` + } + + ctx := context.Background() + var t newUserStruct + err = json.Unmarshal(body, &t) + if err != nil { + log.Printf("Failed unmarshaling userId: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unmarshaling. Missing field: user_id"}`))) + return + } + + if userInfo.Role != "admin" { + log.Printf("%s tried to update user %s", userInfo.Username, t.UserId) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "You need to be admin to change other users"}`))) + return + } + + foundUser, err := getUser(ctx, t.UserId) + if err != nil { + log.Printf("Can't find user %s (apikey gen)", t.UserId, err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false}`))) + return + } + + if t.Role != "admin" && t.Role != "user" { + log.Printf("%s tried and failed to update user %s", userInfo.Username, t.UserId) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can only change to role user and admin"}`))) + return + } else { + // Same user - can't edit yourself + if userInfo.Id == t.UserId { + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't update the role of your own user"}`))) + return + } + + log.Printf("Updated user %s from %s to %s", foundUser.Username, foundUser.Role, t.Role) + foundUser.Role = t.Role + foundUser.Roles = []string{t.Role} + } + + err = setUser(ctx, foundUser) + if err != nil { + log.Printf("Error patching user %s: %s", foundUser.Username, err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false}`))) + return + } + + resp.WriteHeader(200) + resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) +} + func handleApiGeneration(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { @@ -1343,8 +1425,8 @@ func handleApiGeneration(resp http.ResponseWriter, request *http.Request) { foundUser, err := getUser(ctx, t.UserId) if err != nil { log.Printf("Can't find user %s (apikey gen)", t.UserId, err) - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false}`))) return } @@ -6158,6 +6240,7 @@ func init() { r.HandleFunc("/api/v1/users/getinfo", handleInfo).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/users/getsettings", handleSettings).Methods("GET", "OPTIONS") r.HandleFunc("/api/v1/users/generateapikey", handleApiGeneration).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/users/updateuser", handleUpdateUser).Methods("PUT", "OPTIONS") r.HandleFunc("/api/v1/users/{user}", deleteUser).Methods("DELETE", "OPTIONS") // General - duplicates and old. diff --git a/frontend/src/Admin.js b/frontend/src/Admin.js index 8809dd1d..902bf3b9 100644 --- a/frontend/src/Admin.js +++ b/frontend/src/Admin.js @@ -2,6 +2,8 @@ import React, { useEffect} from 'react'; import {Link} from 'react-router-dom'; import Paper from '@material-ui/core/Paper'; +import Select from '@material-ui/core/Select'; +import MenuItem from '@material-ui/core/MenuItem'; import List from '@material-ui/core/List'; import Divider from '@material-ui/core/Divider'; import TextField from '@material-ui/core/TextField'; @@ -319,6 +321,43 @@ const Admin = (props) => { modalUser[field] = value } + const setUser = (userId, field, value) => { + const data = {"user_id": userId} + data[field] = value + console.log("DATA: ", data) + + fetch(globalUrl+"/api/v1/users/updateuser", { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + body: JSON.stringify(data), + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Status not 200 for WORKFLOW EXECUTION :O!") + } else { + getUsers() + } + + return response.json() + }) + .then((responseJson) => { + if (!responseJson.success && responseJson.reason !== undefined) { + alert.error("Failed setting user: "+responseJson.reason) + } else { + alert.success("Set the user field "+field+" to "+value) + } + }) + .catch(error => { + console.log(error) + }); + } + + + const generateApikey = (userId) => { const data = {"user_id": userId} @@ -543,10 +582,6 @@ const Admin = (props) => { primary="API key" style={{minWidth: 350, maxWidth: 350, overflow: "hidden"}} /> - { style={{maxWidth: 350, minWidth: 350,}} /> - { + console.log("VALUE: ", e.target.value) + setUser(data.id, "role", e.target.value) + }} + style={{backgroundColor: surfaceColor, color: "white", height: "50px"}} + > + + Admin + + + User + + style={{minWidth: 150, maxWidth: 150}} />