Tweaked project structure (#88)

This commit is contained in:
Thomas Miceli 2023-09-03 00:30:57 +02:00 committed by GitHub
parent 25316d7bf2
commit a7b346d8df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 122 additions and 116 deletions

2
.gitattributes vendored
View file

@ -1,2 +1,4 @@
templates/**/* linguist-vendored templates/**/* linguist-vendored
public/**/*.css linguist-vendored public/**/*.css linguist-vendored
public/**/*.scss linguist-vendored
*.config.js linguist-vendored

View file

@ -3,7 +3,7 @@
# Specify the name of your Go binary output # Specify the name of your Go binary output
BINARY_NAME := opengist BINARY_NAME := opengist
all: install build all: clean install build
install: install:
@echo "Installing NPM dependencies..." @echo "Installing NPM dependencies..."

View file

@ -1,8 +0,0 @@
//go:build fs_embed
package main
import "embed"
//go:embed templates/*/*.html public/manifest.json public/assets/*.js public/assets/*.css public/assets/*.svg public/assets/*.png
var dirFS embed.FS

View file

@ -1,7 +0,0 @@
//go:build !fs_embed
package main
import "os"
var dirFS = os.DirFS(".")

View file

@ -1,4 +1,4 @@
package models package db
import ( import (
"gorm.io/gorm/clause" "gorm.io/gorm/clause"

View file

@ -1,4 +1,4 @@
package models package db
import ( import (
"errors" "errors"

View file

@ -1,4 +1,4 @@
package models package db
import ( import (
"github.com/thomiceli/opengist/internal/git" "github.com/thomiceli/opengist/internal/git"

View file

@ -1,4 +1,4 @@
package models package db
import ( import (
"fmt" "fmt"

View file

@ -1,4 +1,4 @@
package models package db
import ( import (
"crypto/sha256" "crypto/sha256"

View file

@ -1,4 +1,4 @@
package models package db
import ( import (
"gorm.io/gorm" "gorm.io/gorm"

View file

@ -3,8 +3,8 @@ package ssh
import ( import (
"errors" "errors"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/db"
"github.com/thomiceli/opengist/internal/git" "github.com/thomiceli/opengist/internal/git"
"github.com/thomiceli/opengist/internal/models"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"gorm.io/gorm" "gorm.io/gorm"
"io" "io"
@ -32,12 +32,12 @@ func runGitCommand(ch ssh.Channel, gitCmd string, key string, ip string) error {
userName := strings.ToLower(repoFields[0]) userName := strings.ToLower(repoFields[0])
gistName := strings.TrimSuffix(strings.ToLower(repoFields[1]), ".git") gistName := strings.TrimSuffix(strings.ToLower(repoFields[1]), ".git")
gist, err := models.GetGist(userName, gistName) gist, err := db.GetGist(userName, gistName)
if err != nil { if err != nil {
return errors.New("gist not found") return errors.New("gist not found")
} }
requireLogin, err := models.GetSetting(models.SettingRequireLogin) requireLogin, err := db.GetSetting(db.SettingRequireLogin)
if err != nil { if err != nil {
return errors.New("internal server error") return errors.New("internal server error")
} }
@ -52,7 +52,7 @@ func runGitCommand(ch ssh.Channel, gitCmd string, key string, ip string) error {
gist.ID == 0 || gist.ID == 0 ||
requireLogin == "1" { requireLogin == "1" {
pubKey, err := models.SSHKeyExistsForUser(key, gist.UserID) pubKey, err := db.SSHKeyExistsForUser(key, gist.UserID)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
log.Warn().Msg("Invalid SSH authentication attempt from " + ip) log.Warn().Msg("Invalid SSH authentication attempt from " + ip)
@ -61,7 +61,7 @@ func runGitCommand(ch ssh.Channel, gitCmd string, key string, ip string) error {
errorSsh("Failed to get user by SSH key id", err) errorSsh("Failed to get user by SSH key id", err)
return errors.New("internal server error") return errors.New("internal server error")
} }
_ = models.SSHKeyLastUsedNow(pubKey.Content) _ = db.SSHKeyLastUsedNow(pubKey.Content)
} }
repositoryPath := git.RepositoryPath(gist.User.Username, gist.Uuid) repositoryPath := git.RepositoryPath(gist.User.Username, gist.Uuid)

View file

@ -4,7 +4,7 @@ import (
"errors" "errors"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/config" "github.com/thomiceli/opengist/internal/config"
"github.com/thomiceli/opengist/internal/models" "github.com/thomiceli/opengist/internal/db"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"gorm.io/gorm" "gorm.io/gorm"
"io" "io"
@ -24,7 +24,7 @@ func Start() {
sshConfig := &ssh.ServerConfig{ sshConfig := &ssh.ServerConfig{
PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
strKey := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(key))) strKey := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(key)))
_, err := models.SSHKeyDoesExists(strKey) _, err := db.SSHKeyDoesExists(strKey)
if err != nil { if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) { if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err return nil, err

View file

@ -4,8 +4,8 @@ import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/config" "github.com/thomiceli/opengist/internal/config"
"github.com/thomiceli/opengist/internal/db"
"github.com/thomiceli/opengist/internal/git" "github.com/thomiceli/opengist/internal/git"
"github.com/thomiceli/opengist/internal/models"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -31,19 +31,19 @@ func adminIndex(ctx echo.Context) error {
} }
setData(ctx, "gitVersion", gitVersion) setData(ctx, "gitVersion", gitVersion)
countUsers, err := models.CountAll(&models.User{}) countUsers, err := db.CountAll(&db.User{})
if err != nil { if err != nil {
return errorRes(500, "Cannot count users", err) return errorRes(500, "Cannot count users", err)
} }
setData(ctx, "countUsers", countUsers) setData(ctx, "countUsers", countUsers)
countGists, err := models.CountAll(&models.Gist{}) countGists, err := db.CountAll(&db.Gist{})
if err != nil { if err != nil {
return errorRes(500, "Cannot count gists", err) return errorRes(500, "Cannot count gists", err)
} }
setData(ctx, "countGists", countGists) setData(ctx, "countGists", countGists)
countKeys, err := models.CountAll(&models.SSHKey{}) countKeys, err := db.CountAll(&db.SSHKey{})
if err != nil { if err != nil {
return errorRes(500, "Cannot count SSH keys", err) return errorRes(500, "Cannot count SSH keys", err)
} }
@ -60,9 +60,9 @@ func adminUsers(ctx echo.Context) error {
setData(ctx, "adminHeaderPage", "users") setData(ctx, "adminHeaderPage", "users")
pageInt := getPage(ctx) pageInt := getPage(ctx)
var data []*models.User var data []*db.User
var err error var err error
if data, err = models.GetAllUsers(pageInt - 1); err != nil { if data, err = db.GetAllUsers(pageInt - 1); err != nil {
return errorRes(500, "Cannot get users", err) return errorRes(500, "Cannot get users", err)
} }
@ -79,9 +79,9 @@ func adminGists(ctx echo.Context) error {
setData(ctx, "adminHeaderPage", "gists") setData(ctx, "adminHeaderPage", "gists")
pageInt := getPage(ctx) pageInt := getPage(ctx)
var data []*models.Gist var data []*db.Gist
var err error var err error
if data, err = models.GetAllGists(pageInt - 1); err != nil { if data, err = db.GetAllGists(pageInt - 1); err != nil {
return errorRes(500, "Cannot get gists", err) return errorRes(500, "Cannot get gists", err)
} }
@ -94,7 +94,7 @@ func adminGists(ctx echo.Context) error {
func adminUserDelete(ctx echo.Context) error { func adminUserDelete(ctx echo.Context) error {
userId, _ := strconv.ParseUint(ctx.Param("user"), 10, 64) userId, _ := strconv.ParseUint(ctx.Param("user"), 10, 64)
user, err := models.GetUserById(uint(userId)) user, err := db.GetUserById(uint(userId))
if err != nil { if err != nil {
return errorRes(500, "Cannot retrieve user", err) return errorRes(500, "Cannot retrieve user", err)
} }
@ -108,7 +108,7 @@ func adminUserDelete(ctx echo.Context) error {
} }
func adminGistDelete(ctx echo.Context) error { func adminGistDelete(ctx echo.Context) error {
gist, err := models.GetGistByID(ctx.Param("gist")) gist, err := db.GetGistByID(ctx.Param("gist"))
if err != nil { if err != nil {
return errorRes(500, "Cannot retrieve gist", err) return errorRes(500, "Cannot retrieve gist", err)
} }
@ -133,7 +133,7 @@ func adminSyncReposFromFS(ctx echo.Context) error {
} }
syncReposFromFS = true syncReposFromFS = true
gists, err := models.GetAllGistsRows() gists, err := db.GetAllGistsRows()
if err != nil { if err != nil {
log.Error().Err(err).Msg("Cannot get gists") log.Error().Err(err).Msg("Cannot get gists")
syncReposFromFS = false syncReposFromFS = false
@ -170,7 +170,7 @@ func adminSyncReposFromDB(ctx echo.Context) error {
for _, e := range entries { for _, e := range entries {
path := strings.Split(e, string(os.PathSeparator)) path := strings.Split(e, string(os.PathSeparator))
gist, _ := models.GetGist(path[len(path)-2], path[len(path)-1]) gist, _ := db.GetGist(path[len(path)-2], path[len(path)-1])
if gist.ID == 0 { if gist.ID == 0 {
if err := git.DeleteRepository(path[len(path)-2], path[len(path)-1]); err != nil { if err := git.DeleteRepository(path[len(path)-2], path[len(path)-1]); err != nil {
@ -197,7 +197,7 @@ func adminSetConfig(ctx echo.Context) error {
key := ctx.FormValue("key") key := ctx.FormValue("key")
value := ctx.FormValue("value") value := ctx.FormValue("value")
if err := models.UpdateSetting(key, value); err != nil { if err := db.UpdateSetting(key, value); err != nil {
return errorRes(500, "Cannot set setting", err) return errorRes(500, "Cannot set setting", err)
} }

View file

@ -18,7 +18,7 @@ import (
"github.com/markbates/goth/providers/github" "github.com/markbates/goth/providers/github"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/config" "github.com/thomiceli/opengist/internal/config"
"github.com/thomiceli/opengist/internal/models" "github.com/thomiceli/opengist/internal/db"
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/language" "golang.org/x/text/language"
"gorm.io/gorm" "gorm.io/gorm"
@ -47,7 +47,7 @@ func processRegister(ctx echo.Context) error {
sess := getSession(ctx) sess := getSession(ctx)
dto := new(models.UserDTO) dto := new(db.UserDTO)
if err := ctx.Bind(dto); err != nil { if err := ctx.Bind(dto); err != nil {
return errorRes(400, "Cannot bind data", err) return errorRes(400, "Cannot bind data", err)
} }
@ -57,7 +57,7 @@ func processRegister(ctx echo.Context) error {
return html(ctx, "auth_form.html") return html(ctx, "auth_form.html")
} }
if exists, err := models.UserExists(dto.Username); err != nil || exists { if exists, err := db.UserExists(dto.Username); err != nil || exists {
addFlash(ctx, "Username already exists", "error") addFlash(ctx, "Username already exists", "error")
return html(ctx, "auth_form.html") return html(ctx, "auth_form.html")
} }
@ -101,15 +101,15 @@ func processLogin(ctx echo.Context) error {
var err error var err error
sess := getSession(ctx) sess := getSession(ctx)
dto := &models.UserDTO{} dto := &db.UserDTO{}
if err = ctx.Bind(dto); err != nil { if err = ctx.Bind(dto); err != nil {
return errorRes(400, "Cannot bind data", err) return errorRes(400, "Cannot bind data", err)
} }
password := dto.Password password := dto.Password
var user *models.User var user *db.User
if user, err = models.GetUserByUsername(dto.Username); err != nil { if user, err = db.GetUserByUsername(dto.Username); err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) { if !errors.Is(err, gorm.ErrRecordNotFound) {
return errorRes(500, "Cannot get user", err) return errorRes(500, "Cannot get user", err)
} }
@ -161,7 +161,7 @@ func oauthCallback(ctx echo.Context) error {
} }
// if user is not in database, create it // if user is not in database, create it
userDB, err := models.GetUserByProvider(user.UserID, user.Provider) userDB, err := db.GetUserByProvider(user.UserID, user.Provider)
if err != nil { if err != nil {
if getData(ctx, "DisableSignup") == true { if getData(ctx, "DisableSignup") == true {
return errorRes(403, "Signing up is disabled", nil) return errorRes(403, "Signing up is disabled", nil)
@ -171,7 +171,7 @@ func oauthCallback(ctx echo.Context) error {
return errorRes(500, "Cannot get user", err) return errorRes(500, "Cannot get user", err)
} }
userDB = &models.User{ userDB = &db.User{
Username: user.NickName, Username: user.NickName,
Email: user.Email, Email: user.Email,
MD5Hash: fmt.Sprintf("%x", md5.Sum([]byte(strings.ToLower(strings.TrimSpace(user.Email))))), MD5Hash: fmt.Sprintf("%x", md5.Sum([]byte(strings.ToLower(strings.TrimSpace(user.Email))))),
@ -188,7 +188,7 @@ func oauthCallback(ctx echo.Context) error {
} }
if err = userDB.Create(); err != nil { if err = userDB.Create(); err != nil {
if models.IsUniqueConstraintViolation(err) { if db.IsUniqueConstraintViolation(err) {
addFlash(ctx, "Username "+user.NickName+" already exists in Opengist", "error") addFlash(ctx, "Username "+user.NickName+" already exists in Opengist", "error")
return redirect(ctx, "/login") return redirect(ctx, "/login")
} }
@ -224,7 +224,7 @@ func oauthCallback(ctx echo.Context) error {
keys = keys[:len(keys)-1] keys = keys[:len(keys)-1]
} }
for _, key := range keys { for _, key := range keys {
sshKey := models.SSHKey{ sshKey := db.SSHKey{
Title: "Added from " + user.Provider, Title: "Added from " + user.Provider,
Content: key, Content: key,
User: *userDB, User: *userDB,

View file

@ -7,7 +7,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/thomiceli/opengist/internal/config" "github.com/thomiceli/opengist/internal/config"
"github.com/thomiceli/opengist/internal/models" "github.com/thomiceli/opengist/internal/db"
"gorm.io/gorm" "gorm.io/gorm"
"html/template" "html/template"
"net/url" "net/url"
@ -23,7 +23,7 @@ func gistInit(next echo.HandlerFunc) echo.HandlerFunc {
gistName = strings.TrimSuffix(gistName, ".git") gistName = strings.TrimSuffix(gistName, ".git")
gist, err := models.GetGist(userName, gistName) gist, err := db.GetGist(userName, gistName)
if err != nil { if err != nil {
return notFound("Gist not found") return notFound("Gist not found")
} }
@ -97,7 +97,7 @@ func gistSoftInit(next echo.HandlerFunc) echo.HandlerFunc {
gistName = strings.TrimSuffix(gistName, ".git") gistName = strings.TrimSuffix(gistName, ".git")
gist, _ := models.GetGist(userName, gistName) gist, _ := db.GetGist(userName, gistName)
setData(ctx, "gist", gist) setData(ctx, "gist", gist)
return next(ctx) return next(ctx)
@ -128,7 +128,7 @@ func allGists(ctx echo.Context) error {
setData(ctx, "sort", sort) setData(ctx, "sort", sort)
setData(ctx, "order", orderText) setData(ctx, "order", orderText)
var gists []*models.Gist var gists []*db.Gist
var currentUserId uint var currentUserId uint
if userLogged != nil { if userLogged != nil {
currentUserId = userLogged.ID currentUserId = userLogged.ID
@ -144,12 +144,12 @@ func allGists(ctx echo.Context) error {
setData(ctx, "searchQuery", ctx.QueryParam("q")) setData(ctx, "searchQuery", ctx.QueryParam("q"))
setData(ctx, "searchQueryUrl", template.URL("&q="+ctx.QueryParam("q"))) setData(ctx, "searchQueryUrl", template.URL("&q="+ctx.QueryParam("q")))
urlPage = "search" urlPage = "search"
gists, err = models.GetAllGistsFromSearch(currentUserId, ctx.QueryParam("q"), pageInt-1, sort, order) gists, err = db.GetAllGistsFromSearch(currentUserId, ctx.QueryParam("q"), pageInt-1, sort, order)
} else if strings.HasSuffix(urlctx, "all") { } else if strings.HasSuffix(urlctx, "all") {
setData(ctx, "htmlTitle", "All gists") setData(ctx, "htmlTitle", "All gists")
setData(ctx, "mode", "all") setData(ctx, "mode", "all")
urlPage = "all" urlPage = "all"
gists, err = models.GetAllGistsForCurrentUser(currentUserId, pageInt-1, sort, order) gists, err = db.GetAllGistsForCurrentUser(currentUserId, pageInt-1, sort, order)
} }
} else { } else {
liked := false liked := false
@ -165,9 +165,9 @@ func allGists(ctx echo.Context) error {
return errorRes(500, "Error matching regexp", err) return errorRes(500, "Error matching regexp", err)
} }
var fromUser *models.User var fromUser *db.User
fromUser, err = models.GetUserByUsername(fromUserStr) fromUser, err = db.GetUserByUsername(fromUserStr)
if err != nil { if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return notFound("User not found") return notFound("User not found")
@ -176,19 +176,19 @@ func allGists(ctx echo.Context) error {
} }
setData(ctx, "fromUser", fromUser) setData(ctx, "fromUser", fromUser)
if countFromUser, err := models.CountAllGistsFromUser(fromUser.ID, currentUserId); err != nil { if countFromUser, err := db.CountAllGistsFromUser(fromUser.ID, currentUserId); err != nil {
return errorRes(500, "Error counting gists", err) return errorRes(500, "Error counting gists", err)
} else { } else {
setData(ctx, "countFromUser", countFromUser) setData(ctx, "countFromUser", countFromUser)
} }
if countLiked, err := models.CountAllGistsLikedByUser(fromUser.ID, currentUserId); err != nil { if countLiked, err := db.CountAllGistsLikedByUser(fromUser.ID, currentUserId); err != nil {
return errorRes(500, "Error counting liked gists", err) return errorRes(500, "Error counting liked gists", err)
} else { } else {
setData(ctx, "countLiked", countLiked) setData(ctx, "countLiked", countLiked)
} }
if countForked, err := models.CountAllGistsForkedByUser(fromUser.ID, currentUserId); err != nil { if countForked, err := db.CountAllGistsForkedByUser(fromUser.ID, currentUserId); err != nil {
return errorRes(500, "Error counting forked gists", err) return errorRes(500, "Error counting forked gists", err)
} else { } else {
setData(ctx, "countForked", countForked) setData(ctx, "countForked", countForked)
@ -198,17 +198,17 @@ func allGists(ctx echo.Context) error {
urlPage = fromUserStr + "/liked" urlPage = fromUserStr + "/liked"
setData(ctx, "htmlTitle", "All gists liked by "+fromUserStr) setData(ctx, "htmlTitle", "All gists liked by "+fromUserStr)
setData(ctx, "mode", "liked") setData(ctx, "mode", "liked")
gists, err = models.GetAllGistsLikedByUser(fromUser.ID, currentUserId, pageInt-1, sort, order) gists, err = db.GetAllGistsLikedByUser(fromUser.ID, currentUserId, pageInt-1, sort, order)
} else if forked { } else if forked {
urlPage = fromUserStr + "/forked" urlPage = fromUserStr + "/forked"
setData(ctx, "htmlTitle", "All gists forked by "+fromUserStr) setData(ctx, "htmlTitle", "All gists forked by "+fromUserStr)
setData(ctx, "mode", "forked") setData(ctx, "mode", "forked")
gists, err = models.GetAllGistsForkedByUser(fromUser.ID, currentUserId, pageInt-1, sort, order) gists, err = db.GetAllGistsForkedByUser(fromUser.ID, currentUserId, pageInt-1, sort, order)
} else { } else {
urlPage = fromUserStr urlPage = fromUserStr
setData(ctx, "htmlTitle", "All gists from "+fromUserStr) setData(ctx, "htmlTitle", "All gists from "+fromUserStr)
setData(ctx, "mode", "fromUser") setData(ctx, "mode", "fromUser")
gists, err = models.GetAllGistsFromUser(fromUser.ID, currentUserId, pageInt-1, sort, order) gists, err = db.GetAllGistsFromUser(fromUser.ID, currentUserId, pageInt-1, sort, order)
} }
} }
@ -225,7 +225,7 @@ func allGists(ctx echo.Context) error {
} }
func gistIndex(ctx echo.Context) error { func gistIndex(ctx echo.Context) error {
gist := getData(ctx, "gist").(*models.Gist) gist := getData(ctx, "gist").(*db.Gist)
revision := ctx.Param("revision") revision := ctx.Param("revision")
if revision == "" { if revision == "" {
@ -250,7 +250,7 @@ func gistIndex(ctx echo.Context) error {
} }
func revisions(ctx echo.Context) error { func revisions(ctx echo.Context) error {
gist := getData(ctx, "gist").(*models.Gist) gist := getData(ctx, "gist").(*db.Gist)
userName := gist.User.Username userName := gist.User.Username
gistName := gist.Uuid gistName := gist.Uuid
@ -273,7 +273,7 @@ func revisions(ctx echo.Context) error {
emailsSet[strings.ToLower(commit.AuthorEmail)] = struct{}{} emailsSet[strings.ToLower(commit.AuthorEmail)] = struct{}{}
} }
emailsUsers, err := models.GetUsersFromEmails(emailsSet) emailsUsers, err := db.GetUsersFromEmails(emailsSet)
if err != nil { if err != nil {
return errorRes(500, "Error fetching users emails", err) return errorRes(500, "Error fetching users emails", err)
} }
@ -302,13 +302,13 @@ func processCreate(ctx echo.Context) error {
return errorRes(400, "Bad request", err) return errorRes(400, "Bad request", err)
} }
dto := new(models.GistDTO) dto := new(db.GistDTO)
var gist *models.Gist var gist *db.Gist
if isCreate { if isCreate {
setData(ctx, "htmlTitle", "Create a new gist") setData(ctx, "htmlTitle", "Create a new gist")
} else { } else {
gist = getData(ctx, "gist").(*models.Gist) gist = getData(ctx, "gist").(*db.Gist)
setData(ctx, "htmlTitle", "Edit "+gist.Title) setData(ctx, "htmlTitle", "Edit "+gist.Title)
} }
@ -316,7 +316,7 @@ func processCreate(ctx echo.Context) error {
return errorRes(400, "Cannot bind data", err) return errorRes(400, "Cannot bind data", err)
} }
dto.Files = make([]models.FileDTO, 0) dto.Files = make([]db.FileDTO, 0)
fileCounter := 0 fileCounter := 0
for i := 0; i < len(ctx.Request().PostForm["content"]); i++ { for i := 0; i < len(ctx.Request().PostForm["content"]); i++ {
name := ctx.Request().PostForm["name"][i] name := ctx.Request().PostForm["name"][i]
@ -332,7 +332,7 @@ func processCreate(ctx echo.Context) error {
return errorRes(400, "Invalid character unescaped", err) return errorRes(400, "Invalid character unescaped", err)
} }
dto.Files = append(dto.Files, models.FileDTO{ dto.Files = append(dto.Files, db.FileDTO{
Filename: strings.Trim(name, " "), Filename: strings.Trim(name, " "),
Content: escapedValue, Content: escapedValue,
}) })
@ -414,7 +414,7 @@ func processCreate(ctx echo.Context) error {
} }
func toggleVisibility(ctx echo.Context) error { func toggleVisibility(ctx echo.Context) error {
var gist = getData(ctx, "gist").(*models.Gist) var gist = getData(ctx, "gist").(*db.Gist)
gist.Private = (gist.Private + 1) % 3 gist.Private = (gist.Private + 1) % 3
if err := gist.Update(); err != nil { if err := gist.Update(); err != nil {
@ -426,7 +426,7 @@ func toggleVisibility(ctx echo.Context) error {
} }
func deleteGist(ctx echo.Context) error { func deleteGist(ctx echo.Context) error {
var gist = getData(ctx, "gist").(*models.Gist) var gist = getData(ctx, "gist").(*db.Gist)
err := gist.DeleteRepository() err := gist.DeleteRepository()
if err != nil { if err != nil {
@ -442,7 +442,7 @@ func deleteGist(ctx echo.Context) error {
} }
func like(ctx echo.Context) error { func like(ctx echo.Context) error {
var gist = getData(ctx, "gist").(*models.Gist) var gist = getData(ctx, "gist").(*db.Gist)
currentUser := getUserLogged(ctx) currentUser := getUserLogged(ctx)
hasLiked, err := currentUser.HasLiked(gist) hasLiked, err := currentUser.HasLiked(gist)
@ -468,7 +468,7 @@ func like(ctx echo.Context) error {
} }
func fork(ctx echo.Context) error { func fork(ctx echo.Context) error {
var gist = getData(ctx, "gist").(*models.Gist) var gist = getData(ctx, "gist").(*db.Gist)
currentUser := getUserLogged(ctx) currentUser := getUserLogged(ctx)
alreadyForked, err := gist.GetForkParent(currentUser) alreadyForked, err := gist.GetForkParent(currentUser)
@ -490,7 +490,7 @@ func fork(ctx echo.Context) error {
return errorRes(500, "Error creating an UUID", err) return errorRes(500, "Error creating an UUID", err)
} }
newGist := &models.Gist{ newGist := &db.Gist{
Uuid: strings.Replace(uuidGist.String(), "-", "", -1), Uuid: strings.Replace(uuidGist.String(), "-", "", -1),
Title: gist.Title, Title: gist.Title,
Preview: gist.Preview, Preview: gist.Preview,
@ -519,7 +519,7 @@ func fork(ctx echo.Context) error {
} }
func rawFile(ctx echo.Context) error { func rawFile(ctx echo.Context) error {
gist := getData(ctx, "gist").(*models.Gist) gist := getData(ctx, "gist").(*db.Gist)
file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false) file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false)
if err != nil { if err != nil {
@ -534,7 +534,7 @@ func rawFile(ctx echo.Context) error {
} }
func downloadFile(ctx echo.Context) error { func downloadFile(ctx echo.Context) error {
gist := getData(ctx, "gist").(*models.Gist) gist := getData(ctx, "gist").(*db.Gist)
file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false) file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false)
if err != nil { if err != nil {
@ -558,7 +558,7 @@ func downloadFile(ctx echo.Context) error {
} }
func edit(ctx echo.Context) error { func edit(ctx echo.Context) error {
var gist = getData(ctx, "gist").(*models.Gist) var gist = getData(ctx, "gist").(*db.Gist)
files, err := gist.Files("HEAD") files, err := gist.Files("HEAD")
if err != nil { if err != nil {
@ -572,7 +572,7 @@ func edit(ctx echo.Context) error {
} }
func downloadZip(ctx echo.Context) error { func downloadZip(ctx echo.Context) error {
var gist = getData(ctx, "gist").(*models.Gist) var gist = getData(ctx, "gist").(*db.Gist)
var revision = ctx.Param("revision") var revision = ctx.Param("revision")
files, err := gist.Files(revision) files, err := gist.Files(revision)
@ -617,7 +617,7 @@ func downloadZip(ctx echo.Context) error {
} }
func likes(ctx echo.Context) error { func likes(ctx echo.Context) error {
var gist = getData(ctx, "gist").(*models.Gist) var gist = getData(ctx, "gist").(*db.Gist)
pageInt := getPage(ctx) pageInt := getPage(ctx)
@ -636,7 +636,7 @@ func likes(ctx echo.Context) error {
} }
func forks(ctx echo.Context) error { func forks(ctx echo.Context) error {
var gist = getData(ctx, "gist").(*models.Gist) var gist = getData(ctx, "gist").(*db.Gist)
pageInt := getPage(ctx) pageInt := getPage(ctx)
currentUser := getUserLogged(ctx) currentUser := getUserLogged(ctx)

View file

@ -7,8 +7,8 @@ import (
"fmt" "fmt"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/db"
"github.com/thomiceli/opengist/internal/git" "github.com/thomiceli/opengist/internal/git"
"github.com/thomiceli/opengist/internal/models"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
@ -45,7 +45,7 @@ func gitHttp(ctx echo.Context) error {
continue continue
} }
gist := getData(ctx, "gist").(*models.Gist) gist := getData(ctx, "gist").(*db.Gist)
// Shows basic auth if : // Shows basic auth if :
// - user wants to push the gist // - user wants to push the gist
@ -148,7 +148,7 @@ func pack(ctx echo.Context, serviceType string) error {
// updatedAt is updated only if serviceType is receive-pack // updatedAt is updated only if serviceType is receive-pack
if serviceType == "receive-pack" { if serviceType == "receive-pack" {
gist := getData(ctx, "gist").(*models.Gist) gist := getData(ctx, "gist").(*db.Gist)
_ = gist.SetLastActiveNow() _ = gist.SetLastActiveNow()
_ = gist.UpdatePreviewAndCount() _ = gist.UpdatePreviewAndCount()
} }
@ -159,7 +159,7 @@ func infoRefs(ctx echo.Context) error {
noCacheHeaders(ctx) noCacheHeaders(ctx)
var service string var service string
gist := getData(ctx, "gist").(*models.Gist) gist := getData(ctx, "gist").(*db.Gist)
serviceType := ctx.QueryParam("service") serviceType := ctx.QueryParam("service")
if strings.HasPrefix(serviceType, "git-") { if strings.HasPrefix(serviceType, "git-") {

View file

@ -10,11 +10,12 @@ import (
"github.com/markbates/goth/gothic" "github.com/markbates/goth/gothic"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/config" "github.com/thomiceli/opengist/internal/config"
"github.com/thomiceli/opengist/internal/db"
"github.com/thomiceli/opengist/internal/git" "github.com/thomiceli/opengist/internal/git"
"github.com/thomiceli/opengist/internal/models" "github.com/thomiceli/opengist/public"
"github.com/thomiceli/opengist/templates"
"html/template" "html/template"
"io" "io"
"io/fs"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@ -70,7 +71,7 @@ var fm = template.FuncMap{
"slug": func(s string) string { "slug": func(s string) string {
return strings.Trim(re.ReplaceAllString(strings.ToLower(s), "-"), "-") return strings.Trim(re.ReplaceAllString(strings.ToLower(s), "-"), "-")
}, },
"avatarUrl": func(user *models.User, noGravatar bool) string { "avatarUrl": func(user *db.User, noGravatar bool) string {
if user.AvatarURL != "" { if user.AvatarURL != "" {
return user.AvatarURL return user.AvatarURL
} }
@ -104,8 +105,6 @@ var fm = template.FuncMap{
}, },
} }
var EmbedFS fs.FS
type Template struct { type Template struct {
templates *template.Template templates *template.Template
} }
@ -118,8 +117,6 @@ func Start() {
store = sessions.NewCookieStore([]byte("opengist")) store = sessions.NewCookieStore([]byte("opengist"))
gothic.Store = store gothic.Store = store
assetsFS := echo.MustSubFS(EmbedFS, "public/assets")
e := echo.New() e := echo.New()
e.HideBanner = true e.HideBanner = true
e.HidePort = true e.HidePort = true
@ -143,7 +140,7 @@ func Start() {
e.Use(middleware.Secure()) e.Use(middleware.Secure())
e.Renderer = &Template{ e.Renderer = &Template{
templates: template.Must(template.New("t").Funcs(fm).ParseFS(EmbedFS, "templates/*/*.html")), templates: template.Must(template.New("t").Funcs(fm).ParseFS(templates.Files, "*/*.html")),
} }
e.HTTPErrorHandler = func(er error, ctx echo.Context) { e.HTTPErrorHandler = func(er error, ctx echo.Context) {
if err, ok := er.(*echo.HTTPError); ok { if err, ok := er.(*echo.HTTPError); ok {
@ -166,7 +163,7 @@ func Start() {
if !dev { if !dev {
parseManifestEntries() parseManifestEntries()
e.GET("/assets/*", cacheControl(echo.WrapHandler(http.StripPrefix("/assets", http.FileServer(http.FS(assetsFS)))))) e.GET("/assets/*", cacheControl(echo.WrapHandler(http.FileServer(http.FS(public.Files)))))
} }
// Web based routes // Web based routes
@ -285,9 +282,9 @@ func sessionInit(next echo.HandlerFunc) echo.HandlerFunc {
sess := getSession(ctx) sess := getSession(ctx)
if sess.Values["user"] != nil { if sess.Values["user"] != nil {
var err error var err error
var user *models.User var user *db.User
if user, err = models.GetUserById(sess.Values["user"].(uint)); err != nil { if user, err = db.GetUserById(sess.Values["user"].(uint)); err != nil {
sess.Values["user"] = nil sess.Values["user"] = nil
saveSession(sess, ctx) saveSession(sess, ctx)
setData(ctx, "userLogged", nil) setData(ctx, "userLogged", nil)
@ -315,8 +312,8 @@ func writePermission(next echo.HandlerFunc) echo.HandlerFunc {
return func(ctx echo.Context) error { return func(ctx echo.Context) error {
gist := getData(ctx, "gist") gist := getData(ctx, "gist")
user := getUserLogged(ctx) user := getUserLogged(ctx)
if !gist.(*models.Gist).CanWrite(user) { if !gist.(*db.Gist).CanWrite(user) {
return redirect(ctx, "/"+gist.(*models.Gist).User.Username+"/"+gist.(*models.Gist).Uuid) return redirect(ctx, "/"+gist.(*db.Gist).User.Username+"/"+gist.(*db.Gist).Uuid)
} }
return next(ctx) return next(ctx)
} }
@ -377,7 +374,7 @@ type Asset struct {
var manifestEntries map[string]Asset var manifestEntries map[string]Asset
func parseManifestEntries() { func parseManifestEntries() {
file, err := EmbedFS.Open("public/manifest.json") file, err := public.Files.Open("manifest.json")
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Failed to open manifest.json") log.Fatal().Err(err).Msg("Failed to open manifest.json")
} }

View file

@ -4,7 +4,7 @@ import (
"crypto/md5" "crypto/md5"
"fmt" "fmt"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/thomiceli/opengist/internal/models" "github.com/thomiceli/opengist/internal/db"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"strconv" "strconv"
"strings" "strings"
@ -14,7 +14,7 @@ import (
func userSettings(ctx echo.Context) error { func userSettings(ctx echo.Context) error {
user := getUserLogged(ctx) user := getUserLogged(ctx)
keys, err := models.GetSSHKeysByUserID(user.ID) keys, err := db.GetSSHKeysByUserID(user.ID)
if err != nil { if err != nil {
return errorRes(500, "Cannot get SSH keys", err) return errorRes(500, "Cannot get SSH keys", err)
} }
@ -61,7 +61,7 @@ func accountDeleteProcess(ctx echo.Context) error {
func sshKeysProcess(ctx echo.Context) error { func sshKeysProcess(ctx echo.Context) error {
user := getUserLogged(ctx) user := getUserLogged(ctx)
var dto = new(models.SSHKeyDTO) var dto = new(db.SSHKeyDTO)
if err := ctx.Bind(dto); err != nil { if err := ctx.Bind(dto); err != nil {
return errorRes(400, "Cannot bind data", err) return errorRes(400, "Cannot bind data", err)
} }
@ -97,7 +97,7 @@ func sshKeysDelete(ctx echo.Context) error {
return redirect(ctx, "/settings") return redirect(ctx, "/settings")
} }
key, err := models.GetSSHKeyByID(uint(keyId)) key, err := db.GetSSHKeyByID(uint(keyId))
if err != nil || key.UserID != user.ID { if err != nil || key.UserID != user.ID {
return redirect(ctx, "/settings") return redirect(ctx, "/settings")

View file

@ -11,7 +11,7 @@ import (
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/thomiceli/opengist/internal/config" "github.com/thomiceli/opengist/internal/config"
"github.com/thomiceli/opengist/internal/models" "github.com/thomiceli/opengist/internal/db"
"golang.org/x/crypto/argon2" "golang.org/x/crypto/argon2"
"html/template" "html/template"
"net/http" "net/http"
@ -60,10 +60,10 @@ func errorRes(code int, message string, err error) error {
return &echo.HTTPError{Code: code, Message: message, Internal: err} return &echo.HTTPError{Code: code, Message: message, Internal: err}
} }
func getUserLogged(ctx echo.Context) *models.User { func getUserLogged(ctx echo.Context) *db.User {
user := getData(ctx, "userLogged") user := getData(ctx, "userLogged")
if user != nil { if user != nil {
return user.(*models.User) return user.(*db.User)
} }
return nil return nil
} }
@ -110,7 +110,7 @@ func deleteCsrfCookie(ctx echo.Context) {
} }
func loadSettings(ctx echo.Context) error { func loadSettings(ctx echo.Context) error {
settings, err := models.GetSettings() settings, err := db.GetSettings()
if err != nil { if err != nil {
return err return err
} }

View file

@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/config" "github.com/thomiceli/opengist/internal/config"
"github.com/thomiceli/opengist/internal/db"
"github.com/thomiceli/opengist/internal/git" "github.com/thomiceli/opengist/internal/git"
"github.com/thomiceli/opengist/internal/models"
"github.com/thomiceli/opengist/internal/ssh" "github.com/thomiceli/opengist/internal/ssh"
"github.com/thomiceli/opengist/internal/web" "github.com/thomiceli/opengist/internal/web"
"os" "os"
@ -51,11 +51,9 @@ func initialize() {
} }
log.Info().Msg("Database file: " + filepath.Join(homePath, config.C.DBFilename)) log.Info().Msg("Database file: " + filepath.Join(homePath, config.C.DBFilename))
if err := models.Setup(filepath.Join(homePath, config.C.DBFilename)); err != nil { if err := db.Setup(filepath.Join(homePath, config.C.DBFilename)); err != nil {
log.Fatal().Err(err).Msg("Failed to initialize database") log.Fatal().Err(err).Msg("Failed to initialize database")
} }
web.EmbedFS = dirFS
} }
func main() { func main() {

8
public/fs_embed.go Normal file
View file

@ -0,0 +1,8 @@
//go:build fs_embed
package public
import "embed"
//go:embed manifest.json assets/*.js assets/*.css assets/*.svg assets/*.png
var Files embed.FS

7
public/fs_os.go Normal file
View file

@ -0,0 +1,7 @@
//go:build !fs_embed
package public
import "os"
var Files = os.DirFS(".")

View file

@ -1,5 +1,5 @@
import './style.css'; import './style.css';
import './hljs.scss'; import './style.scss';
import './favicon.svg'; import './favicon.svg';
import './default.png'; import './default.png';
import moment from 'moment'; import moment from 'moment';
@ -14,6 +14,7 @@ document.addEventListener('DOMContentLoaded', () => {
e.stopPropagation() e.stopPropagation()
localStorage.theme = 'light'; localStorage.theme = 'light';
themeMenu.classList.toggle('hidden'); themeMenu.classList.toggle('hidden');
// @ts-ignore
checkTheme() checkTheme()
} }
@ -21,6 +22,7 @@ document.addEventListener('DOMContentLoaded', () => {
e.stopPropagation() e.stopPropagation()
localStorage.theme = 'dark'; localStorage.theme = 'dark';
themeMenu.classList.toggle('hidden'); themeMenu.classList.toggle('hidden');
// @ts-ignore
checkTheme() checkTheme()
} }
@ -28,6 +30,7 @@ document.addEventListener('DOMContentLoaded', () => {
e.stopPropagation() e.stopPropagation()
localStorage.removeItem('theme'); localStorage.removeItem('theme');
themeMenu.classList.toggle('hidden'); themeMenu.classList.toggle('hidden');
// @ts-ignore
checkTheme(); checkTheme();
} }

6
templates/fs_embed.go vendored Normal file
View file

@ -0,0 +1,6 @@
package templates
import "embed"
//go:embed */*.html
var Files embed.FS