Skip to content

Commit

Permalink
Moved user model to top-level, added group model
Browse files Browse the repository at this point in the history
  • Loading branch information
markdicksonjr committed Jul 5, 2019
1 parent 3da451b commit 81bca3b
Show file tree
Hide file tree
Showing 15 changed files with 150 additions and 105 deletions.
57 changes: 32 additions & 25 deletions user/model.go → model.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package user
package nibbler

import (
"encoding/json"
"github.com/markdicksonjr/nibbler"
"reflect"
"time"
)

Expand Down Expand Up @@ -52,31 +49,41 @@ type User struct {
EmploymentEndDate *time.Time `json:"employmentEndDate,omitempty"`
ContractStartDate *time.Time `json:"contractStartDate,omitempty"`
ContractEndDate *time.Time `json:"contractEndDate,omitempty"`
Context *string `json:"contractEndDate,omitempty"`
PrimaryLocation *string `json:"primaryLocation,omitempty"` // e.g. lat/long, grid codes, etc
Context *string `json:"context,omitempty"`
ProtectedContext *string `json:"protectedContext,omitempty"`
}

func FromJson(jsonString string) (*User, error) {
userInt, err := nibbler.FromJson(jsonString, reflect.TypeOf(User{}))
return userInt.(*User), err
}

