Browse Source

first rest api endpoints added

master
Bernd-René Predota 5 years ago
parent
commit
0f5d46164a
  1. 2
      README.md
  2. 24
      api/v1/tokens/route.go
  3. 43
      api/v1/tokens/tokens.go
  4. 24
      api/v1/users/route.go
  5. 20
      api/v1/users/users.go
  6. 8
      api/v1/v1.go
  7. 4
      cmd/add/add.go
  8. 15
      cmd/add/admin/admin.go
  9. 57
      cmd/root.go
  10. 90
      cmd/server/server.go
  11. 2
      lib/common/common.go
  12. 13
      lib/database/database.go
  13. 17
      lib/utils/utils.go
  14. 2
      main.go
  15. 2
      models/token.go
  16. 6
      models/user.go
  17. 26
      repositories/token.go
  18. 4
      repositories/user.go

2
README.md

@ -1,6 +1,6 @@
# golang API Skeleton # golang API Skeleton
[![Build Status](https://drone.devices.local/api/badges/mawas/golang-api-skeleton/status.svg)](https://drone.devices.local/mawas/golang-api-skeleton)<a href='https://github.com/jpoles1/gopherbadger' target='_blank'>![gopherbadger-tag-do-not-edit](https://img.shields.io/badge/Go%20Coverage-67%25-brightgreen.svg?longCache=true&style=flat)</a>
[![Build Status](https://drone.devices.local/api/badges/mawas/golang-api-skeleton/status.svg)](https://drone.devices.local/mawas/golang-api-skeleton)<a href='https://github.com/jpoles1/gopherbadger' target='_blank'>![gopherbadger-tag-do-not-edit](https://img.shields.io/badge/Go%20Coverage-69%25-brightgreen.svg?longCache=true&style=flat)</a>
refined skeleton future apis should be based on refined skeleton future apis should be based on

24
api/v1/tokens/route.go

@ -0,0 +1,24 @@
package tokens
import "github.com/gin-gonic/gin"
// ApplyRoutes applies router to the gin Engine
func ApplyRoutes(r *gin.RouterGroup) *gin.RouterGroup {
tokens := r.Group("/tokens")
{
tokens.POST("", Create)
// tokens.GET("/:id", middlewares.Authorized, ReadAction)
tokens.GET("/:token", Read)
// tokens.GET("/:id/logs", middlewares.Authorized, actionlogs.ReadActionLogs)
// tokens.PATCH("/:id", middlewares.Authorized, UpdateAction)
// tokens.PATCH("", middlewares.Authorized, UpdateActions)
// tokens.DELETE("/:id", middlewares.Authorized, DeleteAction)
// tokens.DELETE("", middlewares.Authorized, DeleteActions)
// tokens.GET("/:id/properties/*path", middlewares.Authorized, actionproperties.ReadActionProperty)
// tokens.GET("/:id/properties", middlewares.Authorized, actionproperties.ReadActionProperties)
// tokens.PUT("/:id/properties/*path", middlewares.Authorized, actionproperties.UpsertActionProperty)
// tokens.PUT("/:id/properties", middlewares.Authorized, actionproperties.ReplaceActionProperties)
// tokens.DELETE("/:id/properties/*path", middlewares.Authorized, actionproperties.DeleteActionProperty)
}
return r
}

43
api/v1/tokens/tokens.go

@ -0,0 +1,43 @@
package tokens
import (
"time"
"git.devices.local/mawas/golang-api-skeleton/lib/cache"
"git.devices.local/mawas/golang-api-skeleton/lib/common"
"git.devices.local/mawas/golang-api-skeleton/models"
"git.devices.local/mawas/golang-api-skeleton/repositories"
"git.devices.local/mawas/golang-api-skeleton/services"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func Create(c *gin.Context) {
// var requestBody models.Token
db := c.MustGet("db").(*gorm.DB)
cc := c.MustGet("cache").(cache.Cache)
// if err := c.ShouldBindBodyWith(&requestBody, binding.JSON); err != nil {
// return
// }
tokenRepo := repositories.NewTokenRepository(db, "01F5FSJXDHWT4HK93B9NB8V5G4", "test", cc)
tokenService := services.NewTokenService(tokenRepo)
userID, _ := common.StringToGUID("01F5G1W6WJCKQ4PPRS36RYGQ08")
t := &models.Token{
ExpiresAt: time.Now().Add(24 * time.Hour),
UserID: userID,
Active: true,
}
token, _ := tokenService.Create(t)
c.JSON(200, token)
}
func Read(c *gin.Context) {
db := c.MustGet("db").(*gorm.DB)
cc := c.MustGet("cache").(cache.Cache)
repo := repositories.NewTokenRepository(db, "01F5FSJXDHWT4HK93B9NB8V5G4", "test", cc)
service := services.NewTokenService(repo)
t := c.Param("token")
token, _ := service.ReadByKey(t)
c.JSON(200, token)
}

24
api/v1/users/route.go

@ -0,0 +1,24 @@
package users
import "github.com/gin-gonic/gin"
// ApplyRoutes applies router to the gin Engine
func ApplyRoutes(r *gin.RouterGroup) *gin.RouterGroup {
users := r.Group("/users")
{
// actions.POST("", middlewares.Authorized, CreateActions)
// actions.GET("/:id", middlewares.Authorized, ReadAction)
users.GET("/:username", Read)
// actions.GET("/:id/logs", middlewares.Authorized, actionlogs.ReadActionLogs)
// actions.PATCH("/:id", middlewares.Authorized, UpdateAction)
// actions.PATCH("", middlewares.Authorized, UpdateActions)
// actions.DELETE("/:id", middlewares.Authorized, DeleteAction)
// actions.DELETE("", middlewares.Authorized, DeleteActions)
// actions.GET("/:id/properties/*path", middlewares.Authorized, actionproperties.ReadActionProperty)
// actions.GET("/:id/properties", middlewares.Authorized, actionproperties.ReadActionProperties)
// actions.PUT("/:id/properties/*path", middlewares.Authorized, actionproperties.UpsertActionProperty)
// actions.PUT("/:id/properties", middlewares.Authorized, actionproperties.ReplaceActionProperties)
// actions.DELETE("/:id/properties/*path", middlewares.Authorized, actionproperties.DeleteActionProperty)
}
return r
}

20
api/v1/users/users.go

@ -0,0 +1,20 @@
package users
import (
"git.devices.local/mawas/golang-api-skeleton/lib/cache"
"git.devices.local/mawas/golang-api-skeleton/repositories"
"git.devices.local/mawas/golang-api-skeleton/services"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func Read(c *gin.Context) {
db := c.MustGet("db").(*gorm.DB)
cc := c.MustGet("cache").(cache.Cache)
userRepo := repositories.NewUserRepository(db, "01F5FSJXDHWT4HK93B9NB8V5G4", "test", cc)
userService := services.NewUserService(userRepo)
username := c.Param("username")
user, _ := userService.ReadByID(username)
c.JSON(200, user)
}

8
api/v1/v1.go

@ -1,11 +1,17 @@
package v1 package v1
import "github.com/gin-gonic/gin"
import (
"git.devices.local/mawas/golang-api-skeleton/api/v1/tokens"
"git.devices.local/mawas/golang-api-skeleton/api/v1/users"
"github.com/gin-gonic/gin"
)
func ApplyRoutes(r *gin.RouterGroup) *gin.RouterGroup { func ApplyRoutes(r *gin.RouterGroup) *gin.RouterGroup {
v1 := r.Group("/v1") v1 := r.Group("/v1")
{ {
v1.GET("/ping") v1.GET("/ping")
users.ApplyRoutes(v1)
tokens.ApplyRoutes(v1)
} }
return v1 return v1
} }

4
cmd/add/add.go

@ -14,8 +14,8 @@ func Command(appName string, cfgFile string, flagCfg map[string]interface{}) *co
// SilenceErrors: true, // SilenceErrors: true,
DisableAutoGenTag: true, DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cmd.Help()
return nil
err := cmd.Help()
return err
}, },
} }
cmd.AddCommand(admin.Command(appName, cfgFile, flagCfg)) cmd.AddCommand(admin.Command(appName, cfgFile, flagCfg))

15
cmd/add/admin/admin.go

@ -29,12 +29,16 @@ func Command(appName string, cfgFile string, flagCfg map[string]interface{}) *co
cmd.Flags().StringVarP(&username, "username", "U", "admin", "desired admin user name") cmd.Flags().StringVarP(&username, "username", "U", "admin", "desired admin user name")
cmd.Flags().StringVarP(&firstname, "firstname", "F", "", "admin user fistname") cmd.Flags().StringVarP(&firstname, "firstname", "F", "", "admin user fistname")
if err := cmd.MarkFlagRequired("firstname"); err != nil { if err := cmd.MarkFlagRequired("firstname"); err != nil {
// cmd.Usage()
panic(err)
} }
cmd.Flags().StringVarP(&lastname, "lastname", "L", "", "admin user lastname") cmd.Flags().StringVarP(&lastname, "lastname", "L", "", "admin user lastname")
cmd.MarkFlagRequired("lastname")
if err := cmd.MarkFlagRequired("lastname"); err != nil {
panic(err)
}
cmd.Flags().StringVarP(&email, "email", "M", "", "admin user email address") cmd.Flags().StringVarP(&email, "email", "M", "", "admin user email address")
cmd.MarkFlagRequired("email")
if err := cmd.MarkFlagRequired("email"); err != nil {
panic(err)
}
return cmd return cmd
} }
@ -63,6 +67,7 @@ func createAdminUser(appName, cfgFile string, flagCfg map[string]interface{}, us
userRepo := repositories.NewUserRepository(db, common.CLIUserID, common.CLIUsername, nil) userRepo := repositories.NewUserRepository(db, common.CLIUserID, common.CLIUsername, nil)
userService := services.NewUserService(userRepo) userService := services.NewUserService(userRepo)
adminUser := services.NewUser(username, firstname, lastname, email) adminUser := services.NewUser(username, firstname, lastname, email)
userService.Create(&adminUser)
return nil
adminUser.Active = true
_, err = userService.Create(&adminUser)
return err
} }

