Admin endpoints

This commit is contained in:
Aurélie Delhaie
2022-06-14 20:34:55 +02:00
parent 3caa99b22a
commit 5ed0cfa837
8 changed files with 304 additions and 19 deletions

29
admin/admin.go Normal file
View File

@@ -0,0 +1,29 @@
package admin
import (
"opensavecloudserver/database"
"opensavecloudserver/upload"
)
// RemoveUser rome the user from the db and all his datas
func RemoveUser(user *database.User) error {
if err := database.RemoveAllUserGameEntries(user); err != nil {
return err
}
if err := upload.RemoveFolders(user.ID); err != nil {
return err
}
return database.RemoveUser(user)
}
func SetAdmin(user *database.User) error {
user.Role = database.AdminRole
user.IsAdmin = true
return database.SaveUser(user)
}
func RemoveAdminRole(user *database.User) error {
user.Role = database.UserRole
user.IsAdmin = false
return database.SaveUser(user)
}

View File

@@ -16,11 +16,8 @@ type AccessToken struct {
}
type Registration struct {
Username string `json:"username"`
Password string `json:"password"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
Pronouns int `json:"pronouns"`
Username string `json:"username"`
Password string `json:"password"`
}
func init() {

View File

@@ -15,7 +15,8 @@ import (
var db *gorm.DB
const adminRole string = "admin"
const AdminRole string = "admin"
const UserRole string = "user"
func init() {
dbConfig := config.Database()
@@ -56,7 +57,7 @@ func AllUsers() ([]*User, error) {
return nil, err
}
for _, user := range users {
if user.Role == adminRole {
if user.Role == AdminRole {
user.IsAdmin = true
}
}
@@ -70,7 +71,7 @@ func UserByUsername(username string) (*User, error) {
if err != nil {
return nil, err
}
if user.Role == adminRole {
if user.Role == AdminRole {
user.IsAdmin = true
}
return user, nil
@@ -79,11 +80,11 @@ func UserByUsername(username string) (*User, error) {
// UserById get a user
func UserById(userId int) (*User, error) {
var user *User
err := db.Model(User{}).Where(User{ID: userId}).First(&user).Error
err := db.Model(User{}).Where(userId).First(&user).Error
if err != nil {
return nil, err
}
if user.Role == adminRole {
if user.Role == AdminRole {
user.IsAdmin = true
}
return user, nil
@@ -98,12 +99,24 @@ func AddUser(username string, password []byte) error {
return db.Save(user).Error
}
func SaveUser(user *User) error {
return db.Save(user).Error
}
func RemoveUser(user *User) error {
return db.Delete(User{}, user.ID).Error
}
func RemoveAllUserGameEntries(user *User) error {
return db.Delete(Game{}, Game{UserId: user.ID}).Error
}
// AddAdmin register a user and set his role to admin
/*func AddAdmin(username string, password []byte) error {
user := &User{
Username: username,
Password: password,
Role: adminRole,
Role: AdminRole,
}
return db.Save(user).Error
}*/

178
server/admin.go Normal file
View File

@@ -0,0 +1,178 @@
package server
import (
"encoding/json"
"github.com/go-chi/chi/v5"
"io"
"log"
"net/http"
"opensavecloudserver/admin"
"opensavecloudserver/authentication"
"opensavecloudserver/database"
"strconv"
"time"
)
func AddUser(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
userInfo := new(authentication.Registration)
err = json.Unmarshal(body, userInfo)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
err = authentication.Register(userInfo)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
user, err := database.UserByUsername(userInfo.Username)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
ok(user, w, r)
}
func RemoveUser(w http.ResponseWriter, r *http.Request) {
queryId := chi.URLParam(r, "id")
id, err := strconv.Atoi(queryId)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
user, err := database.UserById(id)
if err != nil {
notFound(err.Error(), w, r)
log.Println(err)
return
}
err = admin.RemoveUser(user)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
ok(user, w, r)
}
func AllUsers(w http.ResponseWriter, r *http.Request) {
users, err := database.AllUsers()
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
ok(users, w, r)
}
func User(w http.ResponseWriter, r *http.Request) {
queryId := chi.URLParam(r, "id")
id, err := strconv.Atoi(queryId)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
user, err := database.UserById(id)
if err != nil {
notFound(err.Error(), w, r)
log.Println(err)
return
}
ok(user, w, r)
}
func SetAdmin(w http.ResponseWriter, r *http.Request) {
queryId := chi.URLParam(r, "id")
id, err := strconv.Atoi(queryId)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
user, err := database.UserById(id)
if err != nil {
notFound(err.Error(), w, r)
log.Println(err)
return
}
err = admin.SetAdmin(user)
if err != nil {
notFound(err.Error(), w, r)
log.Println(err)
return
}
ok(user, w, r)
}
func SetNotAdmin(w http.ResponseWriter, r *http.Request) {
queryId := chi.URLParam(r, "id")
id, err := strconv.Atoi(queryId)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
user, err := database.UserById(id)
if err != nil {
notFound(err.Error(), w, r)
log.Println(err)
return
}
err = admin.RemoveAdminRole(user)
if err != nil {
notFound(err.Error(), w, r)
log.Println(err)
return
}
ok(user, w, r)
}
func ChangeUserPassword(w http.ResponseWriter, r *http.Request) {
queryId := chi.URLParam(r, "id")
userId, err := strconv.Atoi(queryId)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
newPassword := new(NewPassword)
err = json.Unmarshal(body, newPassword)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
if newPassword.Password != newPassword.VerifyPassword {
badRequest("password are not the same", w, r)
return
}
err = database.ChangePassword(userId, []byte(newPassword.Password))
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
payload := &successMessage{
Message: "Password changed",
Timestamp: time.Now(),
Status: 200,
}
ok(payload, w, r)
}

View File

@@ -81,7 +81,7 @@ func GameInfoByID(w http.ResponseWriter, r *http.Request) {
}
game, err := database.GameInfoById(userId, id)
if err != nil {
internalServerError(w, r)
notFound(err.Error(), w, r)
log.Println(err)
return
}
@@ -293,12 +293,31 @@ func ChangePassword(w http.ResponseWriter, r *http.Request) {
ok(payload, w, r)
}
func AllUsers(w http.ResponseWriter, r *http.Request) {
users, err := database.AllUsers()
func RemoveGame(w http.ResponseWriter, r *http.Request) {
userId, err := userIdFromContext(r.Context())
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
ok(users, w, r)
queryId := chi.URLParam(r, "id")
id, err := strconv.Atoi(queryId)
if err != nil {
badRequest("Game ID missing or not an int", w, r)
log.Println(err)
return
}
game, err := database.GameInfoById(userId, id)
if err != nil {
notFound(err.Error(), w, r)
log.Println(err)
return
}
err = upload.RemoveGame(userId, game)
if err != nil {
internalServerError(w, r)
log.Println(err)
return
}
ok(game, w, r)
}

View File

@@ -42,6 +42,27 @@ func internalServerError(w http.ResponseWriter, r *http.Request) {
}
}
func notFound(message string, w http.ResponseWriter, r *http.Request) {
e := httpError{
Status: 404,
Error: "Not Found",
Message: message,
Path: r.RequestURI,
Timestamp: time.Now(),
}
payload, err := json.Marshal(e)
if err != nil {
log.Println(err)
}
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(404)
_, err = w.Write(payload)
if err != nil {
log.Println(err)
}
}
func unauthorized(w http.ResponseWriter, r *http.Request) {
e := httpError{
Status: 401,

View File

@@ -35,9 +35,6 @@ func Serve() {
}
r.Route("/system", func(systemRouter chi.Router) {
systemRouter.Get("/information", Information)
systemRouter.Group(func(secureRouter chi.Router) {
secureRouter.Get("/users", AllUsers)
})
})
r.Route("/user", func(secureRouter chi.Router) {
secureRouter.Use(authMiddleware)
@@ -45,13 +42,20 @@ func Serve() {
secureRouter.Post("/passwd", ChangePassword)
})
r.Route("/admin", func(secureRouter chi.Router) {
secureRouter.Use(authMiddleware)
secureRouter.Use(adminMiddleware)
secureRouter.Post("/user", AddUser)
secureRouter.Post("/user/passwd/{id}", ChangeUserPassword)
secureRouter.Delete("/user/{id}", RemoveUser)
secureRouter.Get("/user/{id}", User)
secureRouter.Get("/users", AllUsers)
secureRouter.Get("/user/role/admin/{id}", SetAdmin)
secureRouter.Get("/user/role/user/{id}", SetNotAdmin)
})
r.Route("/game", func(secureRouter chi.Router) {
secureRouter.Use(authMiddleware)
secureRouter.Post("/create", CreateGame)
secureRouter.Get("/all", AllGamesInformation)
secureRouter.Delete("/remove/{id}", RemoveGame)
secureRouter.Get("/info/{id}", GameInfoByID)
secureRouter.Post("/upload/init", AskForUpload)
secureRouter.Group(func(uploadRouter chi.Router) {

View File

@@ -163,6 +163,30 @@ func UnlockGame(gameId int) {
delete(locks, gameId)
}
// RemoveFolders remove all files of the user from storage and cache
func RemoveFolders(userId int) error {
userPath := path.Join(config.Path().Storage, strconv.Itoa(userId))
userCache := path.Join(config.Path().Cache, strconv.Itoa(userId))
if _, err := os.Stat(userPath); err == nil {
err := os.RemoveAll(userPath)
if err != nil {
log.Fatal(err)
}
}
if _, err := os.Stat(userCache); err == nil {
err := os.RemoveAll(userCache)
if err != nil {
log.Fatal(err)
}
}
return nil
}
func RemoveGame(userId int, game *database.Game) error {
filePath := path.Join(config.Path().Storage, strconv.Itoa(userId), game.PathStorage)
return os.Remove(filePath)
}
// clearLocks clear lock of zombi upload
func clearLocks() {
mu.Lock()