2020-03-04 11:07:12 +00:00
package main
import (
"encoding/json"
2020-03-08 00:06:44 +00:00
"errors"
2022-02-28 18:00:30 +00:00
"fmt"
2020-03-04 11:07:12 +00:00
"net/http"
"strconv"
2020-03-08 01:18:32 +00:00
"time"
2020-03-04 11:07:12 +00:00
"github.com/julienschmidt/httprouter"
2020-11-20 14:55:54 +00:00
"github.com/russross/blackfriday/v2"
2020-03-04 11:07:12 +00:00
)
func init ( ) {
router . GET ( "/api/questions" , apiHandler (
func ( httprouter . Params , [ ] byte ) HTTPResponse {
return formatApiResponse ( getQuestions ( ) )
2020-03-08 00:06:44 +00:00
} , adminRestricted ) )
router . GET ( "/api/surveys/:sid/questions" , apiAuthHandler ( surveyAuthHandler (
func ( s Survey , u * User , _ [ ] byte ) HTTPResponse {
if ! s . Shown && ! u . IsAdmin {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { err : errors . New ( "Not accessible" ) }
2020-03-08 00:06:44 +00:00
}
2020-03-08 01:18:32 +00:00
if s . StartAvailability . After ( time . Now ( ) ) && ! u . IsAdmin {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { status : http . StatusPaymentRequired , err : errors . New ( "Not available yet" ) }
2020-03-08 01:18:32 +00:00
}
2020-03-04 11:07:12 +00:00
return formatApiResponse ( s . GetQuestions ( ) )
2020-03-08 00:06:44 +00:00
} ) , loggedUser ) )
router . POST ( "/api/surveys/:sid/questions" , apiAuthHandler ( surveyAuthHandler ( func ( s Survey , u * User , body [ ] byte ) HTTPResponse {
if ! s . Shown && ! u . IsAdmin {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { err : errors . New ( "Not accessible" ) }
2020-03-08 00:06:44 +00:00
}
2020-03-04 11:07:12 +00:00
var new Question
if err := json . Unmarshal ( body , & new ) ; err != nil {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
}
2020-10-31 17:06:39 +00:00
return formatApiResponse ( s . NewQuestion ( new . Title , new . DescriptionRaw , new . Placeholder , new . Kind ) )
2020-03-04 11:07:12 +00:00
} ) , adminRestricted ) )
2022-02-28 18:00:30 +00:00
router . GET ( "/api/questions/:qid" , apiAuthHandler ( questionAuthHandler (
func ( q Question , u * User , _ [ ] byte ) HTTPResponse {
if u . IsAdmin {
return APIResponse { q }
} else if s , err := getSurvey ( int ( q . IdSurvey ) ) ; err != nil {
return APIErrorResponse { err : err }
} else if s . Shown || ( s . Direct != nil && * s . Direct == q . Id ) {
return APIResponse { q }
} else {
return APIErrorResponse { err : fmt . Errorf ( "Not authorized" ) , status : http . StatusForbidden }
}
} ) , loggedUser ) )
2020-03-04 11:07:12 +00:00
router . GET ( "/api/surveys/:sid/questions/:qid" , apiHandler ( questionHandler (
func ( s Question , _ [ ] byte ) HTTPResponse {
return APIResponse { s }
2020-03-08 00:06:44 +00:00
} ) , adminRestricted ) )
2020-03-04 11:07:12 +00:00
router . PUT ( "/api/questions/:qid" , apiHandler ( questionHandler ( func ( current Question , body [ ] byte ) HTTPResponse {
var new Question
if err := json . Unmarshal ( body , & new ) ; err != nil {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
}
new . Id = current . Id
return formatApiResponse ( new . Update ( ) )
2020-03-08 00:06:44 +00:00
} ) , adminRestricted ) )
2020-03-04 11:07:12 +00:00
router . PUT ( "/api/surveys/:sid/questions/:qid" , apiHandler ( questionHandler ( func ( current Question , body [ ] byte ) HTTPResponse {
var new Question
if err := json . Unmarshal ( body , & new ) ; err != nil {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
}
new . Id = current . Id
return formatApiResponse ( new . Update ( ) )
2020-03-08 00:06:44 +00:00
} ) , adminRestricted ) )
2020-03-04 11:07:12 +00:00
router . DELETE ( "/api/questions/:qid" , apiHandler ( questionHandler (
func ( q Question , _ [ ] byte ) HTTPResponse {
return formatApiResponse ( q . Delete ( ) )
2020-03-08 00:06:44 +00:00
} ) , adminRestricted ) )
2020-03-04 11:07:12 +00:00
router . DELETE ( "/api/surveys/:sid/questions/:qid" , apiHandler ( questionHandler (
func ( q Question , _ [ ] byte ) HTTPResponse {
return formatApiResponse ( q . Delete ( ) )
2020-03-08 00:06:44 +00:00
} ) , adminRestricted ) )
2020-03-04 11:07:12 +00:00
}
func questionHandler ( f func ( Question , [ ] byte ) HTTPResponse ) func ( httprouter . Params , [ ] byte ) HTTPResponse {
return func ( ps httprouter . Params , body [ ] byte ) HTTPResponse {
var survey * Survey = nil
if sid , err := strconv . Atoi ( string ( ps . ByName ( "sid" ) ) ) ; err == nil {
if s , err := getSurvey ( sid ) ; err == nil {
survey = & s
}
}
if qid , err := strconv . Atoi ( string ( ps . ByName ( "qid" ) ) ) ; err != nil {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
} else if survey == nil {
if question , err := getQuestion ( qid ) ; err != nil {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
} else {
return f ( question , body )
}
} else {
if question , err := survey . GetQuestion ( qid ) ; err != nil {
2020-10-31 17:06:39 +00:00
return APIErrorResponse { err : err }
2020-03-04 11:07:12 +00:00
} else {
return f ( question , body )
}
}
}
}
func questionAuthHandler ( f func ( Question , * User , [ ] byte ) HTTPResponse , access ... func ( * User , * Question ) error ) func ( * User , httprouter . Params , [ ] byte ) HTTPResponse {
return func ( u * User , ps httprouter . Params , body [ ] byte ) HTTPResponse {
return questionHandler ( func ( q Question , body [ ] byte ) HTTPResponse {
// Check access limitation
for _ , a := range access {
if err := a ( u , & q ) ; err != nil {
return APIErrorResponse {
status : http . StatusForbidden ,
2020-10-31 17:06:39 +00:00
err : err ,
2020-03-04 11:07:12 +00:00
}
}
}
return f ( q , u , body )
} ) ( ps , body )
}
}
type Question struct {
2020-10-31 17:06:39 +00:00
Id int64 ` json:"id" `
IdSurvey int64 ` json:"id_survey" `
Title string ` json:"title" `
Description string ` json:"description" `
DescriptionRaw string ` json:"desc_raw,omitempty" `
Placeholder string ` json:"placeholder,omitempty" `
Kind string ` json:"kind" `
2020-03-04 11:07:12 +00:00
}
func getQuestions ( ) ( questions [ ] Question , err error ) {
if rows , errr := DBQuery ( "SELECT id_question, id_survey, title, description, placeholder, kind FROM survey_quests" ) ; errr != nil {
return nil , errr
} else {
defer rows . Close ( )
for rows . Next ( ) {
var q Question
2020-10-31 17:06:39 +00:00
if err = rows . Scan ( & q . Id , & q . IdSurvey , & q . Title , & q . DescriptionRaw , & q . Placeholder , & q . Kind ) ; err != nil {
2020-03-04 11:07:12 +00:00
return
}
2020-10-31 17:06:39 +00:00
q . Description = string ( blackfriday . Run ( [ ] byte ( q . DescriptionRaw ) ) )
2020-03-04 11:07:12 +00:00
questions = append ( questions , q )
}
if err = rows . Err ( ) ; err != nil {
return
}
return
}
}
func ( s * Survey ) GetQuestions ( ) ( questions [ ] Question , err error ) {
if rows , errr := DBQuery ( "SELECT id_question, id_survey, title, description, placeholder, kind FROM survey_quests WHERE id_survey=?" , s . Id ) ; errr != nil {
return nil , errr
} else {
defer rows . Close ( )
for rows . Next ( ) {
var q Question
2020-10-31 17:06:39 +00:00
if err = rows . Scan ( & q . Id , & q . IdSurvey , & q . Title , & q . DescriptionRaw , & q . Placeholder , & q . Kind ) ; err != nil {
2020-03-04 11:07:12 +00:00
return
}
2020-10-31 17:06:39 +00:00
q . Description = string ( blackfriday . Run ( [ ] byte ( q . DescriptionRaw ) ) )
2020-03-04 11:07:12 +00:00
questions = append ( questions , q )
}
if err = rows . Err ( ) ; err != nil {
return
}
return
}
}
func getQuestion ( id int ) ( q Question , err error ) {
2020-10-31 17:06:39 +00:00
err = DBQueryRow ( "SELECT id_question, id_survey, title, description, placeholder, kind FROM survey_quests WHERE id_question=?" , id ) . Scan ( & q . Id , & q . IdSurvey , & q . Title , & q . DescriptionRaw , & q . Placeholder , & q . Kind )
q . Description = string ( blackfriday . Run ( [ ] byte ( q . DescriptionRaw ) ) )
2020-03-04 11:07:12 +00:00
return
}
func ( s * Survey ) GetQuestion ( id int ) ( q Question , err error ) {
2020-10-31 17:06:39 +00:00
err = DBQueryRow ( "SELECT id_question, id_survey, title, description, placeholder, kind FROM survey_quests WHERE id_question=? AND id_survey=?" , id , s . Id ) . Scan ( & q . Id , & q . IdSurvey , & q . Title , & q . DescriptionRaw , & q . Placeholder , & q . Kind )
q . Description = string ( blackfriday . Run ( [ ] byte ( q . DescriptionRaw ) ) )
2020-03-04 11:07:12 +00:00
return
}
func ( s * Survey ) NewQuestion ( title string , description string , placeholder string , kind string ) ( Question , error ) {
if res , err := DBExec ( "INSERT INTO survey_quests (id_survey, title, description, placeholder, kind) VALUES (?, ?, ?, ?, ?)" , s . Id , title , description , placeholder , kind ) ; err != nil {
return Question { } , err
} else if qid , err := res . LastInsertId ( ) ; err != nil {
return Question { } , err
} else {
2020-10-31 17:06:39 +00:00
return Question { qid , s . Id , title , string ( blackfriday . Run ( [ ] byte ( description ) ) ) , description , placeholder , kind } , nil
2020-03-04 11:07:12 +00:00
}
}
func ( q Question ) GetSurvey ( ) ( Survey , error ) {
return getSurvey ( int ( q . IdSurvey ) )
}
func ( q Question ) Update ( ) ( Question , error ) {
2020-10-31 17:06:39 +00:00
if _ , err := DBExec ( "UPDATE survey_quests SET id_survey = ?, title = ?, description = ?, placeholder = ?, kind = ? WHERE id_question = ?" , q . IdSurvey , q . Title , q . DescriptionRaw , q . Placeholder , q . Kind , q . Id ) ; err != nil {
2020-03-04 11:07:12 +00:00
return Question { } , err
} else {
return q , err
}
}
func ( q Question ) Delete ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM survey_quests WHERE id_question = ?" , q . Id ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}
func ClearQuestions ( ) ( int64 , error ) {
if res , err := DBExec ( "DELETE FROM survey_quests" ) ; err != nil {
return 0 , err
} else if nb , err := res . RowsAffected ( ) ; err != nil {
return 0 , err
} else {
return nb , err
}
}