func ToJson(user *User) (result string, err error) {
userJsonBytes, err := json.Marshal(user)
// basic model for both role-based and group privilege-based auth control

if err != nil {
return
}
type Group struct {
ID string `json:"id" bson:"_id" gorm:"primary_key"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt *time.Time `json:"deletedAt,omitempty" sql:"index"`
Name string `json:"name"`
Type string `json:"type"`
}

result = string(userJsonBytes)
return
type GroupMembership struct {
ID string `json:"id" bson:"_id" gorm:"primary_key"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt *time.Time `json:"deletedAt,omitempty" sql:"index"`
GroupID string `json:"groupId"`
MemberID string `json:"memberId"`
Role GroupRole `json:"role"`
}

func GetSafeUser(user User) User {
safeUser := user
safeUser.Password = nil
safeUser.PasswordResetExpiration = nil
safeUser.PasswordResetToken = nil
safeUser.EmailValidationToken = nil
safeUser.EmailValidationExpiration = nil
return safeUser
type GroupPrivilege struct {
ID string `json:"id" bson:"_id" gorm:"primary_key"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt *time.Time `json:"deletedAt,omitempty" sql:"index"`
PerformingGroupID string `json:"performingGroupID"` // e.g. "administrators" ID
TargetGroupID string `json:"targetGroupID"` // e.g. "customers" ID
Action int `json:"action"` // e.g. read/write/admin/etc
}

type GroupRole int // make your own roles
type Action int // make your own actions
10 changes: 5 additions & 5 deletions session/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import (
"net/http"
)

type SessionStoreConnector interface {
type StoreConnector interface {
Connect() (error, sessions.Store)
MaxAge() int
}

type Extension struct {
nibbler.NoOpExtension
SessionName string
StoreConnector SessionStoreConnector // creates cookie store if not provided
store *sessions.Store // created by this extension
StoreConnector StoreConnector // creates cookie store if not provided
store *sessions.Store // created by this extension
}

func (s *Extension) Init(app *nibbler.Application) error {
Expand Down Expand Up @@ -61,7 +61,7 @@ func (s *Extension) SetAttribute(w http.ResponseWriter, r *http.Request, key str
return session.Save(r, w)
}

func (s *Extension) GetCaller(r *http.Request) (*user.User, error) {
func (s *Extension) GetCaller(r *http.Request) (*nibbler.User, error) {
sessionUser, err := s.GetAttribute(r, "user")

if err != nil {
Expand All @@ -75,7 +75,7 @@ func (s *Extension) GetCaller(r *http.Request) (*user.User, error) {
return user.FromJson(sessionUser.(string))
}

func (s *Extension) SetCaller(w http.ResponseWriter, r *http.Request, userValue *user.User) error {
func (s *Extension) SetCaller(w http.ResponseWriter, r *http.Request, userValue *nibbler.User) error {

if userValue == nil {
return s.SetAttribute(w, r, "user", nil)
Expand Down
6 changes: 3 additions & 3 deletions session/sample/sample.application.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/markdicksonjr/nibbler/session"
"github.com/markdicksonjr/nibbler/session/connectors"
"github.com/markdicksonjr/nibbler/user"
NibUserSql "github.com/markdicksonjr/nibbler/user/database/sql"
NibUserSql "github.com/markdicksonjr/nibbler/user/persistence/sql"
_ "github.com/michaeljs1990/sqlitestore"
"log"
)
Expand All @@ -22,7 +22,7 @@ func main() {

// prepare models for initialization
var models = []interface{}{
user.User{},
nibbler.User{},
}

// allocate an SQL controller, providing an sql extension
Expand All @@ -38,7 +38,7 @@ func main() {
}

// allocate session extension, with an optional custom connector
var sessionConnector session.SessionStoreConnector = &connectors.SqlStoreConnector{
var sessionConnector session.StoreConnector = &connectors.SqlStoreConnector{
Secret: "somesecret",
SqlExtension: sqlController.SqlExtension,
}
Expand Down
6 changes: 6 additions & 0 deletions user/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,11 @@ Provides a basic user model, and some means to persist and query it.
- EnforceLoggedIn
- EnforceEmailValidated

## Context and Protected Context

- Some "room" is available in the default user model for app-specific data that
is attached to users. These are the context properties. The difference between Context
and Protected Context is whether or not API requests should expose the data or not. The
Protected Context is a place where the back-end can attach additional info without it ever
being seen by the user, essentially.

8 changes: 4 additions & 4 deletions user/auth/local/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ type Extension struct {
EmailVerificationFromEmail string

// callbacks (for extending default behavior)
OnLoginSuccessful *func(loggedInUser user.User, sessionMaxAgeMinutes int)
OnLogoutSuccessful *func(loggedOutUser user.User)
OnRegistrationSuccessful *func(registeredUser user.User)
OnEmailVerificationSuccessful *func(registeredUser user.User)
OnLoginSuccessful *func(loggedInUser nibbler.User, sessionMaxAgeMinutes int)
OnLogoutSuccessful *func(loggedOutUser nibbler.User)
OnRegistrationSuccessful *func(registeredUser nibbler.User)
OnEmailVerificationSuccessful *func(registeredUser nibbler.User)

app *nibbler.Application
}
Expand Down
2 changes: 1 addition & 1 deletion user/auth/local/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (s *Extension) LogoutHandler(w http.ResponseWriter, r *http.Request) {
nibbler.Write200Json(w, `{"result": "ok"}`)
}

func (s *Extension) Login(email string, password string) (*user.User, error) {
func (s *Extension) Login(email string, password string) (*nibbler.User, error) {
u, err := s.UserExtension.GetUserByEmail(email)
if err != nil {
return u, err
Expand Down
5 changes: 2 additions & 3 deletions user/auth/local/password.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package local
import (
"github.com/google/uuid"
"github.com/markdicksonjr/nibbler"
"github.com/markdicksonjr/nibbler/user"
"net/http"
"strings"
"time"
Expand All @@ -18,7 +17,7 @@ func (s *Extension) ResetPasswordTokenHandler(w http.ResponseWriter, r *http.Req
email := r.FormValue("email")
username := r.FormValue("username")

var userValue *user.User
var userValue *nibbler.User
var err error

if email != "" {
Expand Down Expand Up @@ -147,7 +146,7 @@ func (s *Extension) ResetPasswordHandler(w http.ResponseWriter, r *http.Request)
nibbler.Write200Json(w, `{"result": "ok"}`)
}

func (s *Extension) getUserByPasswordResetTokenAndValidate(token string) (*user.User, error) {
func (s *Extension) getUserByPasswordResetTokenAndValidate(token string) (*nibbler.User, error) {
if !s.PasswordResetEnabled {
return nil, nil
}
Expand Down
4 changes: 2 additions & 2 deletions user/auth/local/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (s *Extension) RegisterFormHandler(w http.ResponseWriter, r *http.Request)

// begin putting together a new user
emailValidated := !s.EmailVerificationEnabled
userValue := user.User{
userValue := nibbler.User{
Email: &email,
IsEmailValidated: &emailValidated,
}
Expand Down Expand Up @@ -204,7 +204,7 @@ func (s *Extension) EmailTokenVerifyHandler(w http.ResponseWriter, r *http.Reque
nibbler.Write200Json(w, `{"result": true}`)
}

func (s *Extension) getUserByEmailValidationToken(token string) (*user.User, error) {
func (s *Extension) getUserByEmailValidationToken(token string) (*nibbler.User, error) {
if !s.EmailVerificationEnabled {
return nil, nil
}
Expand Down
10 changes: 5 additions & 5 deletions user/auth/local/sample/sample.application.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"github.com/markdicksonjr/nibbler/database/sql"
"github.com/markdicksonjr/nibbler/session"
"github.com/markdicksonjr/nibbler/session/connectors"
NibUser "github.com/markdicksonjr/nibbler/user"
"github.com/markdicksonjr/nibbler/user"
NibUserLocalAuth "github.com/markdicksonjr/nibbler/user/auth/local"
NibUserSql "github.com/markdicksonjr/nibbler/user/database/sql"
NibUserSql "github.com/markdicksonjr/nibbler/user/persistence/sql"
"log"
"net/http"
)
Expand Down Expand Up @@ -38,12 +38,12 @@ func main() {
// allocate the sql extension, with all models
sqlExtension := sql.Extension{
Models: []interface{}{
NibUser.User{},
nibbler.User{},
},
}

// allocate user extension, providing sql extension to it
userExtension := NibUser.Extension{
userExtension := user.Extension{
PersistenceExtension: &NibUserSql.Extension{
SqlExtension: &sqlExtension,
},
Expand Down Expand Up @@ -111,7 +111,7 @@ func main() {
log.Fatal(err.Error())
}

_, err = userExtension.Create(&NibUser.User{
_, err = userExtension.Create(&nibbler.User{
Email: &emailVal,
Password: &password,
})
Expand Down
44 changes: 22 additions & 22 deletions user/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,27 @@ const noExtensionErrorMessage = "no extension found"

type PersistenceExtension interface {
nibbler.Extension
GetUserById(id string) (*User, error)
GetUserByEmail(email string) (*User, error)
GetUserByUsername(username string) (*User, error)
Create(user *User) (*User, error)
Update(user *User) error
UpdatePassword(user *User) error
GetUserByPasswordResetToken(token string) (*User, error)
GetUserByEmailValidationToken(token string) (*User, error)
GetUserById(id string) (*nibbler.User, error)
GetUserByEmail(email string) (*nibbler.User, error)
GetUserByUsername(username string) (*nibbler.User, error)
Create(user *nibbler.User) (*nibbler.User, error)
Update(user *nibbler.User) error
UpdatePassword(user *nibbler.User) error
GetUserByPasswordResetToken(token string) (*nibbler.User, error)
GetUserByEmailValidationToken(token string) (*nibbler.User, error)
}

type Extension struct {
nibbler.Extension

PersistenceExtension PersistenceExtension

OnBeforeUserCreate func(user *User)
OnAfterUserCreate func(user *User)
OnBeforeUserUpdate func(user *User)
OnAfterUserUpdate func(user *User)
OnBeforePasswordUpdate func(user *User)
OnAfterPasswordUpdate func(user *User)
OnBeforeUserCreate func(user *nibbler.User)
OnAfterUserCreate func(user *nibbler.User)
OnBeforeUserUpdate func(user *nibbler.User)
OnAfterUserUpdate func(user *nibbler.User)
OnBeforePasswordUpdate func(user *nibbler.User)
OnAfterPasswordUpdate func(user *nibbler.User)
}

func (s *Extension) Init(app *nibbler.Application) error {
Expand All @@ -49,42 +49,42 @@ func (s *Extension) Destroy(app *nibbler.Application) error {
return nil
}

func (s *Extension) GetUserById(id string) (*User, error) {
func (s *Extension) GetUserById(id string) (*nibbler.User, error) {
if s.PersistenceExtension != nil {
return s.PersistenceExtension.GetUserById(id)
}
return nil, errors.New(noExtensionErrorMessage)
}

func (s *Extension) GetUserByEmail(email string) (*User, error) {
func (s *Extension) GetUserByEmail(email string) (*nibbler.User, error) {
if s.PersistenceExtension != nil {
return s.PersistenceExtension.GetUserByEmail(email)
}
return nil, errors.New(noExtensionErrorMessage)
}

func (s *Extension) GetUserByPasswordResetToken(token string) (*User, error) {
func (s *Extension) GetUserByPasswordResetToken(token string) (*nibbler.User, error) {
if s.PersistenceExtension != nil {
return s.PersistenceExtension.GetUserByPasswordResetToken(token)
}
return nil, errors.New(noExtensionErrorMessage)
}

func (s *Extension) GetUserByEmailVerificationToken(token string) (*User, error) {
func (s *Extension) GetUserByEmailVerificationToken(token string) (*nibbler.User, error) {
if s.PersistenceExtension != nil {
return s.PersistenceExtension.GetUserByEmailValidationToken(token)
}
return nil, errors.New(noExtensionErrorMessage)
}

func (s *Extension) GetUserByUsername(username string) (*User, error) {
func (s *Extension) GetUserByUsername(username string) (*nibbler.User, error) {
if s.PersistenceExtension != nil {
return s.PersistenceExtension.GetUserByUsername(username)
}
return nil, errors.New(noExtensionErrorMessage)
}

func (s *Extension) Create(user *User) (*User, error) {
func (s *Extension) Create(user *nibbler.User) (*nibbler.User, error) {
if s.PersistenceExtension != nil {
user.ID = uuid.New().String()

Expand All @@ -111,7 +111,7 @@ func (s *Extension) Create(user *User) (*User, error) {
return user, errors.New(noExtensionErrorMessage)
}

func (s *Extension) Update(user *User) error {
func (s *Extension) Update(user *nibbler.User) error {
if s.PersistenceExtension != nil {

// call the OnBeforeUserUpdate callback if provided
Expand All @@ -134,7 +134,7 @@ func (s *Extension) Update(user *User) error {
return errors.New(noExtensionErrorMessage)
}

func (s *Extension) UpdatePassword(user *User) error {
func (s *Extension) UpdatePassword(user *nibbler.User) error {
if s.PersistenceExtension != nil {

// call the OnBeforePasswordUpdate callback if provided
Expand Down
Loading

0 comments on commit 81bca3b

Please sign in to comment.