Quick prototyping of user authentication/authorization
This commit is contained in:
parent
945a2a29dd
commit
a33cd9ac2d
9 changed files with 94 additions and 474 deletions
|
@ -298,7 +298,7 @@ func modelHandler(model string, pattern PathPattern) http.Handler {
|
|||
|
||||
func homeHandler() http.Handler {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/questions?format=html&tpl_layout=base&tpl_content=questions", http.StatusSeeOther)
|
||||
http.Redirect(w, r, "/contests?format=html&tpl_layout=base&tpl_content=contests", http.StatusSeeOther)
|
||||
}
|
||||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
|
|
@ -1,463 +0,0 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/remogatto/prettytest"
|
||||
"gogs.carducci-dante.gov.it/karmen/core/config"
|
||||
"gogs.carducci-dante.gov.it/karmen/core/orm"
|
||||
"gogs.carducci-dante.gov.it/karmen/core/renderer"
|
||||
)
|
||||
|
||||
var (
|
||||
token string
|
||||
)
|
||||
|
||||
// Start of setup
|
||||
|
||||
type testSuite struct {
|
||||
prettytest.Suite
|
||||
}
|
||||
|
||||
func TestRunner(t *testing.T) {
|
||||
prettytest.Run(
|
||||
t,
|
||||
new(testSuite),
|
||||
)
|
||||
}
|
||||
|
||||
func (t *testSuite) BeforeAll() {
|
||||
|
||||
var (
|
||||
db *gorm.DB
|
||||
err error
|
||||
)
|
||||
|
||||
// Initialize the ORM
|
||||
|
||||
connected := false
|
||||
for !connected {
|
||||
time.Sleep(10 * time.Second)
|
||||
db, err = orm.New("karmen:karmen@/karmen_test?charset=utf8&parseTime=True&loc=Local")
|
||||
if err != nil {
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
connected = true
|
||||
}
|
||||
|
||||
orm.Use(db)
|
||||
orm.AutoMigrate()
|
||||
|
||||
// Initialize the renderers
|
||||
|
||||
htmlRenderer, err := renderer.NewHTMLRenderer("./testdata/templates/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
jsonRenderer, err := renderer.NewJSONRenderer()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
csvRenderer, err := renderer.NewCSVRenderer()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
renderer.Render = make(map[string]func(http.ResponseWriter, *http.Request, interface{}, ...url.Values))
|
||||
|
||||
renderer.Render["html"] = func(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) {
|
||||
htmlRenderer.Render(w, r, data, options...)
|
||||
}
|
||||
|
||||
renderer.Render["json"] = func(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) {
|
||||
jsonRenderer.Render(w, r, data, options...)
|
||||
}
|
||||
|
||||
renderer.Render["csv"] = func(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) {
|
||||
csvRenderer.Render(w, r, data, options...)
|
||||
}
|
||||
|
||||
// Load the configuration
|
||||
|
||||
err = config.ReadFile("testdata/config.yaml", config.Config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
config.Config.LogLevel = config.LOG_LEVEL_OFF
|
||||
|
||||
req, err := http.NewRequest("GET", "/get_token", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req.SetBasicAuth("admin", "admin")
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
tokenHandler().ServeHTTP(rr, req)
|
||||
|
||||
var data struct {
|
||||
Token string
|
||||
UserID string
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(rr.Body.Bytes(), &data); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
token = data.Token
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestGetTeachersHTML() {
|
||||
req, err := http.NewRequest("GET", "/teachers?format=html&tpl_layout=base&tpl_content=teachers", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pattern := PathPattern{
|
||||
"/%s",
|
||||
"/%s?format=html&tpl_layout=base&tpl_content=%s",
|
||||
[]string{"GET"},
|
||||
}
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
modelHandler("teachers", pattern).ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
|
||||
if !t.Failed() {
|
||||
t.True(strings.Contains(rr.Body.String(), "DELLE ROSE"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestGetTeachersJSON() {
|
||||
var (
|
||||
teachers []*orm.Teacher
|
||||
response renderer.JsonResponse
|
||||
)
|
||||
|
||||
req, err := http.NewRequest("GET", "/api/teachers?format=json", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pattern := PathPattern{
|
||||
"/api/%s",
|
||||
"/%s/%d?format=json",
|
||||
[]string{"GET"},
|
||||
}
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
modelHandler("teachers", pattern).ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
t.Nil(err)
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(response.Result, &teachers)
|
||||
t.Nil(err)
|
||||
t.Equal("AGOSTINO", teachers[0].Surname)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestDeleteActivityJSON() {
|
||||
var response renderer.JsonResponse
|
||||
|
||||
req, err := http.NewRequest("DELETE", fmt.Sprintf("/api/activities/%d/delete?format=json", 1), nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
pattern := PathPattern{"/api/%s/{id}/delete", "", []string{"DELETE"}}
|
||||
router := mux.NewRouter()
|
||||
router.Handle("/api/activities/{id}/delete", modelHandler("activities", pattern))
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
t.Nil(err)
|
||||
if !t.Failed() {
|
||||
t.Equal("1", string(response.Result))
|
||||
}
|
||||
}
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
}
|
||||
|
||||
func (t *testSuite) TestGetTeacherJSON() {
|
||||
var (
|
||||
teacher *orm.Teacher
|
||||
response renderer.JsonResponse
|
||||
)
|
||||
|
||||
req, err := http.NewRequest("GET", "/api/teachers/9?format=json", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pattern := PathPattern{"/api/%s/{id}", "", []string{"GET"}}
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.Handle("/api/teachers/{id}", modelHandler("teachers", pattern))
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
t.Nil(err)
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(response.Result, &teacher)
|
||||
t.Nil(err)
|
||||
t.Equal("FRANCESCHINI", teacher.Surname)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestGetTeachersCSV() {
|
||||
var response renderer.JsonResponse
|
||||
|
||||
req, err := http.NewRequest("GET", "/api/teachers?format=csv", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pattern := PathPattern{
|
||||
"/api/%s",
|
||||
"/%s/%d?format=csv",
|
||||
[]string{"GET"},
|
||||
}
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
modelHandler("teachers", pattern).ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
t.Nil(err)
|
||||
if !t.Failed() {
|
||||
t.True(strings.Contains(string(response.Result), "AGOSTINO"))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestGetErrorJSON() {
|
||||
var (
|
||||
response renderer.JsonResponse
|
||||
)
|
||||
|
||||
req, err := http.NewRequest("GET", "/api/teacher/100?format=json", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pattern := PathPattern{"/api/%s/{id}", "/%s?format=json", []string{"GET"}}
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
modelHandler("teachers", pattern).ServeHTTP(rr, req)
|
||||
|
||||
err = json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
t.Nil(err)
|
||||
t.Equal("record not found", string(response.Error))
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestPostErrorJSON() {
|
||||
var (
|
||||
response renderer.JsonResponse
|
||||
)
|
||||
|
||||
teacher := getTeacherJSON(1)
|
||||
teacher.Name = "Mario"
|
||||
teacher.Surname = "ROSSI"
|
||||
|
||||
data, err := json.Marshal(teacher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", "/api/teachers/0/update?format=json", bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
pattern := PathPattern{"/api/%s/{id}/update", "", []string{"POST"}}
|
||||
router := mux.NewRouter()
|
||||
router.Handle("/api/teachers/{id}/update", modelHandler("teachers", pattern))
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusInternalServerError, rr.Code)
|
||||
|
||||
err = json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
t.Nil(err)
|
||||
t.Equal("record not found", string(response.Error))
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestAddTeacherJSON() {
|
||||
var (
|
||||
response renderer.JsonResponse
|
||||
id uint
|
||||
)
|
||||
|
||||
teacher := new(orm.Teacher)
|
||||
teacher.Name = "Mario"
|
||||
teacher.Surname = "ROSSI"
|
||||
|
||||
data, err := json.Marshal(teacher)
|
||||
t.Nil(err)
|
||||
|
||||
req, err := http.NewRequest("POST", "/api/teachers/add", bytes.NewBuffer(data))
|
||||
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pattern := PathPattern{
|
||||
"/api/%s/add",
|
||||
"",
|
||||
[]string{"POST"},
|
||||
}
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
modelHandler("teachers", pattern).ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
t.Nil(err)
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(response.Result, &id)
|
||||
t.Nil(err)
|
||||
t.Equal(uint(10), id)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestUpdateTeacherJSON() {
|
||||
teacher := getTeacherJSON(1)
|
||||
teacher.Name = "Mario"
|
||||
teacher.Surname = "ROSSI"
|
||||
|
||||
data, err := json.Marshal(teacher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("/api/teachers/%d/update?format=json", teacher.ID), bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
pattern := PathPattern{"/api/%s/{id}/update", "", []string{"POST"}}
|
||||
router := mux.NewRouter()
|
||||
router.Handle("/api/teachers/{id}/update", modelHandler("teachers", pattern))
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
|
||||
if !t.Failed() {
|
||||
dbTeacher := getTeacherJSON(1)
|
||||
t.Equal("ROSSI", dbTeacher.Surname)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func getTeacherJSON(id uint) *orm.Teacher {
|
||||
var (
|
||||
teacher *orm.Teacher
|
||||
response renderer.JsonResponse
|
||||
)
|
||||
|
||||
req, err := http.NewRequest("GET", fmt.Sprintf("/api/teachers/%d?format=json", id), nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pattern := PathPattern{"/api/%s/{id}", "", []string{"GET"}}
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.Handle("/api/teachers/{id}", modelHandler("teachers", pattern))
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
err = json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = json.Unmarshal(response.Result, &teacher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return teacher
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestGetDepartmentJSON() {
|
||||
var (
|
||||
department *orm.Department
|
||||
response renderer.JsonResponse
|
||||
)
|
||||
|
||||
req, err := http.NewRequest("GET", "/api/departments/1?format=json", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pattern := PathPattern{"/api/%s/{id}", "", []string{"GET"}}
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.Handle("/api/departments/{id}", modelHandler("departments", pattern))
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
t.Nil(err)
|
||||
if !t.Failed() {
|
||||
err := json.Unmarshal(response.Result, &department)
|
||||
t.Nil(err)
|
||||
t.Equal("LINGUE STRANIERE", department.Name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
"time"
|
||||
|
||||
"git.andreafazzi.eu/andrea/oef/config"
|
||||
"git.andreafazzi.eu/andrea/oef/orm"
|
||||
"git.andreafazzi.eu/andrea/oef/renderer"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
@ -54,11 +55,20 @@ func loginHandler() http.Handler {
|
|||
return http.HandlerFunc(fn)
|
||||
}
|
||||
|
||||
// FIXME: This is an hack for fast prototyping: users should have
|
||||
// their own table on DB.
|
||||
func checkCredential(username string, password string) (*User, error) {
|
||||
var participant orm.Participant
|
||||
|
||||
if username == config.Config.Admin.Username && password == config.Config.Admin.Password {
|
||||
return &User{username, true}, nil
|
||||
}
|
||||
|
||||
if err := orm.DB().Where("username = ? AND password = ?", username, password).First(&participant).Error; err != nil {
|
||||
return nil, errors.New("Authentication failed!")
|
||||
} else {
|
||||
return &User{username, false}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getToken(username string, password string) ([]byte, error) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"time"
|
||||
|
||||
"git.andreafazzi.eu/andrea/oef/renderer"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
|
@ -82,11 +83,29 @@ func (c *Contest) Read(args map[string]string, r *http.Request) (interface{}, er
|
|||
|
||||
func (c *Contest) ReadAll(args map[string]string, r *http.Request) (interface{}, error) {
|
||||
var contests []*Contest
|
||||
|
||||
claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
|
||||
|
||||
if claims["admin"].(bool) {
|
||||
if err := DB().Order("created_at").Find(&contests).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return contests, nil
|
||||
}
|
||||
}
|
||||
|
||||
participant := &Participant{}
|
||||
|
||||
if err := DB().Where("username = ?", claims["name"].(string)).First(&participant).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := DB().Debug().Order("created_at").Find(&participant.Contests).Error; err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return participant.Contests, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Contest) Update(args map[string]string, r *http.Request) (interface{}, error) {
|
||||
if r.Method == "GET" {
|
||||
|
|
|
@ -2,11 +2,13 @@ package orm
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"git.andreafazzi.eu/andrea/oef/renderer"
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/sethvargo/go-password/password"
|
||||
)
|
||||
|
||||
type Participant struct {
|
||||
|
@ -25,12 +27,45 @@ type Participant struct {
|
|||
AllContests []*Contest `gorm:"-"`
|
||||
}
|
||||
|
||||
func (model *Participant) sanitize(s string) string {
|
||||
lower := strings.ToLower(s)
|
||||
r := strings.NewReplacer("'", "", "-", "", " ", "", "ò", "o", "ì", "i")
|
||||
return r.Replace(lower)
|
||||
}
|
||||
|
||||
func (model *Participant) genUsername() error {
|
||||
model.Username = 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) String() string {
|
||||
return fmt.Sprintf("%s %s", strings.ToUpper(model.Lastname), strings.Title(strings.ToLower(model.Firstname)))
|
||||
}
|
||||
|
||||
func (model *Participant) BeforeSave(tx *gorm.DB) error {
|
||||
if err := model.genUsername(); err != nil {
|
||||
return err
|
||||
}
|
||||
if model.Password == "" {
|
||||
if err := model.genPassword(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *Participant) Create(args map[string]string, r *http.Request) (interface{}, error) {
|
||||
if r.Method == "GET" {
|
||||
participant := new(Participant)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
"github.com/jinzhu/inflection"
|
||||
yml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
@ -46,9 +47,19 @@ var (
|
|||
"pluralize": pluralize,
|
||||
"lower": lower,
|
||||
"trim": trim,
|
||||
"username": username,
|
||||
"isAdmin": isAdmin,
|
||||
}
|
||||
)
|
||||
|
||||
func username(claims jwt.MapClaims) string {
|
||||
return claims["name"].(string)
|
||||
}
|
||||
|
||||
func isAdmin(claims jwt.MapClaims) bool {
|
||||
return claims["admin"].(bool)
|
||||
}
|
||||
|
||||
func trim(text string) string {
|
||||
if len(text) > MaxTextLength {
|
||||
return text[0:MaxTextLength] + "…"
|
||||
|
|
|
@ -35,6 +35,7 @@ type PDFRenderer struct{}
|
|||
type htmlTemplateData struct {
|
||||
Data interface{}
|
||||
Options url.Values
|
||||
Claims jwt.MapClaims
|
||||
}
|
||||
|
||||
type JsonResponse struct {
|
||||
|
@ -239,22 +240,24 @@ func (rend *HTMLRenderer) writeError(w http.ResponseWriter, r *http.Request, dat
|
|||
|
||||
func (rend *HTMLRenderer) Render(w http.ResponseWriter, r *http.Request, data interface{}, options ...url.Values) {
|
||||
if data != nil && isErrorType(data) {
|
||||
rend.writeError(w, r, &htmlTemplateData{data.(error), nil})
|
||||
rend.writeError(w, r, &htmlTemplateData{data.(error), nil, nil})
|
||||
} else {
|
||||
t, ok := rend.templates[options[0]["tpl_content"][0]]
|
||||
if !ok {
|
||||
err := fmt.Errorf("Template %s not found", options[0]["tpl_content"][0])
|
||||
rend.writeError(w, r, &htmlTemplateData{err, nil})
|
||||
rend.writeError(w, r, &htmlTemplateData{err, nil, nil})
|
||||
}
|
||||
|
||||
var claims jwt.MapClaims
|
||||
|
||||
if r.Context().Value("user") != nil {
|
||||
log.Println("Current user is", r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)["name"])
|
||||
claims = r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
err := t.ExecuteTemplate(w, options[0]["tpl_layout"][0], &htmlTemplateData{data, options[0]})
|
||||
err := t.ExecuteTemplate(w, options[0]["tpl_layout"][0], &htmlTemplateData{data, options[0], claims})
|
||||
if err != nil {
|
||||
rend.writeError(w, r, &htmlTemplateData{err, nil})
|
||||
rend.writeError(w, r, &htmlTemplateData{err, nil, nil})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,15 @@
|
|||
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<a class="nav-item nav-link {{.Options|active "Contest"}}" href="{{all "Contest"}}">Gare</a>
|
||||
{{if (.Claims|isAdmin)}}
|
||||
<a class="nav-item nav-link {{.Options|active "Question"}}" href="{{all "Question"}}">Domande</a>
|
||||
<a class="nav-item nav-link {{.Options|active "Answer"}}" href="{{all "Answer"}}">Risposte</a>
|
||||
<a class="nav-item nav-link {{.Options|active "Participant"}}" href="{{all "Participant"}}">Partecipanti</a>
|
||||
{{end}}
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a class="nav-link" href="/logout">Esci</a></li>
|
||||
<li><a class="nav-link" href="/logout">Disconnetti {{.Claims|username}}</a></li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</nav>
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
|
||||
<h2 class="karmen-relation-header">Informazioni generali</h2>
|
||||
<p>
|
||||
Questa scheda contiene la informazioni relative al partecipante <strong>{{.Data|string}}</strong>.
|
||||
Il nome utente del partecipante è <strong>{{.Data.Username}}</strong>
|
||||
</p>
|
||||
<p>
|
||||
La sua password è <strong>{{.Data.Password}}</strong>
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
|
Loading…
Reference in a new issue