diff --git a/internal/db/db.go b/internal/db/db.go index a38cff3..1d3a19b 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -3,16 +3,17 @@ package db import ( "errors" "fmt" - "github.com/glebarez/sqlite" - "gorm.io/driver/mysql" - "gorm.io/driver/postgres" - "gorm.io/gorm/logger" "net/url" "path/filepath" "slices" "strings" "time" + "github.com/glebarez/sqlite" + "gorm.io/driver/mysql" + "gorm.io/driver/postgres" + "gorm.io/gorm/logger" + "github.com/rs/zerolog/log" "github.com/thomiceli/opengist/internal/config" "gorm.io/gorm" @@ -154,7 +155,7 @@ func Setup(dbUri string) error { return err } - if err = db.AutoMigrate(&User{}, &Gist{}, &SSHKey{}, &AdminSetting{}, &Invitation{}, &WebAuthnCredential{}, &TOTP{}, &GistTopic{}, &GistLanguage{}); err != nil { + if err = db.AutoMigrate(&User{}, &Gist{}, &SSHKey{}, &AdminSetting{}, &Invitation{}, &WebAuthnCredential{}, &TOTP{}, &GistTopic{}, &GistLanguage{}, &GistInitQueue{}); err != nil { return err } diff --git a/internal/db/gist.go b/internal/db/gist.go index 1aca1ec..6d44d59 100644 --- a/internal/db/gist.go +++ b/internal/db/gist.go @@ -1,8 +1,6 @@ package db import ( - "bytes" - "encoding/gob" "fmt" "os/exec" "path/filepath" @@ -613,30 +611,6 @@ func (gist *Gist) TopicsSlice() []string { return topics } -func (gist *Gist) SerialiseInitRepository() error { - var gobBuffer bytes.Buffer - encoder := gob.NewEncoder(&gobBuffer) - if err := encoder.Encode(gist); err != nil { - return fmt.Errorf("gob encoding error: %v", err) - } - - return git.SerialiseInitRepository(gist.User.Username, gobBuffer.Bytes()) -} - -func DeserialiseInitRepository(user string) (*Gist, error) { - data, err := git.DeserialiseInitRepository(user) - if err != nil { - return nil, err - } - - var gist Gist - decoder := gob.NewDecoder(bytes.NewReader(data)) - if err := decoder.Decode(&gist); err != nil { - return nil, fmt.Errorf("gob decoding error: %v", err) - } - return &gist, nil -} - func (gist *Gist) UpdateLanguages() { languages, err := gist.GetLanguagesFromFiles() if err != nil { diff --git a/internal/db/gist_init_queue.go b/internal/db/gist_init_queue.go new file mode 100644 index 0000000..d0f8534 --- /dev/null +++ b/internal/db/gist_init_queue.go @@ -0,0 +1,34 @@ +package db + +type GistInitQueue struct { + GistID uint `gorm:"primaryKey"` + Gist Gist `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;foreignKey:GistID"` + UserID uint `gorm:"primaryKey"` + User User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;foreignKey:UserID"` +} + +func GetInitGistInQueueForUser(userID uint) (*Gist, error) { + queue := new(GistInitQueue) + err := db.Preload("Gist").Preload("Gist.User"). + Where("user_id = ?", userID). + Order("gist_id asc"). + First(&queue).Error + if err != nil { + return nil, err + } + + err = db.Delete(&queue).Error + if err != nil { + return nil, err + } + + return &queue.Gist, nil +} + +func AddInitGistToQueue(gistID uint, userID uint) error { + queue := &GistInitQueue{ + GistID: gistID, + UserID: userID, + } + return db.Create(&queue).Error +} diff --git a/internal/git/commands.go b/internal/git/commands.go index 4ea6a44..249443e 100644 --- a/internal/git/commands.go +++ b/internal/git/commands.go @@ -4,7 +4,6 @@ import ( "bufio" "bytes" "context" - "encoding/base64" "fmt" "io" "net/url" @@ -565,50 +564,6 @@ func DeleteUserDirectory(user string) error { return os.RemoveAll(filepath.Join(config.GetHomeDir(), ReposDirectory, user)) } -func SerialiseInitRepository(user string, serialized []byte) error { - userRepositoryPath := UserRepositoriesPath(user) - initPath := filepath.Join(userRepositoryPath, "_init") - - f, err := os.OpenFile(initPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return err - } - defer f.Close() - - encodedData := base64.StdEncoding.EncodeToString(serialized) - _, err = f.Write(append([]byte(encodedData), '\n')) - return err -} - -func DeserialiseInitRepository(user string) ([]byte, error) { - initPath := filepath.Join(UserRepositoriesPath(user), "_init") - - content, err := os.ReadFile(initPath) - if err != nil { - return nil, err - } - - idx := bytes.Index(content, []byte{'\n'}) - if idx == -1 { - return base64.StdEncoding.DecodeString(string(content)) - } - - firstLine := content[:idx] - remaining := content[idx+1:] - - if len(remaining) == 0 { - if err := os.Remove(initPath); err != nil { - return nil, fmt.Errorf("failed to remove file: %v", err) - } - } else { - if err := os.WriteFile(initPath, remaining, 0644); err != nil { - return nil, fmt.Errorf("failed to write remaining content: %v", err) - } - } - - return base64.StdEncoding.DecodeString(string(firstLine)) -} - func createDotGitHookFile(repositoryPath string, hook string, content string) error { preReceiveDst, err := os.OpenFile(filepath.Join(repositoryPath, "hooks", hook), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0744) if err != nil { diff --git a/internal/web/handlers/git/http.go b/internal/web/handlers/git/http.go index 0158ad7..ecde51d 100644 --- a/internal/web/handlers/git/http.go +++ b/internal/web/handlers/git/http.go @@ -6,10 +6,6 @@ import ( "encoding/base64" "errors" "fmt" - "github.com/thomiceli/opengist/internal/auth/ldap" - "github.com/thomiceli/opengist/internal/auth/password" - "github.com/thomiceli/opengist/internal/web/context" - "github.com/thomiceli/opengist/internal/web/handlers" "net/http" "os" "os/exec" @@ -19,6 +15,11 @@ import ( "strings" "time" + "github.com/thomiceli/opengist/internal/auth/ldap" + "github.com/thomiceli/opengist/internal/auth/password" + "github.com/thomiceli/opengist/internal/web/context" + "github.com/thomiceli/opengist/internal/web/handlers" + "github.com/google/uuid" "github.com/rs/zerolog/log" "github.com/thomiceli/opengist/internal/auth" @@ -185,16 +186,15 @@ func GitHttp(ctx *context.Context) error { return ctx.ErrorRes(500, "Cannot init repository in database", err) } - err = gist.SerialiseInitRepository() + err = db.AddInitGistToQueue(gist.ID, user.ID) if err != nil { - return ctx.ErrorRes(500, "Cannot serialise the repository", err) + return ctx.ErrorRes(500, "Cannot add inited gist to the queue", err) } - ctx.SetData("gist", gist) } else { - gist, err = db.DeserialiseInitRepository(user.Username) + gist, err = db.GetInitGistInQueueForUser(user.ID) if err != nil { - return ctx.ErrorRes(500, "Cannot deserialise the repository", err) + return ctx.ErrorRes(500, "Cannot retrieve inited gist from the queue", err) } ctx.SetData("gist", gist)