57
cmd/root.go

@ -33,8 +33,8 @@ func NewRootCmd(version string, appName string, appDescription string) *cobra.Co
// SilenceErrors: true, // SilenceErrors: true,
DisableAutoGenTag: true, DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
cmd.Usage()
return nil
err := cmd.Usage()
return err
}, },
} }
// cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { // cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
@ -77,35 +77,35 @@ func newSampleCfgCmd() *cobra.Command {
} }
} }
//func createAdminCmd(userService *services.UserService) *cobra.Command {
// func createAdminCmd(userService *services.UserService) *cobra.Command {
// return &cobra.Command{
// Use: "admin",
// Short: "Create initial admin user",
// Long: "Create initial admin user",
// RunE: func(cmd *cobra.Command, args []string) error{
// adminUser := &models.Token{
// ExpiresAt: time.Now().Add(24 * time.Hour),
// UserID: userID,
// Active: true,
// }
// if result1, err := tokenService.Create(token1); err != nil {
// panic(err)
// }
// },
// }
// }
// func newSampleCLICmd() *cobra.Command {
// return &cobra.Command{ // return &cobra.Command{
// Use: "admin",
// Short: "Create initial admin user",
// Long: "Create initial admin user",
// RunE: func(cmd *cobra.Command, args []string) error{
// adminUser := &models.Token{
// ExpiresAt: time.Now().Add(24 * time.Hour),
// UserID: userID,
// Active: true,
// }
// if result1, err := tokenService.Create(token1); err != nil {
// panic(err)
// }
// Use: "cli",
// Short: "Interactive CLI",
// Long: "Interactive CLI maybe",
// Run: func(cmd *cobra.Command, args []string) {
// cmd.Println("here might be an cli")
// os.Exit(0)
// }, // },
// } // }
//}
func newSampleCLICmd() *cobra.Command {
return &cobra.Command{
Use: "cli",
Short: "Interactive CLI",
Long: "Interactive CLI maybe",
Run: func(cmd *cobra.Command, args []string) {
cmd.Println("here might be an cli")
os.Exit(0)
},
}
}
// }
func Initialize(version string, appName string, appDescription string) (string, map[string]interface{}, error) { func Initialize(version string, appName string, appDescription string) (string, map[string]interface{}, error) {
var cfgFile string var cfgFile string
@ -118,7 +118,6 @@ func Initialize(version string, appName string, appDescription string) (string,
}) })
rootCmd.AddCommand(newVersionCmd(version, appName)) rootCmd.AddCommand(newVersionCmd(version, appName))
rootCmd.AddCommand(newSampleCfgCmd()) rootCmd.AddCommand(newSampleCfgCmd())
rootCmd.AddCommand(newSampleCfgCmd())
// rootCmd.AddCommand(newSampleCLICmd()) // rootCmd.AddCommand(newSampleCLICmd())
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file") rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file")

