Skip to content
Permalink
Browse files

[WIP] Working on QOR Article

  • Loading branch information
Depado committed Feb 13, 2019
1 parent 45e7b04 commit 9bd7f24f40a7d029fbbc14eedfccb589748c3830
No changes.
@@ -0,0 +1,54 @@
package admin

import (
"github.com/Depado/articles/code/qor/v1/models"
"github.com/gin-contrib/sessions/cookie"
"github.com/jinzhu/gorm"
"github.com/qor/admin"
"github.com/qor/qor"
)

// Auth is a structure to handle authentication for QOR. It will satisify the
// qor.Auth interface.
type Auth struct {
db *gorm.DB
store cookie.Store

login string
logout string
session string
key string
}

// GetCurrentUser satisfies the Auth interface and returns the current user
func (a Auth) GetCurrentUser(c *admin.Context) qor.CurrentUser {
var userid uint
s, err := a.store.Get(c.Request, a.session)
if err != nil {
return nil
}
if v, ok := s.Values[a.key]; ok {
userid = v.(uint)
} else {
return nil
}

var user models.AdminUser
if !a.db.First(&user, "id = ?", userid).RecordNotFound() {
return &user
}

return nil
}

// LoginURL statisfies the Auth interface and returns the route used to log
// users in
func (a Auth) LoginURL(c *admin.Context) string { // nolint: unparam
return "/login"
}

// LogoutURL statisfies the Auth interface and returns the route used to logout
// a user
func (a Auth) LogoutURL(c *admin.Context) string { // nolint: unparam
return "/logout"
}
@@ -2,26 +2,20 @@ package main

import (
"net/http"
"time"

"github.com/Depado/articles/code/qor/migrate"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/qor/admin"
uuid "github.com/satori/go.uuid"
"github.com/qor/qor"
"github.com/qor/qor/resource"
"github.com/qor/validations"
"github.com/sirupsen/logrus"
)

type product struct {
ID uuid.UUID `gorm:"primary_key;type:uuid;default:uuid_generate_v4()"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
"golang.org/x/crypto/bcrypt"

Name string
Price int
}
"github.com/Depado/articles/code/qor/v1/migrate"
"github.com/Depado/articles/code/qor/v1/models"
)

func main() {
var db *gorm.DB
@@ -41,7 +35,27 @@ func main() {
mux := http.NewServeMux()
adm.MountTo("/admin", mux)

adm.AddResource(&product{})
adm.AddResource(&models.Product{})
usr := adm.AddResource(&models.AdminUser{}, &admin.Config{Menu: []string{"User Management"}})
usr.IndexAttrs("-Password")
usr.Meta(&admin.Meta{
Name: "Password",
Type: "password",
Setter: func(resource interface{}, metaValue *resource.MetaValue, context *qor.Context) {
values := metaValue.Value.([]string)
if len(values) > 0 {
if np := values[0]; np != "" {
pwd, err := bcrypt.GenerateFromPassword([]byte(np), bcrypt.DefaultCost)
if err != nil {
context.DB.AddError(validations.NewError(usr, "Password", "Can't encrypt password")) // nolint: gosec,errcheck
return
}
u := resource.(*models.AdminUser)
u.Password = pwd
}
}
},
})

r := gin.New()
r.Any("/admin/*resources", gin.WrapH(mux))
@@ -10,6 +10,7 @@ func Start(db *gorm.DB) error {
m := gormigrate.New(db, gormigrate.DefaultOptions, []*gormigrate.Migration{
uuidCheck,
initial,
adminUser,
})
return m.Migrate()
}
@@ -0,0 +1,41 @@
package migrate

import (
"time"

"github.com/jinzhu/gorm"
"golang.org/x/crypto/bcrypt"
gormigrate "gopkg.in/gormigrate.v1"
)

var adminUser = &gormigrate.Migration{
ID: "init_admin",
Migrate: func(tx *gorm.DB) error {
var err error

type adminUser struct {
gorm.Model
Email string `gorm:"not null;unique"`
FirstName string
LastName string
Password []byte
LastLogin *time.Time
}

if err = tx.CreateTable(&adminUser{}).Error; err != nil {
return err
}
var pwd []byte
if pwd, err = bcrypt.GenerateFromPassword([]byte("changeme"), bcrypt.DefaultCost); err != nil {
return err
}
usr := adminUser{
Email: "paul.lhussiez@schibsted.com",
Password: pwd,
}
return tx.Save(&usr).Error
},
Rollback: func(tx *gorm.DB) error {
return tx.DropTable("admin_users").Error
},
}
@@ -0,0 +1,18 @@
package models

import (
"time"

uuid "github.com/satori/go.uuid"
)

// Product is our main product type
type Product struct {
ID uuid.UUID `gorm:"primary_key;type:uuid;default:uuid_generate_v4()"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time

Name string
Price int
}
@@ -0,0 +1,44 @@
package models

import (
"fmt"
"time"

"github.com/jinzhu/gorm"
"golang.org/x/crypto/bcrypt"
)

// AdminUser defines how an admin user is represented in database
type AdminUser struct {
gorm.Model
Email string `gorm:"not null;unique"`
FirstName string
LastName string
Password []byte
LastLogin *time.Time
}

// DisplayName satisfies the interface for Qor Admin
func (u AdminUser) DisplayName() string {
if u.FirstName != "" && u.LastName != "" {
return fmt.Sprintf("%s %s", u.FirstName, u.LastName)
}
return u.Email
}

// HashPassword is a simple utility function to hash the password sent via API
// before inserting it in database
func (u *AdminUser) HashPassword() error {
pwd, err := bcrypt.GenerateFromPassword(u.Password, bcrypt.DefaultCost)
if err != nil {
return err
}
u.Password = pwd
return nil
}

// CheckPassword is a simple utility function to check the password given as raw
// against the user's hashed password
func (u AdminUser) CheckPassword(raw string) bool {
return bcrypt.CompareHashAndPassword(u.Password, []byte(raw)) == nil
}
Binary file not shown.

0 comments on commit 9bd7f24

Please sign in to comment.
You can’t perform that action at this time.