aligned users to new design
This commit is contained in:
parent
f57888cb8e
commit
ffdefae94f
31
auth/auth.go
31
auth/auth.go
@ -246,37 +246,6 @@ func (con Connection) verify(c *gin.Context) {
|
||||
|
||||
c.Redirect(303, fmt.Sprintf("http://%s/login", DOMAIN))
|
||||
}
|
||||
|
||||
func (con Connection) ServerAuthorized(permissions models.Permission) func(*gin.Context) bool {
|
||||
return func(ctx *gin.Context) bool {
|
||||
claims, exists := ctx.Get("claims")
|
||||
if !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
server_id := ctx.Param("server_id")
|
||||
if server_id == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
var serverData models.ServerData
|
||||
|
||||
con.DatabaseConnection.Database("Backend").Collection("Servers").FindOne(context.TODO(), bson.D{{Key: "Id", Value: server_id}}).Decode(&serverData)
|
||||
|
||||
if serverData.OwnerId == claims.(*AuthClaims).Username {
|
||||
return true
|
||||
}
|
||||
|
||||
userPermissions := serverData.UserPermissions[claims.(*AuthClaims).Username]
|
||||
|
||||
if userPermissions&permissions == permissions || userPermissions&models.Admin == models.Admin {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func LoadGroup(group *gin.RouterGroup, client *mongo.Client, config models.GlobalConfig) {
|
||||
connection := Connection{DatabaseConnection: client}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
|
||||
"github.com/google/uuid"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
@ -14,14 +15,11 @@ import (
|
||||
|
||||
type AuthUser struct {
|
||||
Username string `json:"username"`
|
||||
Nickname string `json:"nickname"`
|
||||
HashedPassword string `json:"hashed_password"`
|
||||
Permissions models.Permission `json:"permissions"`
|
||||
}
|
||||
|
||||
type Invite struct {
|
||||
Email string `json:"email"`
|
||||
InvitingUser string `json:"inviting_user"`
|
||||
Token string `json:"token"`
|
||||
MaxOwnedSevers uint `json:"max_owned_severs"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type UserPassAuthenticationDbHandler struct {
|
||||
@ -29,6 +27,29 @@ type UserPassAuthenticationDbHandler struct {
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
func (self *UserPassAuthenticationDbHandler) ListUsers(ctx context.Context) ([]models.User, error) {
|
||||
cursor, err := self.collection.Find(ctx, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var authUsers []AuthUser
|
||||
|
||||
cursor.All(ctx, &authUsers)
|
||||
|
||||
modelUsers := make([]models.User, len(authUsers))
|
||||
for i, authUser := range authUsers {
|
||||
modelUsers[i] = models.User{
|
||||
Username: authUser.Username,
|
||||
Nickname: authUser.Nickname,
|
||||
Email: authUser.Email,
|
||||
}
|
||||
}
|
||||
|
||||
return modelUsers, nil
|
||||
}
|
||||
|
||||
func (self *UserPassAuthenticationDbHandler) AuthenticateUser(ctx context.Context, username string, password string) (models.Permission, error) {
|
||||
var user AuthUser
|
||||
err := self.collection.FindOne(ctx, bson.M{"username": username}).Decode(&user)
|
||||
@ -55,6 +76,8 @@ func (self *UserPassAuthenticationDbHandler) CreateUser(
|
||||
username string,
|
||||
password string,
|
||||
permissions models.Permission,
|
||||
email string,
|
||||
maxOwnedServers uint,
|
||||
) error {
|
||||
hashedPassword, err := dbhandler.HashPassword(password)
|
||||
|
||||
@ -66,6 +89,8 @@ func (self *UserPassAuthenticationDbHandler) CreateUser(
|
||||
Username: username,
|
||||
HashedPassword: hashedPassword,
|
||||
Permissions: permissions,
|
||||
Email: email,
|
||||
MaxOwnedSevers: maxOwnedServers,
|
||||
})
|
||||
|
||||
return err
|
||||
@ -121,3 +146,63 @@ func NewUserPassAuthHandler(config models.MongoDBConfig) (*UserPassAuthenticatio
|
||||
collection: client.Database(config.Database).Collection(config.Collection),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type InviteToken struct {
|
||||
Email string `json:"email"`
|
||||
Token string `json:"token"`
|
||||
Permissions models.Permission `json:"permissions"`
|
||||
}
|
||||
|
||||
type InviteTokenDbHandler struct {
|
||||
dbhandler.InviteTokenDbHandler
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) SaveInviteToken(ctx context.Context, email string, permissions models.Permission) (string, error) {
|
||||
token := uuid.NewString()
|
||||
|
||||
_, err := self.collection.InsertOne(ctx, &InviteToken{
|
||||
Permissions: permissions,
|
||||
Email: email,
|
||||
Token: token,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (self *ServersDbHandler) GetInviteToken(ctx context.Context, token string) (*dbhandler.InviteToken, error) {
|
||||
var inviteToken InviteToken
|
||||
err := self.collection.FindOne(ctx, bson.M{"token": token}).Decode(&inviteToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dbhandler.InviteToken{
|
||||
Email: inviteToken.Email,
|
||||
Permissions: inviteToken.Permissions,
|
||||
Token: inviteToken.Token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewInviteTokenDbHandler(config models.MongoDBConfig) (*InviteTokenDbHandler, error) {
|
||||
clientOptions := options.Client().ApplyURI(config.Url).SetAuth(options.Credential{
|
||||
Username: config.Username,
|
||||
Password: config.Password,
|
||||
})
|
||||
|
||||
ctx, cancel := context.WithTimeoutCause(context.Background(), 30*time.Second, fmt.Errorf("Timeout"))
|
||||
defer cancel()
|
||||
|
||||
client, err := mongo.Connect(ctx, clientOptions)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &InviteTokenDbHandler{
|
||||
collection: client.Database(config.Database).Collection(config.Collection),
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package dbhandler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
@ -10,33 +12,31 @@ func HashPassword(password string) (string, error) {
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
type InviteUserRequest struct {
|
||||
Email string `json:"email"`
|
||||
InvitingUser string `json:"inviting_user"`
|
||||
Permissions models.Permission `json:"permissions"`
|
||||
}
|
||||
|
||||
type InviteToken struct {
|
||||
Email string `json:"email"`
|
||||
Permissions models.Permission `json:"permissions"`
|
||||
Token string `json:"token"`
|
||||
Email string
|
||||
Permissions models.Permission
|
||||
Token string
|
||||
}
|
||||
|
||||
type UserSignupRequest struct {
|
||||
Token InviteToken `json:"token"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Token InviteToken
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type UserPassAuthanticationDbHandler interface {
|
||||
AuthenticateUser(username string, password string) (models.Permission, error)
|
||||
CreateUser(username string, password string, permissions models.Permission) error
|
||||
RemoveUser(username string) error
|
||||
SetPermissions(username string, permissions models.Permission) error
|
||||
SetPassword(username string, password string) error
|
||||
// Read Only
|
||||
AuthenticateUser(ctx context.Context, username string, password string) (models.Permission, error)
|
||||
ListUsers(ctx context.Context) ([]models.User, error)
|
||||
|
||||
// Write
|
||||
CreateUser(ctx context.Context, username string, password string, permissions models.Permission, email string, maxOwnedServers uint) error
|
||||
RemoveUser(ctx context.Context, username string) error
|
||||
SetPermissions(ctx context.Context, username string, permissions models.Permission) error
|
||||
SetPassword(ctx context.Context, username string, password string) error
|
||||
}
|
||||
|
||||
type InviteTokenDbHandler interface {
|
||||
SaveInviteToken(token string, email string, permissions models.Permission) error
|
||||
GetInviteToken(token string) (*InviteToken, error)
|
||||
SaveInviteToken(ctx context.Context, email string, permissions models.Permission) (string, error)
|
||||
GetInviteToken(ctx context.Context, token string) (*InviteToken, error)
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NB
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
|
@ -26,11 +26,17 @@ type OidcAuthConfig struct {
|
||||
ClientSecret string `yaml:"client_secret"`
|
||||
}
|
||||
|
||||
type UserPassAuthConfig struct {
|
||||
type InviteTokenDatabaseConfig struct {
|
||||
Type DatabaseType `yaml:"type"`
|
||||
Mongo *MongoDBConfig `yaml:"mongo"`
|
||||
}
|
||||
|
||||
type UserPassAuthConfig struct {
|
||||
Type DatabaseType `yaml:"type"`
|
||||
Mongo *MongoDBConfig `yaml:"mongo"`
|
||||
InviteTokenDatabase InviteTokenDatabaseConfig `yaml:"invite_token_database"`
|
||||
}
|
||||
|
||||
type AuthenticationConfig struct {
|
||||
Type AuthMode `yaml:"type"`
|
||||
Oidc OidcAuthConfig `yaml:"oidc"`
|
||||
|
@ -1,152 +1,71 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/auth"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/db_handler/mongo"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
|
||||
instancemanager "git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager/docker"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
func (con Connection) getBrowserInfo(volume volume.Volume) (*models.FileBrowser, error) {
|
||||
serverInfo, err := con.getServerInfo(volume)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
containers, err := con.dockerClient.ContainerList(context.TODO(), container.ListOptions{
|
||||
All: true,
|
||||
Filters: filters.NewArgs(filters.Arg("label", "type=FILE_BROWSER"), filters.Arg("label", fmt.Sprintf("volume_id=%s", volume.Name))),
|
||||
})
|
||||
if err != nil || len(containers) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
container := containers[0]
|
||||
jsonData, err := json.Marshal(container.Labels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var browserInfo ContainerLabels
|
||||
err = json.Unmarshal(jsonData, &browserInfo)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.FileBrowser{
|
||||
Id: serverInfo.Id,
|
||||
OwnerId: browserInfo.OwnerId,
|
||||
ConnectedTo: *serverInfo,
|
||||
Url: serverInfo.Id[:12] + ".browsers." + DOMAIN,
|
||||
}, nil
|
||||
|
||||
}
|
||||
func (con Connection) getBrowserInfoFromServerId(serverId string) (*models.FileBrowser, error) {
|
||||
serverInfo, err := con.getServerInfoFromId(serverId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
containers, err := con.dockerClient.ContainerList(context.TODO(), container.ListOptions{
|
||||
All: true,
|
||||
Filters: filters.NewArgs(filters.Arg("label", "type=FILE_BROWSER"), filters.Arg("label", fmt.Sprintf("volume_id=%s", serverInfo.Id))),
|
||||
})
|
||||
if err != nil || len(containers) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
container := containers[0]
|
||||
jsonData, err := json.Marshal(container.Labels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var browserInfo ContainerLabels
|
||||
err = json.Unmarshal(jsonData, &browserInfo)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.FileBrowser{
|
||||
Id: serverInfo.Id,
|
||||
OwnerId: browserInfo.OwnerId,
|
||||
ConnectedTo: *serverInfo,
|
||||
Url: serverInfo.Id[:12] + ".browsers." + DOMAIN,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func (con Connection) GetBrowsers(ctx *gin.Context) {
|
||||
volumes, err := con.dockerClient.VolumeList(
|
||||
context.TODO(),
|
||||
volume.ListOptions{
|
||||
Filters: filters.NewArgs(filters.Arg("label", "type=GAME")),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
|
||||
var servers []models.FileBrowser = make([]models.FileBrowser, 0, len(volumes.Volumes))
|
||||
|
||||
for _, volume := range volumes.Volumes {
|
||||
browserInfo, err := con.getBrowserInfo(*volume)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
if browserInfo == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
servers = append(servers, *browserInfo)
|
||||
}
|
||||
fileBrowsers, err := con.InstanceManager.ListFileBrowsers(ctx)
|
||||
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
}
|
||||
|
||||
ctx.JSON(200, servers)
|
||||
ctx.JSON(200, fileBrowsers)
|
||||
}
|
||||
|
||||
func (con Connection) StopBrowser(ctx *gin.Context) {
|
||||
serverId := ctx.Param("server_id")
|
||||
containersList, err := con.dockerClient.ContainerList(context.TODO(), container.ListOptions{
|
||||
Filters: filters.NewArgs(filters.Arg("label", "volume_id="+serverId), filters.Arg("label", "type=FILE_BROWSER")),
|
||||
})
|
||||
err := con.InstanceManager.StopFileBrowser(ctx, serverId)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
if len(containersList) == 0 {
|
||||
ctx.Status(200)
|
||||
return
|
||||
}
|
||||
|
||||
for _, containerData := range containersList {
|
||||
con.dockerClient.ContainerStop(context.TODO(), containerData.ID, container.StopOptions{})
|
||||
}
|
||||
ctx.Status(200)
|
||||
}
|
||||
|
||||
func LoadBrowsersGroup(group *gin.RouterGroup, mongo_client *mongo.Client, config models.GlobalConfig) {
|
||||
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer apiClient.Close()
|
||||
func LoadBrowsersGroup(group *gin.RouterGroup, config models.GlobalConfig) {
|
||||
var instanceManager instancemanager.InstanceManager
|
||||
var serversDbHandler dbhandler.ServersDbHandler
|
||||
var serversAuthorizationHandler dbhandler.ServersAuthorizationDbHandler
|
||||
|
||||
var err error
|
||||
|
||||
if config.InstanceManager.Type == models.DOCKER {
|
||||
instanceManager, err = docker.NewInstanceManager(config.InstanceManager.Docker)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.ServersDatabase.Type == models.MONGO {
|
||||
serversDbHandler, err = mongo.NewServersDbHandler(*config.ServersDatabase.Mongo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.ServersAuthorizationDatabase.Type == models.MONGO {
|
||||
serversAuthorizationHandler, err = mongo.NewAuthorizationHandler(*config.ServersAuthorizationDatabase.Mongo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
connection := Connection{
|
||||
ServersDbHandler: serversDbHandler,
|
||||
ServerAuthorization: serversAuthorizationHandler,
|
||||
InstanceManager: instanceManager,
|
||||
}
|
||||
|
||||
connection := Connection{databaseConnection: mongo_client, dockerClient: apiClient}
|
||||
authConnection := auth.Connection{DatabaseConnection: mongo_client}
|
||||
group.GET("", auth.AuthorizedTo(0), connection.GetBrowsers)
|
||||
group.POST("/:server_id/stop", auth.AuthorizedTo(models.Browse, authConnection.ServerAuthorized(models.Browse)), connection.StopBrowser)
|
||||
group.POST("/:server_id/stop", auth.AuthorizedTo(models.Browse), connection.ServerAuthorized(models.Browse), connection.StopBrowser)
|
||||
}
|
||||
|
@ -1,46 +1,41 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/auth"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/db_handler/mongo"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
|
||||
instancemanager "git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/instance_manager/docker"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type ImageData struct {
|
||||
Id string
|
||||
Name string
|
||||
Version string
|
||||
DisplayName string
|
||||
Id string `json:"Id"`
|
||||
Name string `json:"Name"`
|
||||
Version string `json:"Version"`
|
||||
DisplayName string `json:"DisplayName"`
|
||||
}
|
||||
|
||||
func convertImageToImageData(imageSummary image.Summary) *ImageData {
|
||||
if len(imageSummary.RepoTags) == 0 {
|
||||
return nil
|
||||
}
|
||||
imageId := imageSummary.RepoTags[0]
|
||||
splitImageId := strings.Split(imageId, ":")
|
||||
imageName, imageVersion := splitImageId[0], splitImageId[1]
|
||||
func convertImageToImageData(instanceImage instancemanager.Image) *ImageData {
|
||||
imageId := instanceImage.Registry + ":" + instanceImage.Tag
|
||||
|
||||
return &ImageData{
|
||||
Id: imageId,
|
||||
Name: imageName,
|
||||
Version: imageVersion,
|
||||
DisplayName: fmt.Sprintf("%s %s", imageName, imageVersion),
|
||||
Name: instanceImage.Registry,
|
||||
Version: instanceImage.Tag,
|
||||
DisplayName: fmt.Sprintf("%s %s", instanceImage.Registry, instanceImage.Tag),
|
||||
}
|
||||
}
|
||||
func (con Connection) GetImages(c *gin.Context) {
|
||||
images, err := con.dockerClient.ImageList(context.TODO(), image.ListOptions{Filters: filters.NewArgs(filters.Arg("label", "type=GAME"))})
|
||||
func (con Connection) GetImages(ctx *gin.Context) {
|
||||
images, err := con.InstanceManager.ListImages(ctx)
|
||||
if err != nil {
|
||||
c.AbortWithError(500, err)
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
imagesData := make([]ImageData, 0, len(images))
|
||||
|
||||
for _, imageSummary := range images {
|
||||
@ -52,16 +47,43 @@ func (con Connection) GetImages(c *gin.Context) {
|
||||
imagesData = append(imagesData, *imageData)
|
||||
}
|
||||
|
||||
c.JSON(200, imagesData)
|
||||
ctx.JSON(200, imagesData)
|
||||
}
|
||||
|
||||
func LoadeImagesGroup(group *gin.RouterGroup, mongo_client *mongo.Client, config models.GlobalConfig) {
|
||||
apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer apiClient.Close()
|
||||
func LoadeImagesGroup(group *gin.RouterGroup, config models.GlobalConfig) {
|
||||
var instanceManager instancemanager.InstanceManager
|
||||
var serversDbHandler dbhandler.ServersDbHandler
|
||||
var serversAuthorizationHandler dbhandler.ServersAuthorizationDbHandler
|
||||
|
||||
var err error
|
||||
|
||||
if config.InstanceManager.Type == models.DOCKER {
|
||||
instanceManager, err = docker.NewInstanceManager(config.InstanceManager.Docker)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.ServersDatabase.Type == models.MONGO {
|
||||
serversDbHandler, err = mongo.NewServersDbHandler(*config.ServersDatabase.Mongo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.ServersAuthorizationDatabase.Type == models.MONGO {
|
||||
serversAuthorizationHandler, err = mongo.NewAuthorizationHandler(*config.ServersAuthorizationDatabase.Mongo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
connection := Connection{
|
||||
ServersDbHandler: serversDbHandler,
|
||||
ServerAuthorization: serversAuthorizationHandler,
|
||||
InstanceManager: instanceManager,
|
||||
}
|
||||
|
||||
connection := Connection{databaseConnection: mongo_client, dockerClient: apiClient}
|
||||
group.GET("", auth.AuthorizedTo(0), connection.GetImages)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -19,7 +18,6 @@ import (
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
@ -67,6 +65,37 @@ type CreateServerRequest struct {
|
||||
Nickname string `json:"Nickname"`
|
||||
}
|
||||
|
||||
func (con Connection) ServerAuthorized(permissions models.Permission) func(*gin.Context) {
|
||||
return func(ctx *gin.Context) {
|
||||
claimsPointer, exists := ctx.Get("claims")
|
||||
if !exists {
|
||||
ctx.AbortWithStatus(403)
|
||||
return
|
||||
}
|
||||
|
||||
claims := claimsPointer.(*auth.AuthClaims)
|
||||
|
||||
serverId := ctx.Param("server_id")
|
||||
if serverId == "" {
|
||||
ctx.AbortWithStatus(403)
|
||||
return
|
||||
}
|
||||
|
||||
userPermissions, err := con.ServerAuthorization.GetPermissions(ctx, claims.Username, serverId)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
if userPermissions&permissions == permissions || userPermissions&models.Admin == models.Admin {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.AbortWithStatus(403)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (con Connection) CreateServer(ctx *gin.Context) {
|
||||
claims, exists := ctx.Get("claims")
|
||||
if !exists {
|
||||
@ -109,6 +138,12 @@ func (con Connection) CreateServer(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
err = con.ServerAuthorization.AddPermissions(ctx, serverClaims.Username, instanceServer.Id, models.Admin)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(200, instanceServer.Id)
|
||||
}
|
||||
|
||||
@ -540,17 +575,16 @@ func LoadGroup(group *gin.RouterGroup, config models.GlobalConfig) {
|
||||
ServerAuthorization: serversAuthorizationHandler,
|
||||
InstanceManager: instanceManager,
|
||||
}
|
||||
authConnection := auth.Connection{}
|
||||
|
||||
group.POST("/:server_id/start", auth.AuthorizedTo(models.Start, authConnection.ServerAuthorized(models.Start)), connection.StartServer)
|
||||
group.POST("/:server_id/start", auth.AuthorizedTo(models.Start), connection.ServerAuthorized(models.Start), connection.StartServer)
|
||||
group.POST("", auth.AuthorizedTo(models.Create), connection.CreateServer)
|
||||
group.GET("", auth.AuthorizedTo(0), connection.GetServers)
|
||||
group.POST("/:server_id/stop", auth.AuthorizedTo(models.Stop, authConnection.ServerAuthorized(models.Stop)), connection.StopServer)
|
||||
group.DELETE("/:server_id", auth.AuthorizedTo(models.Delete, authConnection.ServerAuthorized(models.Delete)), connection.DeleteServer)
|
||||
group.POST("/:server_id/run_command", auth.AuthorizedTo(models.RunCommand, authConnection.ServerAuthorized(models.RunCommand)), connection.RunCommand)
|
||||
group.GET("/:server_id/attach", auth.AuthorizedTo(models.RunCommand, authConnection.ServerAuthorized(models.RunCommand)), connection.AttachServer)
|
||||
group.PATCH("/:server_id", auth.AuthorizedTo(models.Admin, authConnection.ServerAuthorized(models.Admin)), connection.UpdateServer)
|
||||
group.POST("/:server_id/browse", auth.AuthorizedTo(models.Browse, authConnection.ServerAuthorized(models.Admin)), connection.BrowseServer)
|
||||
group.GET("/:server_id/permissions", auth.AuthorizedTo(models.Browse, authConnection.ServerAuthorized(models.Admin)), connection.GetServerUserPermissions)
|
||||
group.POST("/:server_id/permissions", auth.AuthorizedTo(models.Browse, authConnection.ServerAuthorized(models.Admin)), connection.SetServerUserPermissions)
|
||||
group.POST("/:server_id/stop", auth.AuthorizedTo(models.Stop), connection.ServerAuthorized(models.Stop), connection.StopServer)
|
||||
group.DELETE("/:server_id", auth.AuthorizedTo(models.Delete), connection.ServerAuthorized(models.Delete), connection.DeleteServer)
|
||||
group.POST("/:server_id/run_command", auth.AuthorizedTo(models.RunCommand), connection.ServerAuthorized(models.RunCommand), connection.RunCommand)
|
||||
group.GET("/:server_id/attach", auth.AuthorizedTo(models.RunCommand), connection.ServerAuthorized(models.RunCommand), connection.AttachServer)
|
||||
group.PATCH("/:server_id", auth.AuthorizedTo(models.Admin), connection.ServerAuthorized(models.Admin), connection.UpdateServer)
|
||||
group.POST("/:server_id/browse", auth.AuthorizedTo(models.Browse), connection.ServerAuthorized(models.Admin), connection.BrowseServer)
|
||||
group.GET("/:server_id/permissions", auth.AuthorizedTo(models.Browse), connection.ServerAuthorized(models.Admin), connection.GetServerUserPermissions)
|
||||
group.POST("/:server_id/permissions", auth.AuthorizedTo(models.Browse), connection.ServerAuthorized(models.Admin), connection.SetServerUserPermissions)
|
||||
}
|
||||
|
132
users/users.go
132
users/users.go
@ -1,49 +1,49 @@
|
||||
package users
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/auth"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/db_handler/mongo"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/dbhandler"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/mail"
|
||||
"git.acooldomain.co/server-manager/backend-kubernetes-go/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type Connection struct {
|
||||
connection *dbhandler.UsersDBHandler
|
||||
config *models.GlobalConfig
|
||||
userPassAuthHandler dbhandler.UserPassAuthanticationDbHandler
|
||||
tokenHandler dbhandler.InviteTokenDbHandler
|
||||
mailClient mail.MailClient
|
||||
config *models.GlobalConfig
|
||||
}
|
||||
|
||||
type UserResponse struct {
|
||||
Username string
|
||||
Email string
|
||||
Permissions models.Permission
|
||||
Username string `json:"Username"`
|
||||
Email string `json:"Email"`
|
||||
Permissions models.Permission `json:"Permissions"`
|
||||
}
|
||||
|
||||
func (con Connection) GetUsers(c *gin.Context) {
|
||||
users, err := (*con.connection).ListUsers()
|
||||
func (con Connection) GetUsers(ctx *gin.Context) {
|
||||
users, err := con.userPassAuthHandler.ListUsers(ctx)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, users)
|
||||
}
|
||||
|
||||
func (con Connection) GetUser(c *gin.Context) {
|
||||
claims, exists := c.Get("claims")
|
||||
if !exists {
|
||||
c.AbortWithStatus(505)
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusOK, UserResponse{
|
||||
ctx.JSON(http.StatusOK, users)
|
||||
}
|
||||
|
||||
func (con Connection) GetUser(ctx *gin.Context) {
|
||||
claims, exists := ctx.Get("claims")
|
||||
if !exists {
|
||||
ctx.AbortWithStatus(403)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.IndentedJSON(http.StatusOK, UserResponse{
|
||||
Username: claims.(*auth.AuthClaims).Username,
|
||||
Permissions: claims.(*auth.AuthClaims).Permissions,
|
||||
})
|
||||
@ -54,63 +54,87 @@ type InviteUser struct {
|
||||
Permissions models.Permission `json:"Permissions"`
|
||||
}
|
||||
|
||||
func (con Connection) InviteUser(c *gin.Context) {
|
||||
func (con Connection) InviteUser(ctx *gin.Context) {
|
||||
var request InviteUser
|
||||
json.NewDecoder(c.Request.Body).Decode(&request)
|
||||
token := uuid.NewString()
|
||||
json.NewDecoder(ctx.Request.Body).Decode(&request)
|
||||
|
||||
token, err := con.tokenHandler.SaveInviteToken(ctx, request.Email, request.Permissions)
|
||||
|
||||
err := mail.SendMail(request.Email, "You've been invited to join", "please open this link https://games.acooldomain.co/signup?token="+token)
|
||||
if err != nil {
|
||||
c.AbortWithError(500, err)
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
con.connection.Database("Backend").Collection("Tokens").InsertOne(context.TODO(), auth.InviteToken{
|
||||
Email: request.Email,
|
||||
Permissions: request.Permissions,
|
||||
Token: token,
|
||||
})
|
||||
c.JSON(200, "OK")
|
||||
|
||||
err = con.mailClient.SendMail(request.Email, "You've been invited to join", "please open this link https://games.acooldomain.co/signup?token="+token)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(200, "OK")
|
||||
}
|
||||
|
||||
type SetUserPermissionsRequest struct {
|
||||
Permissions models.Permission
|
||||
Permissions models.Permission `json:"Permissions"`
|
||||
}
|
||||
|
||||
func (con Connection) SetUserPermissions(c *gin.Context) {
|
||||
func (con Connection) SetUserPermissions(ctx *gin.Context) {
|
||||
var request SetUserPermissionsRequest
|
||||
json.NewDecoder(c.Request.Body).Decode(&request)
|
||||
username := c.Param("user_id")
|
||||
json.NewDecoder(ctx.Request.Body).Decode(&request)
|
||||
username := ctx.Param("user_id")
|
||||
|
||||
_, err := con.connection.Database("Backend").Collection("Users").UpdateOne(
|
||||
context.TODO(),
|
||||
bson.D{{Key: "Username", Value: username}},
|
||||
bson.D{{Key: "$set", Value: bson.D{{Key: "Permissions", Value: request.Permissions}}}},
|
||||
)
|
||||
err := con.userPassAuthHandler.SetPermissions(ctx, username, request.Permissions)
|
||||
if err != nil {
|
||||
c.AbortWithError(500, err)
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, "OK")
|
||||
ctx.JSON(200, "OK")
|
||||
}
|
||||
|
||||
func (con Connection) DeleteUser(c *gin.Context) {
|
||||
username := c.Param("user_id")
|
||||
func (con Connection) DeleteUser(ctx *gin.Context) {
|
||||
username := ctx.Param("user_id")
|
||||
|
||||
err := con.userPassAuthHandler.RemoveUser(ctx, username)
|
||||
|
||||
_, err := con.connection.Database("Backend").Collection("Users").DeleteOne(
|
||||
context.TODO(),
|
||||
bson.D{{Key: "Username", Value: username}},
|
||||
)
|
||||
if err != nil {
|
||||
c.AbortWithError(500, err)
|
||||
ctx.AbortWithError(500, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, "OK")
|
||||
ctx.JSON(200, "OK")
|
||||
}
|
||||
|
||||
func LoadGroup(group *gin.RouterGroup, client *mongo.Client, config models.GlobalConfig) {
|
||||
connection := Connection{connection: client}
|
||||
func LoadGroup(group *gin.RouterGroup, config models.GlobalConfig) {
|
||||
var userAuthHandler dbhandler.UserPassAuthanticationDbHandler
|
||||
var inviteHandler dbhandler.InviteTokenDbHandler
|
||||
var mailClient mail.MailClient
|
||||
|
||||
var err error
|
||||
|
||||
if config.Authentication.UserPass.Type == models.MONGO {
|
||||
userAuthHandler, err = mongo.NewUserPassAuthHandler(*config.Authentication.UserPass.Mongo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.Authentication.UserPass.InviteTokenDatabase.Type == models.MONGO {
|
||||
inviteHandler, err = mongo.NewInviteTokenDbHandler(*config.Authentication.UserPass.Mongo)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
mailClient = *mail.NewMailClient(config.Email)
|
||||
|
||||
connection := Connection{
|
||||
userPassAuthHandler: userAuthHandler,
|
||||
tokenHandler: inviteHandler,
|
||||
mailClient: mailClient,
|
||||
config: &config,
|
||||
}
|
||||
|
||||
group.GET("", auth.AuthorizedTo(0), connection.GetUsers)
|
||||
group.GET("/@me", auth.AuthorizedTo(0), connection.GetUser)
|
||||
group.POST("", auth.AuthorizedTo(models.Admin), connection.InviteUser)
|
||||
|
Loading…
x
Reference in New Issue
Block a user