added more stuff

This commit is contained in:
ACoolName 2024-05-12 00:53:08 +03:00
parent 2e773d3c7e
commit 44d75030aa
20 changed files with 934 additions and 832 deletions

View File

@ -48,7 +48,7 @@ func signToken(token TokenInfo) (string, error) {
} }
func hashPassword(password string) (string, error) { func hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err return string(bytes), err
} }
@ -63,16 +63,19 @@ func AuthorizedTo(requiredPermissions models.Permission) gin.HandlerFunc {
token, err := jwt.ParseWithClaims(authCookie.Value, &AuthClaims{}, func(token *jwt.Token) (interface{}, error) { token, err := jwt.ParseWithClaims(authCookie.Value, &AuthClaims{}, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect: // Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
} }
// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key") // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return hmacSampleSecret, nil return hmacSampleSecret, nil
}) })
if err != nil {
ctx.AbortWithError(403, err)
}
fmt.Println(token.Claims) fmt.Println(token.Claims)
if claims, ok := token.Claims.(*AuthClaims); ok && token.Valid { if claims, ok := token.Claims.(*AuthClaims); ok && token.Valid {
ctx.Set("claims", claims) ctx.Set("claims", claims)
if requiredPermissions&claims.Permissions != requiredPermissions { if requiredPermissions&claims.Permissions != requiredPermissions && models.Admin&claims.Permissions != models.Admin {
ctx.AbortWithStatus(403) ctx.AbortWithStatus(403)
} }
} else { } else {
@ -104,29 +107,32 @@ func (con Connection) signUp(c *gin.Context) {
} }
type SignInRequest struct { type SignInRequest struct {
username string Username string `json:"username"`
password string Password string `json:"password"`
} }
func (con Connection) signIn(c *gin.Context) { func (con Connection) signIn(c *gin.Context) {
type signInRequest struct { var request SignInRequest
username string
password string
}
var request signInRequest
err := json.NewDecoder(c.Request.Body).Decode(&request) err := json.NewDecoder(c.Request.Body).Decode(&request)
if err != nil { if err != nil {
c.AbortWithError(500, err) c.AbortWithError(500, err)
} }
var userItem models.User var userItem models.User
err = con.connection.Database("Backend").Collection("Users").FindOne(context.TODO(), bson.D{{Key: "username", Value: request.username}}).Decode(&userItem) err = con.connection.Database("Backend").Collection("Users").FindOne(context.TODO(), bson.D{{Key: "Username", Value: request.Username}}).Decode(&userItem)
if err != nil { if err != nil {
c.AbortWithError(403, err) c.AbortWithError(403, err)
} }
if hashedPass, err := hashPassword(request.password); err != nil || userItem.HashedPass != hashedPass { err = bcrypt.CompareHashAndPassword([]byte(userItem.HashedPass), []byte(request.Password))
if err != nil {
println(err.Error())
pass, err := hashPassword(request.Password)
if err != nil {
c.AbortWithError(403, err)
}
fmt.Printf("UserPass: %s\nDatabaseHash: %s\nHash %s\n", request.Password, userItem.HashedPass, pass)
c.AbortWithStatus(403) c.AbortWithStatus(403)
} }

1
go.mod
View File

@ -7,6 +7,7 @@ require github.com/gin-gonic/gin v1.9.1
require ( require (
github.com/bytedance/sonic v1.9.1 // indirect github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/docker/docker v26.1.2+incompatible // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-oas/docs v1.1.0 // indirect github.com/go-oas/docs v1.1.0 // indirect

2
go.sum
View File

@ -6,6 +6,8 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhD
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/docker v26.1.2+incompatible h1:UVX5ZOrrfTGZZYEP+ZDq3Xn9PdHNXaSYMFPDumMqG2k=
github.com/docker/docker v26.1.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=

View File

@ -6,13 +6,17 @@ import (
"fmt" "fmt"
"strings" "strings"
"acooldomain.co/backend/auth"
"acooldomain.co/backend/models" "acooldomain.co/backend/models"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/volume" "github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
) )
@ -32,12 +36,66 @@ type ContainerLabels struct {
type VolumeLabels struct { type VolumeLabels struct {
OwnerId string `json:"user_id"` OwnerId string `json:"user_id"`
ImageId string `json:"image_id"` ImageId string `json:"image_id"`
Type string `json:"type"`
} }
type ImageLabels struct { type ImageLabels struct {
Type string `json:"type"` Type string `json:"type"`
} }
func (con Connection) getServerInfo(volume volume.Volume) (*models.ServerInfo, error) {
var volumeLabels VolumeLabels
jsonData, err := json.Marshal(volume.Labels)
if err != nil {
return nil, err
}
json.Unmarshal(jsonData, &volumeLabels)
imageNameAndVersion := strings.Split(volumeLabels.ImageId, ":")
imageName := imageNameAndVersion[0]
imageVersion := imageNameAndVersion[1]
containers, err := con.apiClient.ContainerList(context.Background(), container.ListOptions{
All: true,
Filters: filters.NewArgs(filters.Arg("label", "type=GAME"), filters.Arg("label", fmt.Sprintf("volume_id=%s", volume.Name))),
})
var state bool
var ports []models.Port
if err != nil || len(containers) == 0 {
state = false
ports = nil
} else {
container := containers[0]
state = container.State == "running"
ports = transformContainerPortsToModel(container.Ports)
}
var serverData models.ServerData
con.connection.Database("backend").Collection("servers").FindOne(context.TODO(), bson.D{{Key: "volume_id", Value: volume.Name}}).Decode(&serverData)
serverInfo := models.ServerInfo{
Id: volume.Name,
Image: models.ImageInfo{
Name: imageName,
Version: imageVersion,
},
OwnerId: volumeLabels.OwnerId,
On: state,
Ports: ports,
Nickname: serverData.Nickname,
}
return &serverInfo, nil
}
func (con Connection) getServerInfoFromId(ServerId string) (*models.ServerInfo, error) {
volume, err := con.apiClient.VolumeInspect(context.Background(), ServerId)
if err != nil {
return nil, err
}
return con.getServerInfo(volume)
}
func transformContainerPortsToModel(ports []types.Port) []models.Port { func transformContainerPortsToModel(ports []types.Port) []models.Port {
modelPorts := make([]models.Port, len(ports)) modelPorts := make([]models.Port, len(ports))
for index, port := range ports { for index, port := range ports {
@ -49,6 +107,74 @@ func transformContainerPortsToModel(ports []types.Port) []models.Port {
return modelPorts return modelPorts
} }
func (con Connection) StartServer(ctx *gin.Context) {
serverId := ctx.Param("server_id")
claims, exists := ctx.Get("claims")
if !exists {
ctx.AbortWithStatus(403)
}
// command := ctx.Param("command")
serverInfo, err := con.getServerInfoFromId(serverId)
if err != nil {
ctx.AbortWithError(500, err)
}
if serverInfo.On {
ctx.Status(200)
return
}
imageId := serverInfo.Image.Name + ":" + serverInfo.Image.Version
labels := ContainerLabels{
OwnerId: claims.(*auth.AuthClaims).Username,
ImageId: imageId,
VolumeId: serverInfo.Id,
Type: "GAME",
}
jsonString, err := json.Marshal(labels)
if err != nil {
ctx.AbortWithError(500, err)
}
jsonLabels := make(map[string]string)
json.Unmarshal(jsonString, &jsonLabels)
volumes := make(map[string]struct{})
image, _, err := con.apiClient.ImageInspectWithRaw(context.Background(), imageId)
if err != nil {
ctx.AbortWithError(500, err)
}
response, err := con.apiClient.ContainerCreate(
context.Background(),
&container.Config{
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
Tty: true,
OpenStdin: false,
StdinOnce: false,
Image: imageId,
Volumes: volumes,
Labels: jsonLabels,
},
&container.HostConfig{
AutoRemove: false,
Mounts: []mount.Mount{{Source: serverInfo.Id, Target: image.Config.WorkingDir, Type: "volume"}},
},
&network.NetworkingConfig{},
&v1.Platform{},
"",
)
if err != nil {
ctx.AbortWithError(500, err)
}
ctx.JSON(200, response.ID)
}
func (con Connection) GetServers(ctx *gin.Context) { func (con Connection) GetServers(ctx *gin.Context) {
volumes, err := con.apiClient.VolumeList( volumes, err := con.apiClient.VolumeList(
context.TODO(), context.TODO(),
@ -59,48 +185,14 @@ func (con Connection) GetServers(ctx *gin.Context) {
if err != nil { if err != nil {
ctx.AbortWithError(500, err) ctx.AbortWithError(500, err)
} }
var volumeLabels VolumeLabels
var servers []models.ServerInfo var servers []models.ServerInfo
println("Found %d Containers", len(volumes.Volumes)) println("Found %d Containers", len(volumes.Volumes))
for _, volume := range volumes.Volumes { for _, volume := range volumes.Volumes {
jsonData, err := json.Marshal(volume.Labels) serverInfo, err := con.getServerInfo(*volume)
if err != nil { if err != nil {
continue continue
} }
json.Unmarshal(jsonData, &volumeLabels) servers = append(servers, *serverInfo)
imageNameAndVersion := strings.Split(volumeLabels.ImageId, ":")
imageName := imageNameAndVersion[0]
imageVersion := imageNameAndVersion[1]
containers, err := con.apiClient.ContainerList(context.Background(), container.ListOptions{
All: true,
Filters: filters.NewArgs(filters.Arg("label", "type=GAME"), filters.Arg("label", fmt.Sprintf("volume_id=%s", volume.Name))),
})
var state bool
var ports []models.Port
if err != nil || len(containers) == 0 {
state = false
ports = nil
} else {
container := containers[0]
state = container.State == "running"
ports = container.Ports
}
var serverData models.ServerData
con.connection.Database("backend").Collection("servers").FindOne(context.TODO(), bson.D{{Key: "volume_id", Value: volume.Name}}).Decode(&serverData)
servers = append(servers, models.ServerInfo{
Id: volume.Name,
Image: models.ImageInfo{
Name: imageName,
Version: imageVersion,
},
OwnerId: volumeLabels.OwnerId,
On: state,
Ports: ports,
})
} }
if err != nil { if err != nil {
@ -111,12 +203,13 @@ func (con Connection) GetServers(ctx *gin.Context) {
} }
func LoadGroup(group *gin.RouterGroup, mongo_client *mongo.Client) { func LoadGroup(group *gin.RouterGroup, mongo_client *mongo.Client) {
apiClient, err := client.NewClientWithOpts(client.FromEnv) apiClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil { if err != nil {
panic(err) panic(err)
} }
defer apiClient.Close() defer apiClient.Close()
connection := Connection{connection: mongo_client, apiClient: apiClient} connection := Connection{connection: mongo_client, apiClient: apiClient}
group.Use(auth.AuthorizedTo(models.Create)).POST("/:server_id/start", connection.StartServer)
group.GET("/", connection.GetServers) group.GET("/", connection.GetServers)
} }