2023-03-14 15:22:52 +00:00
|
|
|
package web
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/labstack/echo/v4"
|
2023-03-19 00:51:25 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
2023-05-15 19:07:29 +00:00
|
|
|
"github.com/thomiceli/opengist/internal/config"
|
|
|
|
"github.com/thomiceli/opengist/internal/git"
|
|
|
|
"github.com/thomiceli/opengist/internal/models"
|
2023-03-19 00:51:25 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2023-03-14 15:22:52 +00:00
|
|
|
"runtime"
|
2023-03-17 13:56:39 +00:00
|
|
|
"strconv"
|
2023-03-19 00:51:25 +00:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
syncReposFromFS = false
|
|
|
|
syncReposFromDB = false
|
2023-03-14 15:22:52 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func adminIndex(ctx echo.Context) error {
|
|
|
|
setData(ctx, "title", "Admin panel")
|
2023-04-17 20:13:19 +00:00
|
|
|
setData(ctx, "htmlTitle", "Admin panel")
|
2023-03-14 15:22:52 +00:00
|
|
|
setData(ctx, "adminHeaderPage", "index")
|
|
|
|
|
|
|
|
setData(ctx, "opengistVersion", config.OpengistVersion)
|
|
|
|
setData(ctx, "goVersion", runtime.Version())
|
|
|
|
gitVersion, err := git.GetGitVersion()
|
|
|
|
if err != nil {
|
|
|
|
return errorRes(500, "Cannot get git version", err)
|
|
|
|
}
|
|
|
|
setData(ctx, "gitVersion", gitVersion)
|
|
|
|
|
|
|
|
countUsers, err := models.CountAll(&models.User{})
|
|
|
|
if err != nil {
|
|
|
|
return errorRes(500, "Cannot count users", err)
|
|
|
|
}
|
|
|
|
setData(ctx, "countUsers", countUsers)
|
|
|
|
|
|
|
|
countGists, err := models.CountAll(&models.Gist{})
|
|
|
|
if err != nil {
|
|
|
|
return errorRes(500, "Cannot count gists", err)
|
|
|
|
}
|
|
|
|
setData(ctx, "countGists", countGists)
|
|
|
|
|
|
|
|
countKeys, err := models.CountAll(&models.SSHKey{})
|
|
|
|
if err != nil {
|
|
|
|
return errorRes(500, "Cannot count SSH keys", err)
|
|
|
|
}
|
|
|
|
setData(ctx, "countKeys", countKeys)
|
|
|
|
|
2023-03-19 00:51:25 +00:00
|
|
|
setData(ctx, "syncReposFromFS", syncReposFromFS)
|
|
|
|
setData(ctx, "syncReposFromDB", syncReposFromDB)
|
2023-03-14 15:22:52 +00:00
|
|
|
return html(ctx, "admin_index.html")
|
|
|
|
}
|
|
|
|
|
|
|
|
func adminUsers(ctx echo.Context) error {
|
|
|
|
setData(ctx, "title", "Users")
|
2023-04-17 20:13:19 +00:00
|
|
|
setData(ctx, "htmlTitle", "Users - Admin panel")
|
2023-03-14 15:22:52 +00:00
|
|
|
setData(ctx, "adminHeaderPage", "users")
|
|
|
|
pageInt := getPage(ctx)
|
|
|
|
|
|
|
|
var data []*models.User
|
|
|
|
var err error
|
|
|
|
if data, err = models.GetAllUsers(pageInt - 1); err != nil {
|
|
|
|
return errorRes(500, "Cannot get users", err)
|
|
|
|
}
|
|
|
|
|
2023-04-16 22:35:04 +00:00
|
|
|
if err = paginate(ctx, data, pageInt, 10, "data", "admin-panel/users", 1); err != nil {
|
2023-03-14 15:22:52 +00:00
|
|
|
return errorRes(404, "Page not found", nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
return html(ctx, "admin_users.html")
|
|
|
|
}
|
|
|
|
|
|
|
|
func adminGists(ctx echo.Context) error {
|
2023-04-17 20:13:19 +00:00
|
|
|
setData(ctx, "title", "Gists")
|
|
|
|
setData(ctx, "htmlTitle", "Gists - Admin panel")
|
2023-03-14 15:22:52 +00:00
|
|
|
setData(ctx, "adminHeaderPage", "gists")
|
|
|
|
pageInt := getPage(ctx)
|
|
|
|
|
|
|
|
var data []*models.Gist
|
|
|
|
var err error
|
|
|
|
if data, err = models.GetAllGists(pageInt - 1); err != nil {
|
|
|
|
return errorRes(500, "Cannot get gists", err)
|
|
|
|
}
|
|
|
|
|
2023-04-16 22:35:04 +00:00
|
|
|
if err = paginate(ctx, data, pageInt, 10, "data", "admin-panel/gists", 1); err != nil {
|
2023-03-14 15:22:52 +00:00
|
|
|
return errorRes(404, "Page not found", nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
return html(ctx, "admin_gists.html")
|
|
|
|
}
|
|
|
|
|
|
|
|
func adminUserDelete(ctx echo.Context) error {
|
2023-03-17 13:56:39 +00:00
|
|
|
userId, _ := strconv.ParseUint(ctx.Param("user"), 10, 64)
|
|
|
|
user, err := models.GetUserById(uint(userId))
|
|
|
|
if err != nil {
|
|
|
|
return errorRes(500, "Cannot retrieve user", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := user.Delete(); err != nil {
|
2023-03-14 15:22:52 +00:00
|
|
|
return errorRes(500, "Cannot delete this user", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
addFlash(ctx, "User has been deleted", "success")
|
2023-04-16 15:48:21 +00:00
|
|
|
return redirect(ctx, "/admin-panel/users")
|
2023-03-14 15:22:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func adminGistDelete(ctx echo.Context) error {
|
|
|
|
gist, err := models.GetGistByID(ctx.Param("gist"))
|
|
|
|
if err != nil {
|
|
|
|
return errorRes(500, "Cannot retrieve gist", err)
|
|
|
|
}
|
|
|
|
|
2023-03-18 15:18:24 +00:00
|
|
|
if err = gist.DeleteRepository(); err != nil {
|
2023-03-14 15:22:52 +00:00
|
|
|
return errorRes(500, "Cannot delete the repository", err)
|
|
|
|
}
|
|
|
|
|
2023-03-17 13:56:39 +00:00
|
|
|
if err = gist.Delete(); err != nil {
|
2023-03-14 15:22:52 +00:00
|
|
|
return errorRes(500, "Cannot delete this gist", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
addFlash(ctx, "Gist has been deleted", "success")
|
2023-04-16 15:48:21 +00:00
|
|
|
return redirect(ctx, "/admin-panel/gists")
|
2023-03-19 00:51:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func adminSyncReposFromFS(ctx echo.Context) error {
|
|
|
|
addFlash(ctx, "Syncing repositories from filesystem...", "success")
|
|
|
|
go func() {
|
|
|
|
if syncReposFromFS {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
syncReposFromFS = true
|
|
|
|
|
|
|
|
gists, err := models.GetAllGistsRows()
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("Cannot get gists")
|
|
|
|
syncReposFromFS = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for _, gist := range gists {
|
|
|
|
// if repository does not exist, delete gist from database
|
|
|
|
if _, err := os.Stat(git.RepositoryPath(gist.User.Username, gist.Uuid)); err != nil && !os.IsExist(err) {
|
|
|
|
if err2 := gist.Delete(); err2 != nil {
|
|
|
|
log.Error().Err(err2).Msg("Cannot delete gist")
|
|
|
|
syncReposFromFS = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
syncReposFromFS = false
|
|
|
|
}()
|
2023-04-16 15:48:21 +00:00
|
|
|
return redirect(ctx, "/admin-panel")
|
2023-03-19 00:51:25 +00:00
|
|
|
}
|
2023-03-14 15:22:52 +00:00
|
|
|
|
2023-03-19 00:51:25 +00:00
|
|
|
func adminSyncReposFromDB(ctx echo.Context) error {
|
|
|
|
addFlash(ctx, "Syncing repositories from database...", "success")
|
|
|
|
go func() {
|
|
|
|
if syncReposFromDB {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
syncReposFromDB = true
|
|
|
|
entries, err := filepath.Glob(filepath.Join(config.GetHomeDir(), "repos", "*", "*"))
|
|
|
|
if err != nil {
|
|
|
|
log.Error().Err(err).Msg("Cannot read repos directories")
|
|
|
|
syncReposFromDB = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, e := range entries {
|
|
|
|
path := strings.Split(e, string(os.PathSeparator))
|
|
|
|
gist, _ := models.GetGist(path[len(path)-2], path[len(path)-1])
|
|
|
|
|
|
|
|
if gist.ID == 0 {
|
|
|
|
if err := git.DeleteRepository(path[len(path)-2], path[len(path)-1]); err != nil {
|
|
|
|
log.Error().Err(err).Msg("Cannot delete repository")
|
|
|
|
syncReposFromDB = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
syncReposFromDB = false
|
|
|
|
}()
|
2023-04-16 15:48:21 +00:00
|
|
|
return redirect(ctx, "/admin-panel")
|
2023-03-14 15:22:52 +00:00
|
|
|
}
|
2023-04-16 22:17:06 +00:00
|
|
|
|
2023-06-07 18:50:30 +00:00
|
|
|
func adminConfig(ctx echo.Context) error {
|
|
|
|
setData(ctx, "title", "Configuration")
|
|
|
|
setData(ctx, "htmlTitle", "Configuration - Admin panel")
|
|
|
|
setData(ctx, "adminHeaderPage", "config")
|
2023-05-11 13:16:05 +00:00
|
|
|
|
2023-06-07 18:50:30 +00:00
|
|
|
return html(ctx, "admin_config.html")
|
2023-05-11 13:16:05 +00:00
|
|
|
}
|
|
|
|
|
2023-06-07 18:50:30 +00:00
|
|
|
func adminSetConfig(ctx echo.Context) error {
|
2023-04-16 22:17:06 +00:00
|
|
|
key := ctx.FormValue("key")
|
|
|
|
value := ctx.FormValue("value")
|
|
|
|
|
|
|
|
if err := models.UpdateSetting(key, value); err != nil {
|
|
|
|
return errorRes(500, "Cannot set setting", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx.JSON(200, map[string]interface{}{
|
|
|
|
"success": true,
|
|
|
|
})
|
|
|
|
}
|