90
cmd/server/server.go

@ -4,7 +4,13 @@ import (
"fmt" "fmt"
"git.devices.local/mawas/golang-api-skeleton/api" "git.devices.local/mawas/golang-api-skeleton/api"
"git.devices.local/mawas/golang-api-skeleton/lib/cache"
"git.devices.local/mawas/golang-api-skeleton/lib/common"
"git.devices.local/mawas/golang-api-skeleton/lib/config" "git.devices.local/mawas/golang-api-skeleton/lib/config"
"git.devices.local/mawas/golang-api-skeleton/lib/database"
"git.devices.local/mawas/golang-api-skeleton/models"
"git.devices.local/mawas/golang-api-skeleton/repositories"
"git.devices.local/mawas/golang-api-skeleton/services"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -28,24 +34,64 @@ func startServer(appName string, cfgFile string, flagCfg map[string]interface{})
if err := config.Initialize(appName, cfgFile, flagCfg); err != nil { if err := config.Initialize(appName, cfgFile, flagCfg); err != nil {
return fmt.Errorf("config:" + err.Error()) return fmt.Errorf("config:" + err.Error())
} }
// db, err := database.Connect(database.Credentials{
// Host: viper.GetString("database.host"),
// Port: viper.GetInt("database.port"),
// Dialect: viper.GetString("database.dialect"),
// Database: viper.GetString("database.database"),
// User: viper.GetString("database.user"),
// Password: viper.GetString("database.password"),
// MaxOpenConn: viper.GetInt("database.port"),
// MaxIdleConn: viper.GetInt("database.port"),
// MaxLifeTime: viper.GetInt("database.port"),
// Debug: true,
// })
// if err != nil {
// return fmt.Errorf("database:%v", err)
// }
db, err := database.Connect(database.Credentials{
Host: viper.GetString("database.host"),
Port: viper.GetInt("database.port"),
Dialect: viper.GetString("database.dialect"),
Database: viper.GetString("database.database"),
User: viper.GetString("database.user"),
Password: viper.GetString("database.password"),
MaxOpenConn: viper.GetInt("database.port"),
MaxIdleConn: viper.GetInt("database.port"),
MaxLifeTime: viper.GetInt("database.port"),
Debug: true,
})
if err != nil {
return fmt.Errorf("database:%v", err)
}
app := gin.New() app := gin.New()
app.Use(gin.Recovery()) app.Use(gin.Recovery())
// app.Use(inject(db))
c, err := cache.Bootstrap()
if err != nil {
return fmt.Errorf("cache:%v", err)
}
defer c.Close()
if err := c.Set("user:"+common.CLIUserID, common.CLIUsername); err != nil { // userID -> username mapping
return fmt.Errorf("cache:%v", err)
}
if err := c.Set("user:"+common.CLIUsername, common.CLIUserID); err != nil { // username -> userID mapping
return fmt.Errorf("api:%v", err)
}
if err := c.Set("user:01F5FSJXDHWT4HK93B9NB8V5G4", "test"); err != nil { // userID -> username mapping
return fmt.Errorf("cache:%v", err)
}
if err := c.Set("user:test", "01F5FSJXDHWT4HK93B9NB8V5G4"); err != nil { // username -> userID mapping
return fmt.Errorf("cache:%v", err)
}
// Prefill cache
// TODO also add deleted users to cache for old references
userRepo := repositories.NewUserRepository(db, common.CLIUserID, common.CLIUsername, nil)
userService := services.NewUserService(userRepo)
if userData, err := userService.ReadAll(); err != nil {
} else {
for i := range userData {
if err := c.Set("user:"+userData[i].ID.String(), userData[i].Username); err != nil { // userID -> username mapping
return fmt.Errorf("cache:%v", err)
}
if err := c.Set("user:"+userData[i].Username, userData[i].ID.String()); err != nil { // username -> userID mapping
return fmt.Errorf("cache:%v", err)
}
}
}
app.Use(inject("cache", c))
app.Use(inject("db", db))
// FIXME find out where todo database migration
if err := db.AutoMigrate(&models.Token{}); err != nil {
return fmt.Errorf("database:%v", err)
}
if err := db.AutoMigrate(&models.User{}); err != nil {
return fmt.Errorf("database:%v", err)
}
api.ApplyRoutes(app) api.ApplyRoutes(app)
if err := app.Run(fmt.Sprintf("%s:%s", viper.GetString("application.listenaddress"), viper.GetString("application.port"))); err != nil { if err := app.Run(fmt.Sprintf("%s:%s", viper.GetString("application.listenaddress"), viper.GetString("application.port"))); err != nil {
return fmt.Errorf("api:%v", err) return fmt.Errorf("api:%v", err)
@ -60,9 +106,9 @@ func startServer(appName string, cfgFile string, flagCfg map[string]interface{})
// } // }
// Inject injects database to gin context // Inject injects database to gin context
// func inject(db *gorm.DB) gin.HandlerFunc {
// return func(c *gin.Context) {
// c.Set("db", db)
// c.Next()
// }
// }
func inject(key string, value interface{}) gin.HandlerFunc {
return func(c *gin.Context) {
c.Set(key, value)
c.Next()
}
}

2
lib/common/common.go

@ -47,7 +47,7 @@ func (basicFields *BasicFields) AfterCreate(tx *gorm.DB) error {
return nil return nil
} }
type GUIDPKicPK struct {
type ModelIntegerPK struct {
ID uint64 `gorm:"primaryKey;column:id" json:"id"` ID uint64 `gorm:"primaryKey;column:id" json:"id"`
BasicFields BasicFields
} }

13
lib/database/database.go

@ -63,8 +63,8 @@ func (c *Credentials) getDSN() gorm.Dialector {
" sslmode=disable connect_timeout=5" " sslmode=disable connect_timeout=5"
return postgres.Open(dsn) return postgres.Open(dsn)
case "sqlite": case "sqlite":
// return sqlite.Open("gorm.db")
return sqlite.Open("file::memory:?cache=shared")
return sqlite.Open("gorm.db")
// return sqlite.Open("file::memory:?cache=shared")
} }
return nil return nil
} }
@ -78,13 +78,18 @@ func Connect(c Credentials) (*gorm.DB, error) {
Colorful: true, // Disable color Colorful: true, // Disable color
}, },
) )
db, err := gorm.Open(c.getDSN(), &gorm.Config{Logger: newLogger})
config := gorm.Config{Logger: newLogger}
if strings.EqualFold(c.Dialect, "sqlite") {
// FIXME HACK for sqlite
config.DisableForeignKeyConstraintWhenMigrating = true
}
db, err := gorm.Open(c.getDSN(), &config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return db, nil
// sqlDB, err := db.DB() // sqlDB, err := db.DB()
// sqlDB.SetMaxOpenConns(config.Configuration.DBMaxOpenConn) // sqlDB.SetMaxOpenConns(config.Configuration.DBMaxOpenConn)
// sqlDB.SetMaxIdleConns(config.Configuration.DBMaxIdleConn) // sqlDB.SetMaxIdleConns(config.Configuration.DBMaxIdleConn)
// sqlDB.SetConnMaxLifetime(time.Duration(config.Configuration.DBMaxLifeTime) * time.Second) // sqlDB.SetConnMaxLifetime(time.Duration(config.Configuration.DBMaxLifeTime) * time.Second)
return db, nil
} }

