Fix tests

This commit is contained in:
Andrea Fazzi 2020-01-17 11:06:28 +01:00
parent 06f96f1ccc
commit d85f66d256
4 changed files with 60 additions and 65 deletions

View file

@ -3,17 +3,19 @@ package config
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/url"
yaml "gopkg.in/yaml.v2"
"git.andreafazzi.eu/andrea/oef/reflect" "git.andreafazzi.eu/andrea/oef/reflect"
yaml "gopkg.in/yaml.v2"
) )
const ( const (
LOG_LEVEL_OFF = iota LOG_LEVEL_OFF = iota
LOG_LEVEL_INFO LOG_LEVEL_INFO
LOG_LEVEL_DEBUG LOG_LEVEL_DEBUG
)
const (
CreateLabel = iota CreateLabel = iota
ReadAllLabel ReadAllLabel
ReadLabel ReadLabel
@ -128,6 +130,20 @@ func (pp PathPattern) Path(model string) string {
return fmt.Sprintf(pp.PathPattern, model) return fmt.Sprintf(pp.PathPattern, model)
} }
func (c *ConfigT) ReadAllPath(model interface{}) string { func (c *ConfigT) ReadAllPath(model interface{}, format string) string {
return fmt.Sprintf(c.Handlers.PathPatterns[actions[ReadAllLabel]].PathPattern, reflect.ModelName(model)) return fmt.Sprintf(c.Handlers.PathPatterns[actions[ReadAllLabel]].PathPattern, reflect.ModelNameLowerPlural(model)) + "?" + c.query(model, format).Encode()
}
func (c *ConfigT) ReadAllPattern() PathPattern {
return c.Handlers.PathPatterns[actions[ReadAllLabel]]
}
func (c *ConfigT) query(model interface{}, format string) url.Values {
values := make(url.Values)
values.Add("format", format)
values.Add("tpl_content", reflect.ModelNameLowerPlural(model))
values.Add("tpl_layout", "base") // FIXME: use config value
return values
} }

View file

@ -45,16 +45,14 @@ type Handlers struct {
JWTHeaderMiddleware *jwtmiddleware.JWTMiddleware JWTHeaderMiddleware *jwtmiddleware.JWTMiddleware
Router *mux.Router Router *mux.Router
}
var (
permissions map[string]map[string]bool permissions map[string]map[string]bool
)
func init() {
permissions = make(map[string]map[string]bool, 0)
} }
// var (
// permissions map[string]map[string]bool
// )
// Generate CRUD handlers for models // Generate CRUD handlers for models
func (h *Handlers) generateModelHandlers(r *mux.Router, model interface{}) { func (h *Handlers) generateModelHandlers(r *mux.Router, model interface{}) {
// Install standard paths // Install standard paths
@ -86,7 +84,7 @@ func (h *Handlers) generateModelHandlers(r *mux.Router, model interface{}) {
)))).Methods(pattern.Methods...) )))).Methods(pattern.Methods...)
} }
// Set permissions for HTML patterns // Set permissions
for role, modelPermissions := range h.Config.Handlers.Permissions { for role, modelPermissions := range h.Config.Handlers.Permissions {
for m, perm := range modelPermissions { for m, perm := range modelPermissions {
@ -94,19 +92,19 @@ func (h *Handlers) generateModelHandlers(r *mux.Router, model interface{}) {
for _, p := range perm { for _, p := range perm {
for _, pattern := range h.Config.Handlers.PathPatterns { for _, pattern := range h.Config.Handlers.PathPatterns {
if pattern.Permission == p { if pattern.Permission == p {
if permissions[role] == nil { if h.permissions[role] == nil {
permissions[role] = make(map[string]bool) h.permissions[role] = make(map[string]bool)
} }
permissions[role][pattern.Path(reflect.ModelNameLowerPlural(model))] = true h.permissions[role][pattern.Path(reflect.ModelNameLowerPlural(model))] = true
} }
} }
for _, pattern := range DefaultAPIPathPatterns { for _, pattern := range DefaultAPIPathPatterns {
if pattern.Permission == p { if pattern.Permission == p {
if permissions[role] == nil { if h.permissions[role] == nil {
permissions[role] = make(map[string]bool) h.permissions[role] = make(map[string]bool)
} }
permissions[role][pattern.Path(reflect.ModelNameLowerPlural(model))] = true h.permissions[role][pattern.Path(reflect.ModelNameLowerPlural(model))] = true
} }
} }
@ -149,6 +147,8 @@ func NewHandlers(config *config.ConfigT, renderer map[string]renderer.Renderer,
SigningMethod: jwt.SigningMethodHS256, SigningMethod: jwt.SigningMethodHS256,
}) })
handlers.permissions = make(map[string]map[string]bool)
r := mux.NewRouter() r := mux.NewRouter()
// Authentication // Authentication
@ -183,9 +183,8 @@ func NewHandlers(config *config.ConfigT, renderer map[string]renderer.Renderer,
return handlers return handlers
} }
func (h *Handlers) NewReadAllRequest(model interface{}) (*http.Request, error) { func (h *Handlers) NewReadAllRequest(model interface{}, format string) (*http.Request, error) {
request, err := http.NewRequest("GET", h.Config.ReadAllPath(reflect.ModelNameLowerPlural(model)), nil) return http.NewRequest("GET", h.Config.ReadAllPath(model, format), nil)
return request, err
} }
func (h *Handlers) onError(w http.ResponseWriter, r *http.Request, err string) { func (h *Handlers) onError(w http.ResponseWriter, r *http.Request, err string) {
@ -243,12 +242,12 @@ func (h *Handlers) setFlashMessage(w http.ResponseWriter, r *http.Request, key s
return nil return nil
} }
func hasPermission(role, path string) bool { func (h *Handlers) hasPermission(role, path string) bool {
if permissions[role] == nil { if h.permissions[role] == nil {
return false return false
} }
return permissions[role][path] return h.permissions[role][path]
} }
func (h *Handlers) get(w http.ResponseWriter, r *http.Request, model string, pattern config.PathPattern) { func (h *Handlers) get(w http.ResponseWriter, r *http.Request, model string, pattern config.PathPattern) {
@ -260,11 +259,10 @@ func (h *Handlers) get(w http.ResponseWriter, r *http.Request, model string, pat
} else { } else {
claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims) claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
role := claims["role"].(string) role := claims["role"].(string)
if !hasPermission(role, pattern.Path(model)) { if !h.hasPermission(role, pattern.Path(model)) {
h.setFlashMessage(w, r, "notAuthorized") h.setFlashMessage(w, r, "notAuthorized")
h.Renderer[format].Render(w, r, h.CookieStore, fmt.Errorf("%s", "Errore di autorizzazione")) h.Renderer[format].Render(w, r, h.CookieStore, fmt.Errorf("%s", "Errore di autorizzazione"))
} else { } else {
data, err := getFn(h.Database, mux.Vars(r), w, r) data, err := getFn(h.Database, mux.Vars(r), w, r)
if err != nil { if err != nil {
h.Renderer[format].Render(w, r, h.CookieStore, err) h.Renderer[format].Render(w, r, h.CookieStore, err)
@ -291,7 +289,7 @@ func (h *Handlers) post(w http.ResponseWriter, r *http.Request, model string, pa
claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims) claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
role := claims["role"].(string) role := claims["role"].(string)
if !hasPermission(role, pattern.Path(model)) { if !h.hasPermission(role, pattern.Path(model)) {
h.Renderer[respFormat].Render(w, r, h.CookieStore, fmt.Errorf("%s", "Errore di autorizzazione")) h.Renderer[respFormat].Render(w, r, h.CookieStore, fmt.Errorf("%s", "Errore di autorizzazione"))
} else { } else {
data, err = postFn(h.Database, mux.Vars(r), w, r) data, err = postFn(h.Database, mux.Vars(r), w, r)
@ -320,7 +318,7 @@ func (h *Handlers) delete(w http.ResponseWriter, r *http.Request, model string,
claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims) claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
role := claims["role"].(string) role := claims["role"].(string)
if !hasPermission(role, pattern.Path(model)) { if !h.hasPermission(role, pattern.Path(model)) {
h.Renderer[respFormat].Render(w, r, h.CookieStore, fmt.Errorf("%s", "Errore di autorizzazione")) h.Renderer[respFormat].Render(w, r, h.CookieStore, fmt.Errorf("%s", "Errore di autorizzazione"))
} else { } else {
postFn, err := h.Database.GetFunc(pattern.Path(model)) postFn, err := h.Database.GetFunc(pattern.Path(model))
@ -354,7 +352,7 @@ func (h *Handlers) ReadAll(model interface{}) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) { fn := func(w http.ResponseWriter, r *http.Request) {
// Replace "api" prefix // Replace "api" prefix
// pattern.PathPattern = strings.Replace(pattern.PathPattern, "/api", "", -1) // pattern.PathPattern = strings.Replace(pattern.PathPattern, "/api", "", -1)
h.get(w, r, model, pattern) h.get(w, r, reflect.ModelNameLowerPlural(model), h.Config.ReadAllPattern())
} }
return http.HandlerFunc(fn) return http.HandlerFunc(fn)

View file

@ -3,11 +3,9 @@ package handlers
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"log" "log"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"strings"
"testing" "testing"
"time" "time"
@ -31,9 +29,11 @@ type testSuite struct {
prettytest.Suite prettytest.Suite
} }
func authenticate(request *http.Request, tokenString string, signingKey string) (*http.Request, error) { func login(request *http.Request, handlers *Handlers, username string, password string) (*http.Request, error) {
tokenString := requestToken(handlers, username, password)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(signingKey), nil return []byte(handlers.Config.Keys.JWTSigningKey), nil
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -44,17 +44,17 @@ func authenticate(request *http.Request, tokenString string, signingKey string)
} }
func requestToken(db *orm.Database, handlers *Handlers) string { func requestToken(handlers *Handlers, username string, password string) string {
req, err := http.NewRequest("GET", "/get_token", nil) req, err := http.NewRequest("GET", "/get_token", nil)
if err != nil { if err != nil {
panic(err) panic(err)
} }
req.SetBasicAuth("admin", "admin") req.SetBasicAuth(username, password)
rr := httptest.NewRecorder() rr := httptest.NewRecorder()
handlers.GetToken(db, []byte(db.Config.Keys.JWTSigningKey)).ServeHTTP(rr, req) handlers.GetToken(handlers.Database, []byte(handlers.Config.Keys.JWTSigningKey)).ServeHTTP(rr, req)
var data struct { var data struct {
Token string Token string
@ -95,7 +95,7 @@ func (t *testSuite) BeforeAll() {
for !connected { for !connected {
var err error var err error
time.Sleep(5 * time.Second) time.Sleep(2 * time.Second)
db, err = orm.NewDatabase(conf, orm.Models) db, err = orm.NewDatabase(conf, orm.Models)
if err != nil { if err != nil {
@ -148,46 +148,27 @@ func (t *testSuite) BeforeAll() {
conf.Handlers.APIPathPatterns = DefaultAPIPathPatterns conf.Handlers.APIPathPatterns = DefaultAPIPathPatterns
handlers = NewHandlers(conf, renderer, db, orm.Models) handlers = NewHandlers(conf, renderer, db, orm.Models)
token = requestToken(db, handlers)
} }
func (t *testSuite) TestReadAllContests() { func (t *testSuite) TestReadAllContests() {
req, err := handlers.NewReadAllRequest(&orm.Contest{}) req, err := handlers.NewReadAllRequest(&orm.Contest{}, "html")
if err != nil {
panic(err)
}
pattern := config.PathPattern{
"/%s",
"/%s?format=html&tpl_layout=base&tpl_content=%s",
[]string{"GET"}, PermissionReadAll,
}
rr := httptest.NewRecorder()
req, err = authenticate(req, token, conf.Keys.JWTSigningKey)
t.Nil(err) t.Nil(err)
if err != nil { req, err = login(req, handlers, "admin", "admin")
handlers.ReadAll(&Contest{}).ServeHTTP(rr, req) t.Nil(err)
if !t.Failed() {
rr := httptest.NewRecorder()
handlers.ReadAll(&orm.Contest{}).ServeHTTP(rr, req)
t.Equal(http.StatusOK, rr.Code) t.Equal(http.StatusOK, rr.Code)
if !t.Failed() { if !t.Failed() {
doc, err := goquery.NewDocumentFromResponse(rr.Result()) doc, err := goquery.NewDocumentFromReader(rr.Body)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
t.Equal(2, doc.Find(".list-group-item").Size())
// Find the review items
doc.Find(".sidebar-reviews article .content-block").Each(func(i int, s *goquery.Selection) {
// For each item found, get the band and title
band := s.Find("a").Text()
title := s.Find("i").Text()
fmt.Printf("Review %d: %s - %s\n", i, band, title)
})
t.True(strings.Contains(rr.Body.String(), "JUNIOR Contest"))
} }
} }

View file

@ -92,7 +92,7 @@ func (c *Contest) ReadAll(db *Database, args map[string]string, w http.ResponseW
var contests []*Contest var contests []*Contest
claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims) claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
if claims["admin"].(bool) { if claims["admin"].(bool) {
if err := db._db.Order("created_at").Find(&contests).Error; err != nil { if err := db._db.Order("created_at").Find(&contests).Error; err != nil {
return nil, err return nil, err