fixed DB problems

templ
Johannes Bülow 2024-01-07 15:10:47 +01:00
parent b2cf2c81d3
commit b01a4dc9d9
Signed by untrusted user who does not match committer: jmb
GPG Key ID: B56971CF7B8F83A6
22 changed files with 235 additions and 28 deletions

View File

@ -19,3 +19,5 @@ minio:
bucket: filegate
usessl: false
location: filegate-local
# 2024/01/07 14:30:16 Admin PW is: qFjzuboCUqJ6ddzezC1LQZORYjwxBbCz
# 2024/01/07 14:30:16 Hashed Admin PW iDErxHTH9OFf873UYiqPz7S6P84Wvs46

View File

@ -40,6 +40,46 @@ func (file *File) save() error {
return nil
}
func (file *File) delete() error {
if err := conn.Delete(file).Error; err != nil {
return err
}
return nil
}
// Status() gives the status of the file because GORM currently doesn't do ManyToOne, so to make this work well I'll
// have to ditch the ORM and go raw SQL
func (file *File) Status() (Status) {
var status Status
if err := conn.First(&status, file.StatusID); err != nil {
log.Printf("Could not get Status of File %d: %v", file.ID, err)
status.ID = 18446744073709551615
status.Name = "Unknown"
}
return status
}
func (file *File) Creator() (User) {
var user User
if err := conn.First(&user, file.CreatorID); err != nil {
log.Printf("Could not get Creator of File %d: %v", file.ID, err)
user.ID = 18446744073709551615
user.Name = "Unknown"
}
return user
}
func (file *File) Assignee() (User) {
var user User
if err := conn.First(&user, file.AssigneeID); err != nil {
log.Printf("Could not get Creator of File %d: %v", file.ID, err)
user.ID = 18446744073709551615
user.Name = "Unknown"
}
return user
}
func CreateFile(name string, url string, comment string, blob string) (uint, error) {
file := File{
Name: name,
@ -51,9 +91,7 @@ func CreateFile(name string, url string, comment string, blob string) (uint, err
}
if err := conn.Create(&file).Error; err != nil {
return 0, err
}
return file.ID, nil
}

View File

@ -39,12 +39,12 @@ type File struct {
gorm.Model
Name string
Comment *string
Status Status
StatusID uint
Blob string
Attachments []Attachment
Properties FileProperties
Creator User
Assignee User
CreatorID uint
AssigneeID uint
}
type Status struct {

22
db/status.go Normal file
View File

@ -0,0 +1,22 @@
package db
func (status *Status) New() (*Status, error) {
if err := conn.Create(status).Error; err != nil {
return status, err
}
return status, nil
}
func (status *Status) Save() (*Status, error) {
if err := conn.Save(status).Error; err != nil {
return status, err
}
return status, nil
}
func (status *Status) Delete() (*Status, error) {
if err := conn.Delete(status).Error; err != nil {
return status, err
}
return status, nil
}

View File

@ -2,6 +2,7 @@ package auth
import (
"fmt"
"log"
"net/http"
"github.com/gin-contrib/sessions"
@ -33,7 +34,21 @@ func AuthMiddleware(requiredLevel int) gin.HandlerFunc {
metaContent.ErrorTitle = "Not Authorized"
metaContent.ErrorText = "You are not authorized to do this Action"
c.HTML(http.StatusUnauthorized, "", templates.Index(metaContent, err))
log.Printf(
"[WARN] %s: %s User: %s IP: %s Unauthorized",
c.Request.Method,
c.Request.URL,
session.Get("username"),
c.Request.RemoteAddr,
)
c.Abort()
log.Printf(
"[INFO] %s: %s User: %s IP: %s",
c.Request.Method,
c.Request.URL,
session.Get("username"),
c.Request.RemoteAddr,
)
return
}
}

View File

@ -4,11 +4,12 @@ import (
"log"
"net/http"
"git.jmbit.de/filegate/filegate/db"
"git.jmbit.de/filegate/filegate/web/static"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
"git.jmbit.de/filegate/filegate/db"
"git.jmbit.de/filegate/filegate/web/static"
)
func setupRouter(production bool) *gin.Engine {
@ -18,9 +19,11 @@ func setupRouter(production bool) *gin.Engine {
} else {
gin.SetMode(gin.DebugMode)
}
gin.ForceConsoleColor()
router := gin.New()
router.Use(gin.Recovery())
router.Use(sessions.Sessions("session", db.CreateStore()))
router.Use(urlLog())
err := router.SetTrustedProxies(viper.GetStringSlice("web.trustedProxies"))
router.HTMLRender = &TemplRender{}
if err != nil {
@ -35,3 +38,21 @@ func setupRouter(production bool) *gin.Engine {
return router
}
func urlLog() gin.HandlerFunc {
return func(c *gin.Context) {
session := sessions.Default(c)
username := session.Get("username")
if username == nil {
username = "N/A"
}
log.Printf(
"[INFO] %s: %s User: %s Source: %s",
c.Request.Method,
c.Request.URL,
username,
c.Request.RemoteAddr,
)
}
}

View File

@ -93,7 +93,7 @@ func browserIframe(browserUUID string) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(fmt.Sprintf("/browser/%s", browserUUID)))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(fmt.Sprintf("/ct/%s/", browserUUID)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@ -22,9 +22,9 @@ templ FileListTable(files []db.File) {
<td>{ fmt.Sprint(file.ID) }</td>
<td>{ file.Name }</td>
<td>{ file.Properties.OriginalName }</td>
<td>{ file.Status.Name }</td>
<td>{ file.Creator.DisplayName }</td>
<td>{ file.Assignee.DisplayName }</td>
<td>{ file.Status().Name }</td>
<td>{ file.Creator().DisplayName }</td>
<td>{ file.Assignee().DisplayName }</td>
</tr>
}
</tbody>

View File

@ -116,7 +116,7 @@ func FileListTable(files []db.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string = file.Status.Name
var templ_7745c5c3_Var11 string = file.Status().Name
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@ -125,7 +125,7 @@ func FileListTable(files []db.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string = file.Creator.DisplayName
var templ_7745c5c3_Var12 string = file.Creator().DisplayName
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@ -134,7 +134,7 @@ func FileListTable(files []db.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string = file.Assignee.DisplayName
var templ_7745c5c3_Var13 string = file.Assignee().DisplayName
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err

View File

@ -12,9 +12,9 @@ templ FileView(file db.File) {
<h2 class="title level-left">{ file.Name }</h2>
<a
class="level-right"
href={ templ.URL(fmt.Sprintf("/user/%d", file.Assignee.ID)) }
href={ templ.URL(fmt.Sprintf("/user/%d", file.Assignee().ID)) }
>
Assignee: { file.Assignee.Name }
Assignee: { file.Assignee().Name }
</a>
</div>
<div class="block">

View File

@ -41,7 +41,7 @@ func FileView(file db.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 templ.SafeURL = templ.URL(fmt.Sprintf("/user/%d", file.Assignee.ID))
var templ_7745c5c3_Var3 templ.SafeURL = templ.URL(fmt.Sprintf("/user/%d", file.Assignee().ID))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@ -55,7 +55,7 @@ func FileView(file db.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string = file.Assignee.Name
var templ_7745c5c3_Var5 string = file.Assignee().Name
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err

View File

@ -1,7 +1,7 @@
package templates
templ loginForm() {
<form id="loginForm" name="login" action="/login.html" method="POST" hx-post="/login.html">
<form id="loginForm" name="login" action="/login.html" method="POST">
<div class="field">
<label class="label">Username </label>
<input class="input" type="text" placeholder="username" name="username" required class="input"/>

View File

@ -23,7 +23,7 @@ func loginForm() templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form id=\"loginForm\" name=\"login\" action=\"/login.html\" method=\"POST\" hx-post=\"/login.html\"><div class=\"field\"><label class=\"label\">")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form id=\"loginForm\" name=\"login\" action=\"/login.html\" method=\"POST\"><div class=\"field\"><label class=\"label\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@ -60,11 +60,11 @@ templ navbar(loggedIn bool) {
templ loginButton(loggedIn bool) {
if loggedIn {
<a class="navbar-link" href="/profile.html">
<a class="navbar-link" href="/profile/">
Profile
</a>
<div class="buttons">
<a class="button is-light" href="/login.html">
<a class="button is-light" href="/logout.html">
Log out
</a>
</div>

View File

@ -334,7 +334,7 @@ func loginButton(loggedIn bool) templ.Component {
}
ctx = templ.ClearChildren(ctx)
if loggedIn {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"navbar-link\" href=\"/profile.html\">")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"navbar-link\" href=\"/profile/\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -343,7 +343,7 @@ func loginButton(loggedIn bool) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a><div class=\"buttons\"><a class=\"button is-light\" href=\"/login.html\">")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a><div class=\"buttons\"><a class=\"button is-light\" href=\"/logout.html\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View File

@ -0,0 +1,12 @@
package templates
import "git.jmbit.de/filegate/filegate/db"
templ profileMain(user *db.User) {
<div class="section is-medium">
<div class="container">
</div>
</div>
}

View File

@ -0,0 +1,8 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: 0.2.476
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"

View File

@ -103,3 +103,8 @@ templ Browser(metaContent utils.MetaContent, title string, browserUUID string,er
@browserFileDiv(browserUUID)
}
}
templ ProfilePage(metaContent utils.MetaContent, title string, user *db.User, err error) {
@wrapBase(metaContent, title, err) {
}
}

View File

@ -411,3 +411,38 @@ func Browser(metaContent utils.MetaContent, title string, browserUUID string, er
return templ_7745c5c3_Err
})
}
func ProfilePage(metaContent utils.MetaContent, title string, user *db.User, err error) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var20 := templ.GetChildren(ctx)
if templ_7745c5c3_Var20 == nil {
templ_7745c5c3_Var20 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var21 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = wrapBase(metaContent, title, err).Render(templ.WithChildren(ctx, templ_7745c5c3_Var21), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}

View File

@ -7,6 +7,7 @@ import (
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"git.jmbit.de/filegate/filegate/db"
"git.jmbit.de/filegate/filegate/utils"
"git.jmbit.de/filegate/filegate/web/auth"
"git.jmbit.de/filegate/filegate/web/templates"
@ -29,8 +30,28 @@ func postLogin(c *gin.Context) {
log.Println(err)
return
} else {
user, err := db.GetUserByName(username)
if err != nil {
log.Printf("Could not retrieve User Object for User with name %s", username)
}
session.Set("username", username)
session.Set("isLoggedIn", true)
session.Set("isAdmin", user.Admin)
session.Set("isAgent", user.Agent)
err = session.Save()
if err != nil {
log.Println("[ERRO] Could not save Session")
}
c.Redirect(http.StatusTemporaryRedirect, "/")
}
}
func getLogout(c *gin.Context) {
session := sessions.Default(c)
username := session.Get("username")
session.Clear()
log.Printf("[INFO] Logged out %s", username)
c.Redirect(http.StatusTemporaryRedirect, "/login.html")
}

View File

@ -1,12 +1,38 @@
package ui
import (
"github.com/gin-gonic/gin"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"git.jmbit.de/filegate/filegate/db"
"git.jmbit.de/filegate/filegate/utils"
"git.jmbit.de/filegate/filegate/web/templates"
)
func getProfile(c *gin.Context) {
c.HTML(http.StatusOK, "profile", gin.H{
"title": "Profile",
})
session := sessions.Default(c)
sessionUserName := session.Get("username")
var user db.User
if username, ok := sessionUserName.(string); ok {
user, err := db.GetUserByName(username)
if err != nil {
c.HTML(
http.StatusInternalServerError,
"",
templates.ProfilePage(utils.GenMetaContent(c), "User Profile", &user, nil),
)
}
c.HTML(
http.StatusOK,
"",
templates.ProfilePage(utils.GenMetaContent(c), "User Profile", &user, nil),
)
} else {
c.HTML(http.StatusNotFound, "", templates.ProfilePage(utils.GenMetaContent(c), "User Profile", &user, nil))
}
}

View File

@ -10,6 +10,8 @@ func GroupWeb(router *gin.Engine) *gin.Engine {
router.POST("/", index)
router.GET("/login.html", getLogin)
router.POST("/login.html", postLogin)
router.GET("/profile/", getProfile)
router.GET("/logout.html", getLogout)
file := router.Group("/file")
file.GET("/", getFileListPage)
file.GET("/empty.html", empty)