DB & Route Organization
This commit is contained in:
parent
04924ead5c
commit
96b0c888ed
81
cmd/cmd.go
81
cmd/cmd.go
@ -1,14 +1,17 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// "reichard.io/imagini/routes"
|
"fmt"
|
||||||
|
"errors"
|
||||||
|
"reichard.io/imagini/routes"
|
||||||
"reichard.io/imagini/internal/db"
|
"reichard.io/imagini/internal/db"
|
||||||
|
"reichard.io/imagini/internal/auth"
|
||||||
|
"reichard.io/imagini/internal/models"
|
||||||
"reichard.io/imagini/internal/config"
|
"reichard.io/imagini/internal/config"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
// "net/http"
|
"net/http"
|
||||||
// "log"
|
log "github.com/sirupsen/logrus"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var CmdServe = cli.Command{
|
var CmdServe = cli.Command{
|
||||||
@ -19,32 +22,66 @@ var CmdServe = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var CmdDBTest = cli.Command{
|
var CmdDBTest = cli.Command{
|
||||||
Name: "db",
|
Name: "test",
|
||||||
Aliases: []string{"d"},
|
Aliases: []string{"t"},
|
||||||
Usage: "test db.",
|
Usage: "test db.",
|
||||||
Action: testDatabase,
|
Action: testDatabase,
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveWeb(ctx *cli.Context) error {
|
func serveWeb(ctx *cli.Context) error {
|
||||||
c := config.NewConfig()
|
log.Info("Serving Web")
|
||||||
db.ConnectDB(c)
|
routes.RegisterRoutes()
|
||||||
//db.PopulateTestData()
|
if err := http.ListenAndServe(":8080", nil); err != nil {
|
||||||
newItems := db.ItemsFromAlbum(1, 2)
|
log.Fatal(err)
|
||||||
|
}
|
||||||
fmt.Printf("%+v\n", newItems)
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
|
||||||
// routes.RegisterRoutes()
|
|
||||||
|
|
||||||
// if err := http.ListenAndServe(":8080", nil); err != nil {
|
|
||||||
// log.Fatal(err)
|
|
||||||
// }
|
|
||||||
// return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDatabase(ctx *cli.Context) error {
|
func testDatabase(ctx *cli.Context) error {
|
||||||
resp := db.ItemsFromAlbum(1, 3)
|
log.Info("Testing Database")
|
||||||
fmt.Printf("%v", resp)
|
c := config.NewConfig()
|
||||||
|
db.ConnectDB(c)
|
||||||
|
|
||||||
|
err := auth.CreateUser(models.User{
|
||||||
|
Username: "User12346",
|
||||||
|
Email: "user26@evan.pub",
|
||||||
|
FirstName: "User",
|
||||||
|
LastName: "Reichard",
|
||||||
|
AuthType: "Local",
|
||||||
|
}, "myPassword123")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := auth.AuthenticateUser("User123", "myPassword123")
|
||||||
|
if resp == true {
|
||||||
|
log.Info("USER SUCCESSFULLY AUTHENTICATED BY USERNAME")
|
||||||
|
}else {
|
||||||
|
log.Info("USER NOT AUTHENTICATED")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = auth.AuthenticateUser("user@evan.pub", "myPassword123")
|
||||||
|
if resp == true {
|
||||||
|
log.Info("USER SUCCESSFULLY AUTHENTICATED BY EMAIL")
|
||||||
|
}else {
|
||||||
|
log.Info("USER NOT AUTHENTICATED")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = auth.AuthenticateUser("user@evan.pub", "myPassword12")
|
||||||
|
if resp == true {
|
||||||
|
log.Info("USER SUCCESSFULLY AUTHENTICATED BY EMAIL")
|
||||||
|
}else {
|
||||||
|
log.Info("USER NOT AUTHENTICATED")
|
||||||
|
}
|
||||||
|
|
||||||
|
// foundUser, err := db.GetUser(db.User{Username: "User123"})
|
||||||
|
|
||||||
|
// if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
// log.Warn("RECORD NOT FOUND")
|
||||||
|
// } else {
|
||||||
|
// log.Info("FOUND USER", foundUser)
|
||||||
|
// }
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -6,8 +6,10 @@ require (
|
|||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/disintegration/imaging v1.6.2 // indirect
|
github.com/disintegration/imaging v1.6.2 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.6
|
github.com/mattn/go-sqlite3 v1.14.6
|
||||||
|
github.com/sirupsen/logrus v1.7.0
|
||||||
github.com/tus/tusd v1.4.0
|
github.com/tus/tusd v1.4.0
|
||||||
github.com/urfave/cli/v2 v2.3.0
|
github.com/urfave/cli/v2 v2.3.0
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect
|
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 // indirect
|
||||||
gorm.io/driver/sqlite v1.1.4
|
gorm.io/driver/sqlite v1.1.4
|
||||||
gorm.io/gorm v1.20.9
|
gorm.io/gorm v1.20.9
|
||||||
|
8
go.sum
8
go.sum
@ -99,6 +99,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
|
|||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||||
@ -124,9 +126,12 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
|||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||||
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
@ -160,6 +165,9 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
BIN
imagini.db
BIN
imagini.db
Binary file not shown.
37
internal/auth/auth.go
Normal file
37
internal/auth/auth.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"reichard.io/imagini/internal/db"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AuthenticateUser(userIdentifier string, userPassword string) bool {
|
||||||
|
// By Username
|
||||||
|
foundUser, err := db.GetUser(db.User{Username: userIdentifier})
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
foundUser, err = db.GetUser(db.User{Email: userIdentifier})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error Checking
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
log.Warn("[auth] User not found: ", userIdentifier)
|
||||||
|
return false
|
||||||
|
} else if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("[auth] Authenticating user: ", foundUser.Username)
|
||||||
|
|
||||||
|
// Determine Type
|
||||||
|
switch foundUser.AuthType {
|
||||||
|
case "Local":
|
||||||
|
return authenticateLocalUser(foundUser, userPassword)
|
||||||
|
case "LDAP":
|
||||||
|
return authenticateLDAPUser(foundUser, userPassword)
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reichard.io/imagini/internal/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
func authenticateLDAPUser(user db.User, pw string) bool {
|
||||||
|
return false
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"reichard.io/imagini/internal/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
func authenticateLocalUser(user db.User, pw string) bool {
|
||||||
|
bPassword :=[]byte(pw)
|
||||||
|
err := bcrypt.CompareHashAndPassword([]byte(user.HashedPassword), bPassword)
|
||||||
|
if err == nil {
|
||||||
|
log.Info("[local] Authentication successfull: ", user.Username)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
log.Warn("[local] Authentication failed: ", user.Username)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateUser(user db.User, pw string) error {
|
||||||
|
log.Info("[local] Creating user: ", user.Username)
|
||||||
|
_, err := db.GetUser(user)
|
||||||
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
log.Warn("[auth] User already exists: ", user.Username)
|
||||||
|
return errors.New("User already exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user.HashedPassword = string(hashedPassword)
|
||||||
|
return db.CreateUser(user)
|
||||||
|
}
|
@ -3,39 +3,41 @@ package db
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"path"
|
"path"
|
||||||
"fmt"
|
// "time"
|
||||||
"time"
|
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
"gorm.io/driver/sqlite"
|
"gorm.io/driver/sqlite"
|
||||||
|
|
||||||
"reichard.io/imagini/internal/config"
|
"reichard.io/imagini/internal/config"
|
||||||
|
"reichard.io/imagini/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var db *gorm.DB
|
var db *gorm.DB
|
||||||
|
|
||||||
func ConnectDB(c *config.Config) {
|
func ConnectDB(c *config.Config) {
|
||||||
fmt.Printf("%+v\n", c)
|
gormConfig := &gorm.Config{
|
||||||
|
PrepareStmt: true,
|
||||||
|
Logger: logger.Default.LogMode(logger.Silent),
|
||||||
|
}
|
||||||
|
|
||||||
if c.DBType == "SQLite" {
|
if c.DBType == "SQLite" {
|
||||||
dbLocation := path.Join(c.ConfigPath, "imagini.db")
|
dbLocation := path.Join(c.ConfigPath, "imagini.db")
|
||||||
db, _ = gorm.Open(sqlite.Open(dbLocation), &gorm.Config{
|
db, _ = gorm.Open(sqlite.Open(dbLocation), gormConfig)
|
||||||
PrepareStmt: true,
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
log.Fatal("ERROR: Unsupported Database")
|
log.Fatal("ERROR: Unsupported Database")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Database
|
// Initialize Database
|
||||||
db.AutoMigrate(&ServerSetting{})
|
db.AutoMigrate(&models.ServerSetting{})
|
||||||
db.AutoMigrate(&User{})
|
db.AutoMigrate(&models.User{})
|
||||||
db.AutoMigrate(&MediaItem{})
|
db.AutoMigrate(&models.MediaItem{})
|
||||||
db.AutoMigrate(&Tag{})
|
db.AutoMigrate(&models.Tag{})
|
||||||
db.AutoMigrate(&Album{})
|
db.AutoMigrate(&models.Album{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ItemsFromAlbum(user User, album Album) []MediaItem {
|
func ItemsFromAlbum(user models.User, album models.Album) []models.MediaItem {
|
||||||
var mediaItems []MediaItem
|
var mediaItems []models.MediaItem
|
||||||
// db.Table("media_albums").
|
// db.Table("media_albums").
|
||||||
// Select("media_item.*").
|
// Select("media_item.*").
|
||||||
// Joins("INNER JOIN media_items ON media_albums.ID = media_items.Albums").
|
// Joins("INNER JOIN media_items ON media_albums.ID = media_items.Albums").
|
||||||
@ -63,63 +65,63 @@ func ItemsFromAlbum(user User, album Album) []MediaItem {
|
|||||||
// func IndexMediaItems(newItems []MediaItem) {
|
// func IndexMediaItems(newItems []MediaItem) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func PopulateTestData() {
|
// func PopulateTestData() {
|
||||||
user1 := User{Name: "Evan", Email: "evan@reichard.io", AuthType: "LDAP", Salt: "1234", HashedPWSalt: "1234"}
|
// user1 := User{Username: "Evan", Email: "evan@reichard.io", FirstName: "Evan", LastName: "Reichard", AuthType: "LDAP", Salt: "1234", HashedPWSalt: "1234"}
|
||||||
user2 := User{Name: "Ryan", Email: "ryan@example.com", AuthType: "Local", Salt: "2345", HashedPWSalt: "2345"}
|
// user2 := User{Username: "Ryan", Email: "ryan@example.com", FirstName: "Ryan", LastName: "Dunfrey", AuthType: "Local", Salt: "2345", HashedPWSalt: "2345"}
|
||||||
user3 := User{Name: "Bill", Email: "bill@example.com", AuthType: "LDAP", Salt: "3456", HashedPWSalt: "3456"}
|
// user3 := User{Username: "Bill", Email: "bill@example.com", FirstName: "Bill", LastName: "Smith", AuthType: "LDAP", Salt: "3456", HashedPWSalt: "3456"}
|
||||||
|
//
|
||||||
mi1 := MediaItem{
|
// mi1 := MediaItem{
|
||||||
User: user1,
|
// User: user1,
|
||||||
EXIFDate: time.Now(),
|
// EXIFDate: time.Now(),
|
||||||
Latitude: "1234",
|
// Latitude: "1234",
|
||||||
Longitude: "1234",
|
// Longitude: "1234",
|
||||||
RelPath: "./1234.jpg",
|
// RelPath: "./1234.jpg",
|
||||||
Tags: []Tag{
|
// Tags: []Tag{
|
||||||
{Name: "Tag1"},
|
// {Name: "Tag1"},
|
||||||
{Name: "Tag2"},
|
// {Name: "Tag2"},
|
||||||
},
|
// },
|
||||||
Albums: []Album{
|
// Albums: []Album{
|
||||||
{Name: "Album1"},
|
// {Name: "Album1"},
|
||||||
{Name: "Album2"},
|
// {Name: "Album2"},
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
mi2 := MediaItem{
|
// mi2 := MediaItem{
|
||||||
User: user2,
|
// User: user2,
|
||||||
EXIFDate: time.Now(),
|
// EXIFDate: time.Now(),
|
||||||
Latitude: "1234",
|
// Latitude: "1234",
|
||||||
Longitude: "1234",
|
// Longitude: "1234",
|
||||||
RelPath: "./1234.jpg",
|
// RelPath: "./1234.jpg",
|
||||||
Tags: []Tag{
|
// Tags: []Tag{
|
||||||
{Name: "Tag3"},
|
// {Name: "Tag3"},
|
||||||
{Name: "Tag4"},
|
// {Name: "Tag4"},
|
||||||
},
|
// },
|
||||||
Albums: []Album{
|
// Albums: []Album{
|
||||||
{Name: "Album3"},
|
// {Name: "Album3"},
|
||||||
{Name: "Album4"},
|
// {Name: "Album4"},
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
mi3 := MediaItem{
|
// mi3 := MediaItem{
|
||||||
User: user3,
|
// User: user3,
|
||||||
EXIFDate: time.Now(),
|
// EXIFDate: time.Now(),
|
||||||
Latitude: "1234",
|
// Latitude: "1234",
|
||||||
Longitude: "1234",
|
// Longitude: "1234",
|
||||||
RelPath: "./1234.jpg",
|
// RelPath: "./1234.jpg",
|
||||||
Tags: []Tag{
|
// Tags: []Tag{
|
||||||
{Name: "Tag4"},
|
// {Name: "Tag4"},
|
||||||
{Name: "Tag5"},
|
// {Name: "Tag5"},
|
||||||
},
|
// },
|
||||||
Albums: []Album{
|
// Albums: []Album{
|
||||||
{Name: "Album1"},
|
// {Name: "Album1"},
|
||||||
{Name: "Album7"},
|
// {Name: "Album7"},
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// db.Create(&user1)
|
// // db.Create(&user1)
|
||||||
// db.Create(&user2)
|
// // db.Create(&user2)
|
||||||
// db.Create(&user3)
|
// // db.Create(&user3)
|
||||||
db.Create(&mi1)
|
// db.Create(&mi1)
|
||||||
db.Create(&mi2)
|
// db.Create(&mi2)
|
||||||
db.Create(&mi3)
|
// db.Create(&mi3)
|
||||||
}
|
// }
|
||||||
|
7
internal/db/errors.go
Normal file
7
internal/db/errors.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrUserAlreadyExists = errors.New("user already exists")
|
||||||
|
)
|
25
internal/db/users.go
Normal file
25
internal/db/users.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reichard.io/imagini/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateUser (user models.User) error {
|
||||||
|
err := db.Create(&user).Error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func User (user models.User) (models.User, error) {
|
||||||
|
var foundUser models.User
|
||||||
|
var count int64
|
||||||
|
err := db.Where(&user).First(&foundUser).Count(&count).Error
|
||||||
|
return foundUser, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteUser (user models.User) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdatePassword (user models.User, pw string) {
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package db
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -14,11 +14,12 @@ type ServerSetting struct {
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Name string
|
Email string `gorm:"unique;not null"`
|
||||||
Email string
|
Username string `gorm:"unique;not null"`
|
||||||
|
FirstName string
|
||||||
|
LastName string
|
||||||
AuthType string
|
AuthType string
|
||||||
Salt string
|
HashedPassword string
|
||||||
HashedPWSalt string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MediaItem struct {
|
type MediaItem struct {
|
16
main.go
16
main.go
@ -2,9 +2,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"reichard.io/imagini/cmd"
|
"reichard.io/imagini/cmd"
|
||||||
"reichard.io/imagini/internal/sessions"
|
"reichard.io/imagini/internal/sessions"
|
||||||
@ -12,15 +12,27 @@ import (
|
|||||||
|
|
||||||
var globalSessions *sessions.Manager
|
var globalSessions *sessions.Manager
|
||||||
|
|
||||||
|
type UTCFormatter struct {
|
||||||
|
log.Formatter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UTCFormatter) Format(e *log.Entry) ([]byte, error) {
|
||||||
|
e.Time = e.Time.UTC()
|
||||||
|
return u.Formatter.Format(e)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
log.SetFormatter(UTCFormatter{&log.TextFormatter{FullTimestamp: true}})
|
||||||
|
|
||||||
|
log.Info("Starging Imagini")
|
||||||
app := &cli.App{
|
app := &cli.App{
|
||||||
Name: "Imagini",
|
Name: "Imagini",
|
||||||
Usage: "A self hosted photo library.",
|
Usage: "A self hosted photo library.",
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
&cmd.CmdServe,
|
&cmd.CmdServe,
|
||||||
|
&cmd.CmdDBTest,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := app.Run(os.Args)
|
err := app.Run(os.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
9
routes/albums.go
Normal file
9
routes/albums.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func albumsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
13
routes/auth.go
Normal file
13
routes/auth.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func loginHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func logoutHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
9
routes/info.go
Normal file
9
routes/info.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func infoHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
9
routes/media_items.go
Normal file
9
routes/media_items.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mediaItemsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
@ -19,17 +19,17 @@ func MultipleMiddleware(h http.Handler, m ...Middleware) http.Handler {
|
|||||||
return wrapped
|
return wrapped
|
||||||
}
|
}
|
||||||
|
|
||||||
func authMiddleware(h http.Handler) http.Handler {
|
// func authMiddleware(h http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
_, ok := ValidateUserToken(r)
|
// _, ok := ValidateUserToken(r)
|
||||||
|
//
|
||||||
if ok {
|
// if ok {
|
||||||
next.ServeHTTP(w, r)
|
// next.ServeHTTP(w, r)
|
||||||
} else {
|
// } else {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
// w.WriteHeader(http.StatusUnauthorized)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
func logMiddleware(h http.Handler) http.Handler {
|
func logMiddleware(h http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
154
routes/routes.go
154
routes/routes.go
@ -2,84 +2,90 @@ package routes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"fmt"
|
|
||||||
// "reichard.io/imagini/internal/db"
|
|
||||||
"github.com/tus/tusd/pkg/filestore"
|
|
||||||
tusd "github.com/tus/tusd/pkg/handler"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterRoutes() {
|
func RegisterRoutes() {
|
||||||
commonMiddleware := []Middleware{
|
http.HandleFunc("/MediaItems", mediaItemsHandler)
|
||||||
logMiddleware,
|
http.HandleFunc("/Upload", uploadHandler)
|
||||||
authMiddleware,
|
http.HandleFunc("/Albums", albumsHandler)
|
||||||
}
|
http.HandleFunc("/Logout", logoutHandler)
|
||||||
http.Handle("/Users", MultipleMiddleware(usersHandler, commonMiddleware...))
|
http.HandleFunc("/Login", loginHandler)
|
||||||
http.Handle("/Uploads/", MultipleMiddleware(uploadsHandler, commonMiddleware...))
|
http.HandleFunc("/Users", usersHandler)
|
||||||
|
http.HandleFunc("/Tags", tagsHandler)
|
||||||
// http.HandleFunc("/uploads/", uploadsHandler())
|
http.HandleFunc("/Info", infoHandler)
|
||||||
http.Handle("/Uploads/", func(next http.Handler) http.Handler {
|
http.HandleFunc("/Me", meHandler)
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
_, ok := ValidateUserToken(r)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
} else {
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}(http.StripPrefix("/Uploads/", tusHandler)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func tagsHandler(w http.ResponseWriter, r *http.Request) {
|
// Examples:
|
||||||
// query := r.URL.Query()
|
// [POST] /Login { user: <USER_OR_EMAIL>, password: <PASSWORD> }
|
||||||
// filters, present := query["filters"]
|
// [POST] /Logout
|
||||||
|
// [GET] /MediaItems
|
||||||
|
|
||||||
|
// commonMiddleware := []Middleware{
|
||||||
|
// logMiddleware,
|
||||||
|
// authMiddleware,
|
||||||
|
// }
|
||||||
|
// http.Handle("/Users", MultipleMiddleware(usersHandler, commonMiddleware...))
|
||||||
|
// http.Handle("/Uploads/", MultipleMiddleware(uploadsHandler, commonMiddleware...))
|
||||||
|
|
||||||
|
// // http.HandleFunc("/uploads/", uploadsHandler())
|
||||||
|
// http.Handle("/Uploads/", func(next http.Handler) http.Handler {
|
||||||
|
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// _, ok := ValidateUserToken(r)
|
||||||
|
|
||||||
|
// if ok {
|
||||||
|
// next.ServeHTTP(w, r)
|
||||||
|
// } else {
|
||||||
|
// w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }(http.StripPrefix("/Uploads/", tusHandler)))
|
||||||
|
|
||||||
|
// Filter Example:
|
||||||
|
// query := r.URL.Query()
|
||||||
|
// filters, present := query["filters"]
|
||||||
|
|
||||||
|
// HTTP Errors
|
||||||
|
// if r.Method != "GET" {
|
||||||
|
// http.Error(w, "Method is not supported.", http.StatusNotFound)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if r.URL.Path != "/hello" {
|
||||||
|
// http.Error(w, "404 not found.", http.StatusNotFound)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func uploadsHandler() http.Handler {
|
||||||
|
// store := filestore.FileStore{
|
||||||
|
// Path: "./Uploads",
|
||||||
|
// }
|
||||||
|
// composer := tusd.NewStoreComposer()
|
||||||
|
// store.UseIn(composer)
|
||||||
|
//
|
||||||
|
// handler, err := tusd.NewHandler(tusd.Config{
|
||||||
|
// BasePath: "/uploads/",
|
||||||
|
// StoreComposer: composer,
|
||||||
|
// NotifyCompleteUploads: true,
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// panic(fmt.Errorf("Unable to create handler: %s", err))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// go func() {
|
||||||
|
// for {
|
||||||
|
// event := <-handler.CompleteUploads
|
||||||
|
// fmt.Printf("Upload %s finished\n", event.Upload.ID)
|
||||||
|
// }
|
||||||
|
// }()
|
||||||
|
//
|
||||||
|
// // return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// // http.StripPrefix("/Uploads/", handler).ServeHTTP(w, r)
|
||||||
|
// // };
|
||||||
|
//
|
||||||
|
// return http.StripPrefix("/Uploads/", handler)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func helloHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.URL.Path != "/hello" {
|
|
||||||
http.Error(w, "404 not found.", http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Method != "GET" {
|
|
||||||
http.Error(w, "Method is not supported.", http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(w, "Hello!")
|
|
||||||
}
|
|
||||||
|
|
||||||
func uploadsHandler() http.Handler {
|
|
||||||
store := filestore.FileStore{
|
|
||||||
Path: "./Uploads",
|
|
||||||
}
|
|
||||||
composer := tusd.NewStoreComposer()
|
|
||||||
store.UseIn(composer)
|
|
||||||
|
|
||||||
handler, err := tusd.NewHandler(tusd.Config{
|
|
||||||
BasePath: "/uploads/",
|
|
||||||
StoreComposer: composer,
|
|
||||||
NotifyCompleteUploads: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Errorf("Unable to create handler: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
event := <-handler.CompleteUploads
|
|
||||||
fmt.Printf("Upload %s finished\n", event.Upload.ID)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// http.StripPrefix("/Uploads/", handler).ServeHTTP(w, r)
|
|
||||||
// };
|
|
||||||
|
|
||||||
return http.StripPrefix("/Uploads/", handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// func processMedia() {
|
// func processMedia() {
|
||||||
// var mi db.MediaItem
|
// var mi db.MediaItem
|
||||||
//
|
//
|
||||||
@ -108,9 +114,3 @@ func uploadsHandler() http.Handler {
|
|||||||
// img = imaging.Fit(img, 240, 160, imaging.Lanczos)
|
// img = imaging.Fit(img, 240, 160, imaging.Lanczos)
|
||||||
// err = imaging.Save(img, "thumbnail.jpg")
|
// err = imaging.Save(img, "thumbnail.jpg")
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
9
routes/tags.go
Normal file
9
routes/tags.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func tagsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
9
routes/upload.go
Normal file
9
routes/upload.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func uploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
@ -5,6 +5,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func usersHandler(w http.ResponseWriter, r *http.Request) {
|
func usersHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// TODO:
|
|
||||||
// - Get current UserID
|
}
|
||||||
|
|
||||||
|
func meHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user