17
lib/utils/utils.go

@ -46,15 +46,22 @@ func RandInt(s int, e int) int {
} }
func PrettyPrintJSON(s interface{}) { func PrettyPrintJSON(s interface{}) {
switch s.(type) {
switch v := s.(type) {
case string: case string:
var j map[string]interface{} var j map[string]interface{}
json.Unmarshal([]byte(s.(string)), &j)
// jsonString, _ := json.MarshalIndent(j, "", " ")
jsonString, _ := json.Marshal(j)
if err := json.Unmarshal([]byte(v), &j); err != nil {
panic(err)
}
jsonString, err := json.Marshal(j)
if err != nil {
panic(err)
}
fmt.Println(string(jsonString)) fmt.Println(string(jsonString))
default: default:
jsonString, _ := json.MarshalIndent(s, "", " ")
jsonString, err := json.MarshalIndent(s, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(jsonString)) fmt.Println(string(jsonString))
} }
} }

2
main.go

@ -23,6 +23,8 @@ const defaultHost = "unknown"
// TODO because there is a badgerdb cache which tokens are existing or which userids are existing make an existence check at uuid generation just do be sure // TODO because there is a badgerdb cache which tokens are existing or which userids are existing make an existence check at uuid generation just do be sure
// TODO add logger to gin // TODO add logger to gin
// TODO make explicit getDBConnection function // TODO make explicit getDBConnection function
// TODO restructure flags e.g. listenaddress and port to server
var ( var (
Version string // allows to set version on build Version string // allows to set version on build
APPName string // allows to overwrite app name on build APPName string // allows to overwrite app name on build

2
models/token.go

@ -16,7 +16,7 @@ type Token struct {
LastUsedDB sql.NullTime `gorm:"column:last_used" json:"-"` LastUsedDB sql.NullTime `gorm:"column:last_used" json:"-"`
LastUsedJSON *time.Time `gorm:"-" json:"last_used,omitempty"` LastUsedJSON *time.Time `gorm:"-" json:"last_used,omitempty"`
ExpiresAt time.Time `json:"expires_at"` ExpiresAt time.Time `json:"expires_at"`
UserID common.GUID `json:"asd"`
UserID common.GUID `json:"-"`
Username string `gorm:"-" json:"username"` Username string `gorm:"-" json:"username"`
Active bool `json:"active"` Active bool `json:"active"`
} }

6
models/user.go

@ -16,7 +16,7 @@ type User struct {
TokensRef []Token `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"` TokensRef []Token `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
Tokens []string `gorm:"-" json:"tokens"` Tokens []string `gorm:"-" json:"tokens"`
PasswordHash string `json:"-"` PasswordHash string `json:"-"`
Active bool ` json:"active"`
Active bool `json:"active"`
} }
func (user *User) AfterCreate(tx *gorm.DB) error { func (user *User) AfterCreate(tx *gorm.DB) error {
@ -34,12 +34,10 @@ func (user *User) AfterFind(tx *gorm.DB) error {
if user.DeletedAtDB.Valid { if user.DeletedAtDB.Valid {
user.DeletedAtJSON = &user.DeletedAtDB.Time user.DeletedAtJSON = &user.DeletedAtDB.Time
} }
user.Tokens = []string{}
for i := range user.TokensRef { for i := range user.TokensRef {
user.Tokens = append(user.Tokens, user.TokensRef[i].Token.String()) user.Tokens = append(user.Tokens, user.TokensRef[i].Token.String())
} }
if len(user.Tokens) == 0 {
user.Tokens = []string{}
}
if cc, ok := tx.Get("cache"); ok { if cc, ok := tx.Get("cache"); ok {
if c, ok := cc.(cache.Cache); ok { if c, ok := cc.(cache.Cache); ok {
if username, err := c.Get("user:" + user.CreatedByDB.String()); err != nil { if username, err := c.Get("user:" + user.CreatedByDB.String()); err != nil {

26
repositories/token.go

@ -3,18 +3,19 @@ package repositories
import ( import (
"git.devices.local/mawas/golang-api-skeleton/lib/cache" "git.devices.local/mawas/golang-api-skeleton/lib/cache"
"git.devices.local/mawas/golang-api-skeleton/lib/common"
model "git.devices.local/mawas/golang-api-skeleton/models" model "git.devices.local/mawas/golang-api-skeleton/models"
"gorm.io/gorm" "gorm.io/gorm"
) )
type tokenDAO struct {
type TokenDAO struct {
repo repo
} }
// NewTokenRepository create new repository for model token // NewTokenRepository create new repository for model token
func NewTokenRepository(db *gorm.DB, userID string, username string, cache cache.Cache) *tokenDAO {
func NewTokenRepository(db *gorm.DB, userID string, username string, cache cache.Cache) *TokenDAO {
db = db.Set("username", username).Set("userID", userID).Set("cache", cache) db = db.Set("username", username).Set("userID", userID).Set("cache", cache)
return &tokenDAO{
return &TokenDAO{
repo: repo{ repo: repo{
db: db, db: db,
userID: userID, userID: userID,
@ -23,28 +24,29 @@ func NewTokenRepository(db *gorm.DB, userID string, username string, cache cache
} }
} }
func (dao *tokenDAO) ReadByKey(key interface{}) (*model.Token, error) {
func (dao *TokenDAO) ReadByKey(key interface{}) (*model.Token, error) {
token := model.Token{} token := model.Token{}
err := dao.db.Joins("User").First(&token, key).Error
t, _ := common.StringToGUID(key.(string))
err := dao.db.Where(model.Token{Token: t}).First(&token).Error
return &token, err return &token, err
} }
func (dao *tokenDAO) ReadAll() ([]*model.Token, error) {
func (dao *TokenDAO) ReadAll() ([]*model.Token, error) {
var tokens []*model.Token var tokens []*model.Token
err := dao.db.Find(&tokens).Error err := dao.db.Find(&tokens).Error
return tokens, err return tokens, err
} }
func (dao *tokenDAO) Create(token *model.Token) (*model.Token, error) {
func (dao *TokenDAO) Create(token *model.Token) (*model.Token, error) {
err := dao.db.Create(token).Error err := dao.db.Create(token).Error
if cc, ok := dao.db.Get("cache"); ok { if cc, ok := dao.db.Get("cache"); ok {
if c, ok := cc.(cache.Cache); ok { if c, ok := cc.(cache.Cache); ok {
if username, err := c.Get("user:" + token.UserID.String()); err != nil {
username, err := c.Get("user:" + token.UserID.String())
if err != nil {
return nil, err return nil, err
} else {
if username != nil {
token.Username = *username
}
}
if username != nil {
token.Username = *username
} }
} }
} }

4
repositories/user.go

@ -25,7 +25,9 @@ func NewUserRepository(db *gorm.DB, userID string, username string, cache cache.
func (dao *UserDAO) ReadByUsername(username string) (*model.User, error) { func (dao *UserDAO) ReadByUsername(username string) (*model.User, error) {
result := model.User{} result := model.User{}
err := dao.db.Where(&model.User{Username: username}).First(&result).Error
// err := dao.db.Joins("TokensRef").Where(&model.User{Username: username}).First(&result).Error
err := dao.db.Preload("TokensRef").Where(&model.User{Username: username}).First(&result).Error
// err := dao.db.Where(&model.User{Username: username}).First(&result).Error
return &result, err return &result, err
} }

Loading…
Cancel
Save