Refactor user modifier

This commit is contained in:
Andrea Fazzi 2020-01-27 08:35:37 +01:00
parent dbbc664fe9
commit d027e84807
10 changed files with 101 additions and 153 deletions

View file

@ -16,8 +16,13 @@ func (e *Error) Error() string {
}
var (
RecordExists = errors.New("Record already exists!")
NotAuthorized = errors.New(i18n.Authorization["notAuthorized"]["it"])
RecordExists = errors.New("Record already exists!")
NotAuthorized = errors.New(i18n.Authorization["notAuthorized"]["it"])
SchoolExists = &Error{
TemplateName: "error_school_exists",
Err: errors.New(i18n.Errors["schoolExists"]["it"]),
}
CategoryExists = &Error{
TemplateName: "error_category_exists",
Err: errors.New(i18n.FlashMessages["categoryExists"]["it"]),

View file

@ -44,6 +44,8 @@ var (
"notAuthorized": map[string]string{
"it": "Non si è autorizzati ad accedere a questa pagina",
},
"schoolExists": map[string]string{
"it": "Una scuola con questo codice meccanografico è già presente nella base dati!",
},
}
)

View file

@ -17,8 +17,7 @@ type ContestIDs []uint
type Participant struct {
gorm.Model
*UserModifierCreate
*UserModifierUpdate
UserModifier
UserID uint
@ -211,7 +210,7 @@ func (model *Participant) Create(db *Database, args map[string]string, w http.Re
return nil, errors.CategoryExists
}
participant.UserModifierCreate = NewUserModifierCreate(r)
participant.CreatorID = getUserIDFromTokenAsUint(r)
participant, err = CreateParticipant(db, participant)
if err != nil {
@ -226,7 +225,7 @@ func (model *Participant) Create(db *Database, args map[string]string, w http.Re
return nil, err
}
response.UserModifierCreate = NewUserModifierCreate(r)
response.CreatorID = getUserIDFromTokenAsUint(r)
if err := db._db.Save(&response).Error; err != nil {
return nil, err
@ -262,8 +261,6 @@ func (model *Participant) Read(db *Database, args map[string]string, w http.Resp
return nil, err
}
participant.UserModifierCreate.get(db)
participant.UserModifierUpdate.get(db)
}
return &participant, nil
@ -369,7 +366,7 @@ func (model *Participant) Update(db *Database, args map[string]string, w http.Re
return nil, err
}
participant.(*Participant).UserModifierUpdate = NewUserModifierUpdate(r)
participant.(*Participant).UpdaterID = getUserIDFromTokenAsUint(r)
_, err = SaveParticipant(db, participant)
if err != nil {
@ -393,7 +390,7 @@ func (model *Participant) Update(db *Database, args map[string]string, w http.Re
return nil, err
}
response.UserModifierUpdate = NewUserModifierUpdate(r)
response.UpdaterID = getUserIDFromTokenAsUint(r)
if err := db._db.Save(&response).Error; err != nil {
return nil, err

View file

@ -21,8 +21,7 @@ type SingleResponse struct {
type Response struct {
gorm.Model
*UserModifierCreate
*UserModifierUpdate
UserModifier
Name string
@ -94,7 +93,7 @@ func (model *Response) Create(db *Database, args map[string]string, w http.Respo
return nil, err
}
response.UserModifierCreate = NewUserModifierCreate(r)
response.CreatorID = getUserIDFromTokenAsUint(r)
response, err = CreateResponse(db, response)
if err != nil {
@ -211,7 +210,7 @@ func (model *Response) Update(db *Database, args map[string]string, w http.Respo
return nil, err
}
response.(*Response).UserModifierUpdate = NewUserModifierUpdate(r)
response.(*Response).UpdaterID = getUserIDFromTokenAsUint(r)
_, err = SaveResponse(db, response)
if err != nil {

View file

@ -2,6 +2,7 @@ package orm
import (
"net/http"
"strconv"
"github.com/dgrijalva/jwt-go"
)
@ -17,6 +18,10 @@ func isRole(role string, r *http.Request) bool {
return false
}
func getUserRole(r *http.Request) string {
return getClaims(r)["role"].(string)
}
func isAdministrator(r *http.Request) bool {
return isRole("administrator", r)
}
@ -36,3 +41,8 @@ func isSubscriber(r *http.Request) bool {
func getUserIDFromToken(r *http.Request) string {
return getClaims(r)["user_id"].(string)
}
func getUserIDFromTokenAsUint(r *http.Request) uint {
id, _ := strconv.Atoi(getUserIDFromToken(r))
return uint(id)
}

View file

@ -37,8 +37,7 @@ Lo Staff delle OEF 2020.
type School struct {
gorm.Model
*UserModifierCreate
*UserModifierUpdate
UserModifier
Name string
Address string
@ -161,16 +160,14 @@ func (model *School) Create(db *Database, args map[string]string, w http.Respons
if err := db._db.Where("user_id = ?", user.ID).Find(&school).Error; err != nil {
return nil, err
}
// err := setFlashMessage(w, r, "schoolExists")
// if err != nil {
// return nil, err
// }
return school, nil
return nil, errors.SchoolExists
} else if err != nil {
return nil, err
}
school.UserModifierCreate = NewUserModifierCreate(r)
school.CreatorID = getUserIDFromTokenAsUint(r)
school.CreatorRole = getUserRole(r)
school.CreatorIP = r.RemoteAddr
school.mailSender = mail.NewMailSender(db.Config, mailBody)
school, err = CreateSchool(db, school)
@ -187,25 +184,19 @@ func (model *School) Read(db *Database, args map[string]string, w http.ResponseW
id := args["id"]
if isSchool(r) && id != getUserIDFromToken(r) {
// setFlashMessage(w, r, "notAuthorized")
return nil, errors.NotAuthorized
}
if err := db._db.Preload("User").Preload("Region").Preload("Participants.Category").Preload("Participants").First(&school, id).Error; err != nil {
if err := db._db.Set("gorm:auto_preload", true).First(&school, id).Error; err != nil {
return nil, err
}
if isAdministrator(r) {
school.UserModifierCreate.get(db)
school.UserModifierUpdate.get(db)
}
return &school, nil
}
func (model *School) ReadAll(db *Database, args map[string]string, w http.ResponseWriter, r *http.Request) (interface{}, error) {
var schools []*School
if err := db._db.Preload("Region").Preload("Participants.Category").Preload("Participants").Order("code").Find(&schools).Error; err != nil {
if err := db._db.Set("gorm:auto_preload", true).Order("code").Find(&schools).Error; err != nil {
return nil, err
}
return schools, nil
@ -241,17 +232,18 @@ func (model *School) Update(db *Database, args map[string]string, w http.Respons
// Check if the modified school code belong to an existing school.
if user, err := school.(*School).exists(db); err == nil && user != nil {
if user.ID != school.(*School).UserID {
// err := setFlashMessage(w, r, "schoolExists")
// if err != nil {
// return nil, err
// }
return school, nil
return nil, errors.SchoolExists
}
} else if err != nil {
return nil, err
}
school.(*School).UserModifierUpdate = NewUserModifierUpdate(r)
// FIXME
// WriteCreator(school.(*School))
school.(*School).UpdaterID = getUserIDFromTokenAsUint(r)
school.(*School).UpdaterRole = getUserRole(r)
school.(*School).UpdaterIP = r.RemoteAddr
_, err = SaveSchool(db, school)
if err != nil {

View file

@ -1,115 +0,0 @@
package orm
import (
"errors"
"net/http"
"github.com/dgrijalva/jwt-go"
)
type UserAction struct {
User
UserModifierCreate
UserModifierUpdate
}
type UserModifierCreate struct {
CreatorID string
CreatorRole string
CreatorIP string
CreatorUser *User
}
type UserModifierUpdate struct {
UpdaterID string
UpdaterRole string
UpdaterIP string
UpdaterUser *User
}
func NewUserModifierCreate(r *http.Request) *UserModifierCreate {
var claims jwt.MapClaims
if r.Context().Value("user") != nil {
claims = r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
}
return &UserModifierCreate{
CreatorID: claims["user_id"].(string),
CreatorRole: claims["role"].(string),
CreatorIP: r.RemoteAddr,
}
}
func (um *UserModifierCreate) CreatedBy() *User {
return um.CreatorUser
}
func (um *UserModifierCreate) get(db *Database) error {
switch um.CreatorRole {
case "participant":
var participant Participant
if err := db._db.Preload("User").First(&participant, um.CreatorID).Error; err != nil {
return err
}
um.CreatorUser = participant.User
case "school":
var school School
if err := db._db.Preload("User").First(&school, um.CreatorID).Error; err != nil {
return err
}
um.CreatorUser = school.User
case "subscriber":
um.CreatorUser = &SubscriberUser
case "administrator":
um.CreatorUser = &AdministratorUser
default:
return errors.New("Undefined user!")
}
return nil
}
func NewUserModifierUpdate(r *http.Request) *UserModifierUpdate {
var claims jwt.MapClaims
if r.Context().Value("user") != nil {
claims = r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
}
return &UserModifierUpdate{
UpdaterID: claims["user_id"].(string),
UpdaterRole: claims["role"].(string),
UpdaterIP: r.RemoteAddr,
}
}
func (um *UserModifierUpdate) UpdatedBy() *User {
return um.UpdaterUser
}
func (um *UserModifierUpdate) get(db *Database) (*User, error) {
switch um.UpdaterRole {
case "participant":
var participant Participant
if err := db._db.Preload("User").First(&participant, um.UpdaterID).Error; err != nil {
return nil, err
}
return participant.User, nil
case "school":
var school School
if err := db._db.Preload("User").First(&school, um.UpdaterID).Error; err != nil {
return nil, err
}
return school.User, nil
case "subscriber":
return &SubscriberUser, nil
case "administrator":
return &AdministratorUser, nil
default:
return nil, errors.New("Undefined user!")
}
}

47
orm/usermodifier.go Normal file
View file

@ -0,0 +1,47 @@
package orm
type Modifier interface {
SetCreatorID(id uint)
SetUpdaterID(id uint)
SetCreatorRole(role string)
SetUpdaterRole(role string)
SetCreatorIP(addr string)
SetUpdaterIP(addr string)
}
type UserModifier struct {
CreatorID uint
UpdaterID uint
CreatorRole string
UpdaterRole string
CreatorIP string
UpdaterIP string
Creator *User
Updater *User
}
func (um UserModifier) CreatedBy() *User {
switch um.CreatorRole {
case "administrator":
return &AdministratorUser
case "subscriber":
return &SubscriberUser
}
return um.Creator
}
func (um UserModifier) UpdatedBy() *User {
switch um.UpdaterRole {
case "administrator":
return &AdministratorUser
case "subscriber":
return &SubscriberUser
}
return um.Updater
}

View file

@ -0,0 +1,11 @@
{{ define "content" }}
<div class="container">
<h1 class="border-bottom">Errore</h1>
<p>
Si è verificato un errore durante la creazione o l'aggiornamento di un partecipante: <strong>{{.Data}}</strong>
</p>
<p>
Clicca {{create "School"|anchor "qui"}} per tornare al modulo di iscrizione.
</p>
</div>
{{ end }}

View file

@ -9,7 +9,7 @@
<form action="/login" method="post">
<div class="form-group">
<label for="username">Nome utente</label>
<input type="text" class="form-control uppercase" id="username" name="username" placeholder="Nome utente" required autofocus="" />
<input type="text" class="form-control" id="username" name="username" placeholder="Nome utente" required autofocus="" />
</div>
<div class="form-group">
<label for="password">Password</label>