Use db for queue (#498)
هذا الالتزام موجود في:
@@ -3,16 +3,17 @@ package db
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/glebarez/sqlite"
|
|
||||||
"gorm.io/driver/mysql"
|
|
||||||
"gorm.io/driver/postgres"
|
|
||||||
"gorm.io/gorm/logger"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/glebarez/sqlite"
|
||||||
|
"gorm.io/driver/mysql"
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/thomiceli/opengist/internal/config"
|
"github.com/thomiceli/opengist/internal/config"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -154,7 +155,7 @@ func Setup(dbUri string) error {
|
|||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -613,30 +611,6 @@ func (gist *Gist) TopicsSlice() []string {
|
|||||||
return topics
|
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() {
|
func (gist *Gist) UpdateLanguages() {
|
||||||
languages, err := gist.GetLanguagesFromFiles()
|
languages, err := gist.GetLanguagesFromFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
34
internal/db/gist_init_queue.go
Normal file
34
internal/db/gist_init_queue.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -565,50 +564,6 @@ func DeleteUserDirectory(user string) error {
|
|||||||
return os.RemoveAll(filepath.Join(config.GetHomeDir(), ReposDirectory, user))
|
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 {
|
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)
|
preReceiveDst, err := os.OpenFile(filepath.Join(repositoryPath, "hooks", hook), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0744)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"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"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -19,6 +15,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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/google/uuid"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/thomiceli/opengist/internal/auth"
|
"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)
|
return ctx.ErrorRes(500, "Cannot init repository in database", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gist.SerialiseInitRepository()
|
err = db.AddInitGistToQueue(gist.ID, user.ID)
|
||||||
if err != nil {
|
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)
|
ctx.SetData("gist", gist)
|
||||||
} else {
|
} else {
|
||||||
gist, err = db.DeserialiseInitRepository(user.Username)
|
gist, err = db.GetInitGistInQueueForUser(user.ID)
|
||||||
if err != nil {
|
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)
|
ctx.SetData("gist", gist)
|
||||||
|
|||||||
المرجع في مشكلة جديدة
حظر مستخدم