Decoupling user credential from participant model
This commit is contained in:
parent
17f1be188e
commit
43dd305835
10 changed files with 475 additions and 37 deletions
|
@ -15,8 +15,8 @@ import (
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type UserToken struct {
|
||||||
Name string
|
Username string
|
||||||
Admin bool
|
Admin bool
|
||||||
Role string
|
Role string
|
||||||
UserID string
|
UserID string
|
||||||
|
@ -88,17 +88,17 @@ func loginHandler() http.Handler {
|
||||||
|
|
||||||
// FIXME: This is an hack for fast prototyping: users should have
|
// FIXME: This is an hack for fast prototyping: users should have
|
||||||
// their own table on DB.
|
// their own table on DB.
|
||||||
func checkCredential(username string, password string) (*User, error) {
|
func checkCredential(username string, password string) (*UserToken, error) {
|
||||||
var participant orm.Participant
|
var participant orm.Participant
|
||||||
|
|
||||||
if username == config.Config.Admin.Username && password == config.Config.Admin.Password {
|
if username == config.Config.Admin.Username && password == config.Config.Admin.Password {
|
||||||
return &User{username, true, "administrator", "0"}, nil
|
return &UserToken{username, true, "administrator", "0"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := orm.DB().Where("username = ? AND password = ?", username, password).First(&participant).Error; err != nil {
|
if err := orm.DB().Where("username = ? AND password = ?", username, password).First(&participant).Error; err != nil {
|
||||||
return nil, errors.New("Authentication failed!")
|
return nil, errors.New("Authentication failed!")
|
||||||
} else {
|
} else {
|
||||||
return &User{username, false, "participant", strconv.Itoa(int(participant.ID))}, nil
|
return &UserToken{username, false, "participant", strconv.Itoa(int(participant.ID))}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ func getToken(username string, password string) ([]byte, error) {
|
||||||
/* Set token claims */
|
/* Set token claims */
|
||||||
claims := make(map[string]interface{})
|
claims := make(map[string]interface{})
|
||||||
claims["admin"] = user.Admin
|
claims["admin"] = user.Admin
|
||||||
claims["name"] = user.Name
|
claims["username"] = user.Username
|
||||||
claims["role"] = user.Role
|
claims["role"] = user.Role
|
||||||
claims["user_id"] = user.UserID
|
claims["user_id"] = user.UserID
|
||||||
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
||||||
|
@ -141,7 +141,7 @@ func tokenHandler() http.Handler {
|
||||||
/* Set token claims */
|
/* Set token claims */
|
||||||
claims := make(map[string]interface{})
|
claims := make(map[string]interface{})
|
||||||
claims["admin"] = true
|
claims["admin"] = true
|
||||||
claims["name"] = user.Name
|
claims["name"] = user.Username
|
||||||
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
||||||
|
|
||||||
/* Create the token */
|
/* Create the token */
|
||||||
|
@ -154,7 +154,7 @@ func tokenHandler() http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
w.Write([]byte(fmt.Sprintf("{\"Token\":\"%s\",\"User\":\"%s\"}", tokenString, user.Name)))
|
w.Write([]byte(fmt.Sprintf("{\"Token\":\"%s\",\"User\":\"%s\"}", tokenString, user.Username)))
|
||||||
}
|
}
|
||||||
return http.HandlerFunc(fn)
|
return http.HandlerFunc(fn)
|
||||||
}
|
}
|
||||||
|
|
1
main.go
1
main.go
|
@ -31,6 +31,7 @@ var (
|
||||||
&orm.Contest{},
|
&orm.Contest{},
|
||||||
&orm.Participant{},
|
&orm.Participant{},
|
||||||
&orm.Response{},
|
&orm.Response{},
|
||||||
|
&orm.User{},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
201
oef_dev.sql
Normal file
201
oef_dev.sql
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
-- MariaDB dump 10.17 Distrib 10.4.8-MariaDB, for debian-linux-gnu (x86_64)
|
||||||
|
--
|
||||||
|
-- Host: localhost Database: oef_test
|
||||||
|
-- ------------------------------------------------------
|
||||||
|
-- Server version 10.4.8-MariaDB-1:10.4.8+maria~bionic
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||||
|
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||||
|
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `answers`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `answers`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `answers` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`created_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`updated_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`text` varchar(255) DEFAULT NULL,
|
||||||
|
`correct` tinyint(1) DEFAULT NULL,
|
||||||
|
`question_id` int(10) unsigned DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_answers_deleted_at` (`deleted_at`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `answers`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `answers` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `answers` DISABLE KEYS */;
|
||||||
|
INSERT INTO `answers` VALUES (1,'2019-11-13 15:44:39','2019-11-13 15:44:39',NULL,'la quantità di moneta che viene richiesta dalle imprese sotto forma di prestiti richiesti al sistema bancario',0,1),(2,'2019-11-14 11:48:06','2019-11-14 11:48:06',NULL,'la quantità di moneta richiesta dalla Banca Centrale quando mette in vendita dei titoli per ridurre la moneta in circolazione',0,1),(3,'2019-11-14 11:48:28','2019-11-14 11:48:28',NULL,'la quantità di moneta richiesta dalle famiglie per mantenere in forma liquida i loro risparmi',0,1),(4,'2019-11-14 11:49:05','2019-11-14 12:21:09',NULL,'la quantità di moneta richiesta dai soggetti del sistema economico per transazioni, per ragioni speculative o prudenziali o per altri motivi',1,1),(5,'2019-11-15 10:17:49','2019-11-15 10:17:49',NULL,'elevata differenziazione dei prodotti offerti',0,2),(6,'2019-11-15 10:18:14','2019-11-15 10:18:53',NULL,'trasparenza delle informazioni',1,2),(7,'2019-11-15 10:18:29','2019-11-15 10:18:29',NULL,'presenza di un solo consumatore',0,2),(8,'2019-11-15 10:18:44','2019-11-15 10:18:44',NULL,'presenza di un numero limitato di grandi produttori',0,2),(9,'2019-11-15 10:23:11','2019-11-15 10:23:11',NULL,'un ciclo economico',0,3),(10,'2019-11-15 10:23:24','2019-11-15 10:23:35',NULL,'l\'attività di trasformazione materiale di beni e servizi (input) in altri (output) al fine di accrescerne l\'utilità',1,3),(11,'2019-11-15 10:23:47','2019-11-15 10:23:47',NULL,'l\'insieme dei beni di produzione',0,3),(12,'2019-11-15 10:23:59','2019-11-15 10:23:59',NULL,'il risultato del lavoro dei dipendenti dell\'impresa',0,3);
|
||||||
|
/*!40000 ALTER TABLE `answers` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `contests`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `contests`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `contests` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`created_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`updated_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`category` varchar(255) DEFAULT NULL,
|
||||||
|
`start_date` timestamp NULL DEFAULT NULL,
|
||||||
|
`end_date` timestamp NULL DEFAULT NULL,
|
||||||
|
`start_time` timestamp NULL DEFAULT NULL,
|
||||||
|
`end_time` timestamp NULL DEFAULT NULL,
|
||||||
|
`date` timestamp NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_contests_deleted_at` (`deleted_at`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `contests`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `contests` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `contests` DISABLE KEYS */;
|
||||||
|
INSERT INTO `contests` VALUES (1,'2019-11-14 10:02:17','2019-11-18 15:57:14',NULL,'Regionale JUNIOR','','0000-00-00 00:00:00','0000-00-00 00:00:00','2020-04-01 10:00:00','2020-04-01 11:00:00','2020-04-01 10:00:00'),(2,'2019-11-15 10:15:57','2019-11-18 15:58:55',NULL,'Test Diagnostico','',NULL,NULL,'2019-11-15 13:00:00','2019-11-15 14:00:00','2019-11-15 13:00:00');
|
||||||
|
/*!40000 ALTER TABLE `contests` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `participants`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `participants`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `participants` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`created_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`updated_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`firstname` varchar(255) DEFAULT NULL,
|
||||||
|
`lastname` varchar(255) DEFAULT NULL,
|
||||||
|
`username` varchar(255) DEFAULT NULL,
|
||||||
|
`password` varchar(255) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_participants_deleted_at` (`deleted_at`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `participants`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `participants` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `participants` DISABLE KEYS */;
|
||||||
|
INSERT INTO `participants` VALUES (1,'2019-11-15 10:02:46','2019-11-18 15:58:55',NULL,'Mario','Rossi','mario.rossi','EqAs1z7M'),(2,'2019-11-18 12:00:07','2019-11-18 15:57:14',NULL,'Luigi','BIANCHI','luigi.bianchi','FpWJj89n'),(3,'2019-11-18 12:01:55','2019-11-18 12:12:26',NULL,'Francesco','VERDI','francesco.verdi','MiJ9Ig4L'),(4,'2019-11-18 15:57:36','2019-11-18 15:57:36',NULL,'Franco','neri','franco.neri','YtGGU28p');
|
||||||
|
/*!40000 ALTER TABLE `participants` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `questions`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `questions`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `questions` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`created_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`updated_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`text` varchar(255) DEFAULT NULL,
|
||||||
|
`contest_id` int(10) unsigned DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_questions_deleted_at` (`deleted_at`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `questions`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `questions` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `questions` DISABLE KEYS */;
|
||||||
|
INSERT INTO `questions` VALUES (1,'2019-11-13 14:45:17','2019-11-14 12:21:09',NULL,'Cosa si intende per domanda di moneta?',1),(2,'2019-11-15 10:17:24','2019-11-15 10:18:53',NULL,'È una caratteristica della concorrenza perfetta',2),(3,'2019-11-15 10:21:14','2019-11-15 10:23:35',NULL,'La produzione è',2);
|
||||||
|
/*!40000 ALTER TABLE `questions` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `responses`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `responses`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `responses` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`created_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`updated_at` timestamp NULL DEFAULT NULL,
|
||||||
|
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_responses_deleted_at` (`deleted_at`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `responses`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `responses` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `responses` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `responses` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `subscriptions`
|
||||||
|
--
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `subscriptions`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
CREATE TABLE `subscriptions` (
|
||||||
|
`participant_id` int(10) unsigned NOT NULL,
|
||||||
|
`contest_id` int(10) unsigned NOT NULL,
|
||||||
|
PRIMARY KEY (`participant_id`,`contest_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dumping data for table `subscriptions`
|
||||||
|
--
|
||||||
|
|
||||||
|
LOCK TABLES `subscriptions` WRITE;
|
||||||
|
/*!40000 ALTER TABLE `subscriptions` DISABLE KEYS */;
|
||||||
|
INSERT INTO `subscriptions` VALUES (1,2),(2,1),(2,2),(3,2);
|
||||||
|
/*!40000 ALTER TABLE `subscriptions` ENABLE KEYS */;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||||
|
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
|
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||||
|
|
||||||
|
-- Dump completed on 2019-11-18 16:05:30
|
|
@ -8,17 +8,19 @@ import (
|
||||||
|
|
||||||
"git.andreafazzi.eu/andrea/oef/renderer"
|
"git.andreafazzi.eu/andrea/oef/renderer"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/sethvargo/go-password/password"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Participant struct {
|
type Participant struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
|
|
||||||
|
UserID uint
|
||||||
|
|
||||||
Firstname string
|
Firstname string
|
||||||
Lastname string
|
Lastname string
|
||||||
|
|
||||||
Username string
|
FiscalCode string
|
||||||
Password string
|
|
||||||
|
User *User
|
||||||
|
|
||||||
Responses []*Response
|
Responses []*Response
|
||||||
|
|
||||||
|
@ -35,19 +37,8 @@ func (model *Participant) sanitize(s string) string {
|
||||||
return r.Replace(lower)
|
return r.Replace(lower)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (model *Participant) genUsername() error {
|
func (model *Participant) username() string {
|
||||||
model.Username = strings.Join([]string{model.sanitize(model.Firstname), model.sanitize(model.Lastname)}, ".")
|
return strings.Join([]string{model.sanitize(model.Firstname), model.sanitize(model.Lastname)}, ".")
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (model *Participant) genPassword() error {
|
|
||||||
password, err := password.Generate(8, 2, 0, false, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
model.Password = password
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (model *Participant) GetID() uint { return model.ID }
|
func (model *Participant) GetID() uint { return model.ID }
|
||||||
|
@ -57,14 +48,11 @@ func (model *Participant) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (model *Participant) BeforeSave(tx *gorm.DB) error {
|
func (model *Participant) BeforeSave(tx *gorm.DB) error {
|
||||||
if err := model.genUsername(); err != nil {
|
var user User
|
||||||
|
if err := tx.FirstOrCreate(&user, &User{Username: model.username()}).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if model.Password == "" {
|
model.UserID = user.ID
|
||||||
if err := model.genPassword(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +72,13 @@ func (model *Participant) AfterSave(tx *gorm.DB) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (model *Participant) AfterDelete(tx *gorm.DB) error {
|
||||||
|
if err := tx.Unscoped().Delete(model.User).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (model *Participant) Create(args map[string]string, r *http.Request) (interface{}, error) {
|
func (model *Participant) Create(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
participant := new(Participant)
|
participant := new(Participant)
|
||||||
|
@ -110,7 +105,7 @@ func (model *Participant) Read(args map[string]string, r *http.Request) (interfa
|
||||||
|
|
||||||
id := args["id"]
|
id := args["id"]
|
||||||
|
|
||||||
if err := DB().Preload("Responses").Preload("Contests").First(&participant, id).Error; err != nil {
|
if err := DB().Preload("User").Preload("Responses").Preload("Contests").First(&participant, id).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +182,9 @@ func (model *Participant) Delete(args map[string]string, r *http.Request) (inter
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateParticipant(participant *Participant) (*Participant, error) {
|
func CreateParticipant(participant *Participant) (*Participant, error) {
|
||||||
|
if err := DB().Where(participant.ContestIDs).Find(&participant.Contests).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if err := DB().Create(participant).Error; err != nil {
|
if err := DB().Create(participant).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
147
orm/user.go
Normal file
147
orm/user.go
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
package orm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.andreafazzi.eu/andrea/oef/renderer"
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
|
||||||
|
"github.com/sethvargo/go-password/password"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
gorm.Model
|
||||||
|
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
Role string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (model *User) GetID() uint { return model.ID }
|
||||||
|
|
||||||
|
func (model *User) String() string {
|
||||||
|
return "" // Please implement this.
|
||||||
|
}
|
||||||
|
|
||||||
|
func genPassword() (string, error) {
|
||||||
|
password, err := password.Generate(8, 2, 0, false, true)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return password, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (model *User) BeforeSave(tx *gorm.DB) error {
|
||||||
|
if model.Password == "" {
|
||||||
|
password, err := genPassword()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
model.Password = password
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (model *User) Create(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
|
if r.Method == "GET" {
|
||||||
|
user := new(User)
|
||||||
|
// if err := DB().Find(&user.AllContests).Error; err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
return user, nil
|
||||||
|
} else {
|
||||||
|
user := new(User)
|
||||||
|
err := renderer.Decode(user, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user, err = CreateUser(user)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (model *User) Read(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
|
var user User
|
||||||
|
|
||||||
|
id := args["id"]
|
||||||
|
|
||||||
|
if err := DB(). /*.Preload("Something")*/ First(&user, id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (model *User) ReadAll(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
|
var users []*User
|
||||||
|
if err := DB(). /*.Preload("Something")*/ Order("created_at").Find(&users).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (model *User) Update(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
|
if r.Method == "GET" {
|
||||||
|
result, err := model.Read(args, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
user := result.(*User)
|
||||||
|
|
||||||
|
// if err := DB().Find(&user.AllElements).Error; err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// user.SelectedElement = make(map[uint]string)
|
||||||
|
// user.SelectedElement[user.ElementID] = "selected"
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
} else {
|
||||||
|
user, err := model.Read(args, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = renderer.Decode(user, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_, err = SaveUser(user)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user, err = model.Read(args, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return user.(*User), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (model *User) Delete(args map[string]string, r *http.Request) (interface{}, error) {
|
||||||
|
user, err := model.Read(args, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := DB().Unscoped().Delete(user.(*User)).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return user.(*User), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateUser(user *User) (*User, error) {
|
||||||
|
if err := DB().Create(user).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SaveUser(user interface{}) (interface{}, error) {
|
||||||
|
if err := DB(). /*.Omit("Something")*/ Save(user).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return user, nil
|
||||||
|
}
|
|
@ -30,6 +30,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{$options := ` { name: "FiscalCode",id: "participant_fiscalcode",label: "Codice fiscale del partecipante",placeholder: "Inserire il codice fiscale",type: "text",required: "true"} `}}
|
||||||
|
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "FiscalCode") "update" $update}}
|
||||||
|
|
||||||
{{$options := ` { name: "contest_ids", id: "contest_ids", label: "Gare a cui il partecipante è iscritto", title: "Seleziona le gare", multiple: "true"}`}}
|
{{$options := ` { name: "contest_ids", id: "contest_ids", label: "Gare a cui il partecipante è iscritto", title: "Seleziona le gare", multiple: "true"}`}}
|
||||||
{{template "select" dict "options" ($options|yaml) "data" (.Data|field "AllContests") "selected" (.Data|field "SelectedContest") "update" $update "form" $form}}
|
{{template "select" dict "options" ($options|yaml) "data" (.Data|field "AllContests") "selected" (.Data|field "SelectedContest") "update" $update "form" $form}}
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
|
|
||||||
<h2 class="karmen-relation-header">Informazioni generali</h2>
|
<h2 class="karmen-relation-header">Informazioni generali</h2>
|
||||||
<p>
|
<p>
|
||||||
Il nome utente del partecipante è <strong>{{.Data.Username}}</strong>
|
Il nome utente del partecipante è {{if .Data.User}}<strong>{{.Data.User.Username}}</strong>{{end}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
La sua password è <strong>{{.Data.Password}}</strong>
|
La sua password è {{if .Data.User}}<strong>{{.Data.User.Password}}</strong>{{end}}
|
||||||
</p>
|
</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
|
|
33
templates/users.html.tpl
Normal file
33
templates/users.html.tpl
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{{ define "content" }}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{{$options := `
|
||||||
|
title: "Users"
|
||||||
|
buttonTitle: "Crea nuovo User"
|
||||||
|
`}}
|
||||||
|
|
||||||
|
{{template "read_all_header" dict "options" ($options | yaml) "lengthData" (len .Data) "modelPath" (create "User")}}
|
||||||
|
{{template "search_input"}}
|
||||||
|
|
||||||
|
{{if not .}}
|
||||||
|
{{template "display_no_elements"}}
|
||||||
|
{{else}}
|
||||||
|
<div class="list-group" id="myUL">
|
||||||
|
{{range $element := .Data}}
|
||||||
|
<a class="list-group-item list-group-item-action" href={{$element.ID|show "User"}}>
|
||||||
|
<span class="fa fa-user"></span>
|
||||||
|
{{$element|string}}
|
||||||
|
<div class="text-right">
|
||||||
|
{{$options := `noElements: "no subelements"`}}
|
||||||
|
{{/*template "small" dict "options" ($options | yaml) "data" $element.SubElements*/}}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{{ end }}
|
28
templates/users_add_update.html.tpl
Normal file
28
templates/users_add_update.html.tpl
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{{ define "content" }}
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
{{$update := .Options.Get "update"}}
|
||||||
|
|
||||||
|
{{if $update}}
|
||||||
|
|
||||||
|
{{template "breadcrumb" toSlice "Users" (all "User") (.Data|string) (.Data.ID|show "User") "Aggiorna" "current"}}
|
||||||
|
{{else}}
|
||||||
|
{{template "breadcrumb" toSlice "Users" (all "User") "Aggiungi" "current"}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{template "add_update_header" dict "update" $update "addTitle" "Crea nuovo ELEMENTO" "updateTitle" (printf "Aggiorna ELEMENTO %s" (.Data|string))}}
|
||||||
|
{{$form := "form_add_update"}}
|
||||||
|
<form
|
||||||
|
class="needs-validation"
|
||||||
|
action="{{if $update}}{{.Data.ID|update "User"}}{{else}}{{create "User"}}{{end}}"
|
||||||
|
method="POST"
|
||||||
|
role="form"
|
||||||
|
id={{$form}}>
|
||||||
|
|
||||||
|
{{$options := ` { cancelTitle: "Annulla", saveTitle: "Salva", model: "User" } `}}
|
||||||
|
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
27
templates/users_show.html.tpl
Normal file
27
templates/users_show.html.tpl
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{{ define "content" }}
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
{{template "breadcrumb" toSlice "ELEMENTS" (all "User") (.Data|string) "current"}}
|
||||||
|
{{template "show_header" dict "title" (.Data|string) "updatePath" (.Data.ID|update "User") "deletePath" (.Data.ID|delete "User")}}
|
||||||
|
|
||||||
|
<h2 class="karmen-relation-header">GENERAL SECTION</h2>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
|
||||||
|
{{$options := `
|
||||||
|
title: "RELATIONS"
|
||||||
|
model: "MODEL"
|
||||||
|
icon: "ICON_CLASS"
|
||||||
|
`}}
|
||||||
|
|
||||||
|
{{$noElements := "NO ELEMENTS"}}
|
||||||
|
{{template "relation_list" dict "options" ($options|yaml) "data" .Data.RELATIONS "noElements" $noElements}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
Loading…
Reference in a new issue