Protect responses from participants
This commit is contained in:
parent
6c1550e7fe
commit
b06eba6698
8 changed files with 122 additions and 3 deletions
|
@ -146,6 +146,10 @@ func (c *ConfigT) CreatePath(model interface{}, path, format string) string {
|
|||
return path + "?" + c.query(model, CreateLabel, format).Encode()
|
||||
}
|
||||
|
||||
func (c *ConfigT) UpdatePath(model interface{}, path, format string) string {
|
||||
return path + "?" + c.query(model, UpdateLabel, format).Encode()
|
||||
}
|
||||
|
||||
func (c *ConfigT) DeletePath(model interface{}, path, format string) string {
|
||||
return path + "?format=html"
|
||||
}
|
||||
|
@ -162,6 +166,10 @@ func (c *ConfigT) ReadPattern() PathPattern {
|
|||
return c.Handlers.PathPatterns[actions[ReadLabel]]
|
||||
}
|
||||
|
||||
func (c *ConfigT) UpdatePattern() PathPattern {
|
||||
return c.Handlers.PathPatterns[actions[UpdateLabel]]
|
||||
}
|
||||
|
||||
func (c *ConfigT) DeletePattern() PathPattern {
|
||||
return c.Handlers.PathPatterns[actions[DeleteLabel]]
|
||||
}
|
||||
|
@ -180,6 +188,9 @@ func (c *ConfigT) query(model interface{}, action int, format string) url.Values
|
|||
tplContent = reflect.ModelNameLowerPlural(model)
|
||||
case ReadLabel:
|
||||
tplContent = reflect.ModelNameLowerPlural(model) + "_show"
|
||||
case UpdateLabel:
|
||||
tplContent = reflect.ModelNameLowerPlural(model) + "_add_update"
|
||||
values.Add("update", "true")
|
||||
}
|
||||
|
||||
values.Add("tpl_content", tplContent)
|
||||
|
|
|
@ -19,7 +19,10 @@ func (e *Error) Error() string {
|
|||
var (
|
||||
RecordExists = errors.New("Record already exists!")
|
||||
|
||||
NotAuthorized = errors.New(i18n.Authorization["notAuthorized"]["it"])
|
||||
NotAuthorized = &Error{
|
||||
TemplateName: "error_not_authorized",
|
||||
Err: errors.New(i18n.Authorization["notAuthorized"]["it"]),
|
||||
}
|
||||
|
||||
SchoolExists = &Error{
|
||||
TemplateName: "error_school_exists",
|
||||
|
|
|
@ -206,6 +206,20 @@ func (h *Handlers) NewReadRequest(model interface{}, path string, format string)
|
|||
return http.NewRequest("GET", h.Config.ReadPath(model, path, format), nil)
|
||||
}
|
||||
|
||||
func (h *Handlers) NewUpdateRequest(model interface{}, path string, format string, method string, form url.Values) (*http.Request, error) {
|
||||
var (
|
||||
request *http.Request
|
||||
err error
|
||||
)
|
||||
switch method {
|
||||
case "GET":
|
||||
request, err = http.NewRequest("GET", h.Config.UpdatePath(model, path, format), nil)
|
||||
case "POST":
|
||||
request, err = http.NewRequest("POST", h.Config.UpdatePath(model, path, format), strings.NewReader(form.Encode()))
|
||||
}
|
||||
return request, err
|
||||
}
|
||||
|
||||
func (h *Handlers) NewCreateRequest(model interface{}, path string, format string, method string, form url.Values) (*http.Request, error) {
|
||||
var (
|
||||
request *http.Request
|
||||
|
@ -401,6 +415,26 @@ func (h *Handlers) Create(model interface{}) http.Handler {
|
|||
return newRootMiddleware(h, fn)
|
||||
}
|
||||
|
||||
func (h *Handlers) Update(model interface{}) http.Handler {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) error {
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
err := h.get(w, r, reflect.ModelNameLowerPlural(model), h.Config.UpdatePattern())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "POST":
|
||||
err := h.post(w, r, reflect.ModelNameLowerPlural(model), h.Config.UpdatePattern())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return newRootMiddleware(h, fn)
|
||||
}
|
||||
|
||||
func (h *Handlers) ReadAll(model interface{}) http.Handler {
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
h.get(w, r, reflect.ModelNameLowerPlural(model), h.Config.ReadAllPattern())
|
||||
|
|
|
@ -176,7 +176,7 @@ func (t *testSuite) BeforeAll() {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
conf.LogLevel = config.LOG_LEVEL_OFF
|
||||
conf.LogLevel = config.LOG_LEVEL_DEBUG
|
||||
|
||||
// Initialize the ORM
|
||||
|
||||
|
@ -443,6 +443,61 @@ func (t *testSuite) TestSchoolSubscription() {
|
|||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestParticipantResponse() {
|
||||
form := url.Values{}
|
||||
form.Set("Singleresponses.0", "9")
|
||||
|
||||
req, err := handlers.NewCreateRequest(&orm.School{}, "/responses/5/update", "html", "POST", form)
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
t.Nil(err)
|
||||
|
||||
req, err = login(req, handlers, "RHOMAT9HZ", "9HzXOfJPje")
|
||||
t.Nil(err)
|
||||
|
||||
if !t.Failed() {
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.Handle("/responses/{id}/update", handlers.Update(&orm.Response{}))
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusSeeOther, rr.Code)
|
||||
|
||||
if !t.Failed() {
|
||||
req, err := handlers.NewReadRequest(&orm.Contest{}, "/responses/1", "html")
|
||||
t.Nil(err)
|
||||
|
||||
req, err = login(req, handlers, "admin", "admin")
|
||||
t.Nil(err)
|
||||
|
||||
rr = httptest.NewRecorder()
|
||||
|
||||
router = mux.NewRouter()
|
||||
router.Handle("/responses/{id}", handlers.Read(&orm.Response{}))
|
||||
router.ServeHTTP(rr, req)
|
||||
|
||||
t.Equal(http.StatusOK, rr.Code)
|
||||
|
||||
log.Println(rr)
|
||||
if !t.Failed() {
|
||||
doc, err := goquery.NewDocumentFromReader(rr.Body)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
expected := "1"
|
||||
ok := true
|
||||
doc.Find("h1").Each(func(i int, s *goquery.Selection) {
|
||||
if !strings.Contains(s.Text(), expected) {
|
||||
ok = false
|
||||
}
|
||||
})
|
||||
t.True(ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestUserModifier() {
|
||||
id, err := subscribeSchoolAsSchool()
|
||||
t.Nil(err)
|
||||
|
|
|
@ -27,7 +27,7 @@ var (
|
|||
"it": "Il tempo utile per consegnare la prova è scaduto.",
|
||||
},
|
||||
"notAuthorized": map[string]string{
|
||||
"it": "Non si è autorizzati ad accedere a questa pagina",
|
||||
"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!",
|
||||
|
|
|
@ -261,6 +261,12 @@ func (model *Participant) Read(db *Database, args map[string]string, w http.Resp
|
|||
|
||||
id := args["id"]
|
||||
|
||||
if isParticipant(r) {
|
||||
if id != getModelIDFromToken(r) {
|
||||
return nil, errors.NotAuthorized
|
||||
}
|
||||
}
|
||||
|
||||
// School user can access to its participants only!
|
||||
if isSchool(r) {
|
||||
if err := db._db.Preload("School").First(&participant, id).Error; err != nil {
|
||||
|
|
|
@ -141,6 +141,12 @@ func (model *Response) Read(db *Database, args map[string]string, w http.Respons
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if isParticipant(r) {
|
||||
if strconv.Itoa(int(response.ParticipantID)) != getModelIDFromToken(r) {
|
||||
return nil, errors.NotAuthorized
|
||||
}
|
||||
}
|
||||
|
||||
if response.AnswersIDs != "" {
|
||||
srIDs := strings.Split(response.AnswersIDs, " ")
|
||||
for _, srID := range srIDs {
|
||||
|
|
4
templates/error_not_authorized.html.tpl
Normal file
4
templates/error_not_authorized.html.tpl
Normal file
|
@ -0,0 +1,4 @@
|
|||
{{ define "content" }}
|
||||
{{$options := `title: "Errore di autorizzazione"`}}
|
||||
{{template "error" dict "options" ($options|yaml) "data" .Data}}
|
||||
{{end}}
|
Loading…
Reference in a new issue