add templates for kontor-gin
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6s

This commit is contained in:
Thomas Peetz
2026-09-21 19:55:46 +02:00
parent 652aa3005b
commit f2f4a0aaf6
28 changed files with 787 additions and 41 deletions
+93
View File
@@ -0,0 +1,93 @@
package controllers
import (
"kontor-api-gin/pkg/globals"
"kontor-api-gin/pkg/helpers"
"log"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
func LoginGetHandler(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
if user != nil {
c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "Please logout first",
"user": user,
})
return
}
c.HTML(http.StatusOK, "login.tmpl", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "",
"user": user,
})
}
func LoginPostHandler(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
if user != nil {
c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "Please logout first",
})
return
}
username := c.PostForm("username")
password := c.PostForm("password")
if helpers.EmptyUserPass(username, password) {
c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "Parameters can't be empty",
})
}
if !helpers.CheckUserPass(username, password) {
c.HTML(http.StatusUnauthorized, "login.tmpl", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "Incorrect username or password",
})
}
session.Set(globals.UserKey, username)
if err := session.Save(); err != nil {
c.HTML(http.StatusInternalServerError, "login.tmpl", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "Failed to save session",
})
return
}
c.Redirect(http.StatusMovedPermanently, "/")
}
func LogoutGetHandler(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
log.Printf("logging out user %v", user)
if user == nil {
log.Println("Invalid session token")
return
}
session.Delete(globals.UserKey)
if err := session.Save(); err != nil {
log.Printf("Failed to save session: %v", err)
return
}
c.Redirect(http.StatusMovedPermanently, "/")
}
+20
View File
@@ -0,0 +1,20 @@
package controllers
import (
"kontor-api-gin/pkg/globals"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
func IndexGetHandler(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "This is an index page...",
"user": user,
})
}
@@ -1,4 +1,4 @@
package handlers
package controllers
import (
"kontor-api-gin/pkg/schema"
@@ -20,3 +20,15 @@ func ListMediaFiles(c *gin.Context) {
"files": files,
})
}
func ListMediaLoFis(c *gin.Context) {
var lofis []schema.MediaLoFi
result := schema.DB.Find(&lofis)
log.Printf("found %d MediaLoFis", result.RowsAffected)
c.JSON(http.StatusOK, lofis)
// c.JSON(http.StatusOK, gin.H{
// "message": "All MediaLoFis",
// "lofis": lofis,
// })
}
+5
View File
@@ -0,0 +1,5 @@
package globals
var Secret = []byte("secret")
const UserKey = "user"
+11
View File
@@ -0,0 +1,11 @@
package helpers
import "strings"
func CheckUserPass(username, password string) bool {
return true
}
func EmptyUserPass(username, password string) bool {
return strings.Trim(username, " ") == "" || strings.Trim(password, " ") == ""
}
+22
View File
@@ -0,0 +1,22 @@
package middleware
import (
"log"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
func AuthRequired(c *gin.Context) {
session := sessions.Default(c)
user := session.Get("user")
log.Printf("current user %v", user)
if user == nil {
log.Println("User not logged in")
c.Redirect(http.StatusMovedPermanently, "/auth/login")
c.Abort()
return
}
c.Next()
}
+21
View File
@@ -0,0 +1,21 @@
package middleware
import (
"net/http"
"github.com/gin-gonic/gin"
)
// corsMiddleware adds CORS headers for cross-origin requests
func CorsMiddleware(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE, OPTIONS")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
+7 -2
View File
@@ -1,7 +1,7 @@
package routes
import (
"kontor-api-gin/pkg/handlers"
"kontor-api-gin/pkg/controllers"
"github.com/gin-gonic/gin"
)
@@ -11,6 +11,11 @@ func SetupMediaRoutes(router *gin.RouterGroup) {
files := media.Group("/files")
{
files.GET("", handlers.ListMediaFiles)
files.GET("", controllers.ListMediaFiles)
}
lofi := media.Group("/lofi")
{
lofi.GET("", controllers.ListMediaLoFis)
}
}
+21
View File
@@ -0,0 +1,21 @@
package routes
import (
"kontor-api-gin/pkg/controllers"
"github.com/gin-gonic/gin"
)
func PublicRoutes(g *gin.RouterGroup) {
g.GET("/auth/login", controllers.LoginGetHandler)
g.POST("/auth/login", controllers.LoginPostHandler)
g.GET("/", controllers.IndexGetHandler)
}
func ProtectedRoutes(g *gin.RouterGroup) {
g.GET("/media/actors", controllers.IndexGetHandler)
g.GET("/comic/comics", controllers.IndexGetHandler)
g.GET("/media/files", controllers.IndexGetHandler)
g.GET("/media/lofis", controllers.IndexGetHandler)
g.GET("/auth/logout", controllers.LogoutGetHandler)
}
+25 -14
View File
@@ -1,37 +1,48 @@
package schema
import (
)
type MediaLoFi struct {
Base
WebLink string `gorm:"uniqueIndex" json:"url"`
Review bool `json:"review"`
ShouldDownload bool `json:"should_download"`
Title string `gorm:"size:300" json:"title"`
FileName string `json:"file_name"`
}
func (media_lofi *MediaLoFi) TableName() string {
return "media_lofi"
}
type MediaFile struct {
Base
CloudLink string `json:"cloud_link"`
FileName string `json:"file_name"`
Path string `json:"path"`
Review bool `json:"review"`
Title string `gorm:"size:300" json:"title"`
WebLink string `gorm:"uniqueIndex" json:"url"`
ShouldDownload bool `json:"should_download"`
CloudLink string `json:"cloud_link"`
FileName string `json:"file_name"`
Path string `json:"path"`
Review bool `json:"review"`
Title string `gorm:"size:300" json:"title"`
WebLink string `gorm:"uniqueIndex" json:"url"`
ShouldDownload bool `json:"should_download"`
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaFileID" json:"media_actor_files"`
}
func (media_file *MediaFile) TableName() string {
return "media_file"
return "media_file"
}
type MediaActor struct {
Base
Name string `json:"name"`
WebLink string `gorm:"uniqueIndex" json:"url"`
Name string `json:"name"`
WebLink string `gorm:"uniqueIndex" json:"url"`
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaActorID" json:"media_actor_files"`
}
func (media_actor *MediaActor) TableName() string {
return "media_actor"
return "media_actor"
}
type MediaActorFile struct {
@@ -44,7 +55,7 @@ type MediaActorFile struct {
}
func (media_file *MediaActorFile) TableName() string {
return "media_actor_file"
return "media_actor_file"
}
// type MediaArticle struct {