func main() { dbHost := flag.String("dbhost", "localhost", "the database host") dbPort := flag.Int("dbport", 5432, "the database port") dbUser := flag.String("dbuser", "aclapp", "the database user") dbSsl := flag.Bool("dbssl", false, "database ssl config") dbName := flag.String("dbname", "acl", "the database name") dbPassword := flag.String("dbpass", "", "database password") flag.Parse() config := pgmapper.DefaultConfig() config.Host = *dbHost config.Port = *dbPort config.User = *dbUser config.Ssl = *dbSsl config.Database = *dbName config.Password = *dbPassword r := mux.NewRouter() mapper, err := pgmapper.New(config) if err != nil { log.Fatal(err) } objectIdExtractor := idextractor.MuxIdExtractor("objectId") userIdExtractor := idextractor.MuxIdExtractor("userId") r.Methods("POST").Path("/objects").Handler(jwtware.New(addObjectHandler(mapper))) r.Methods("DELETE").Path("/objects/{objectId}").Handler(jwtware.New(deleteObjectHandler(mapper, objectIdExtractor))) r.Methods("GET").Path("/objects/{objectId}/permissions/{userId}").Handler(jwtware.New(getPermissionsHandler(mapper, objectIdExtractor, userIdExtractor))) r.Methods("PUT").Path("/objects/{objectId}/permissions").Handler(jwtware.New(upsertPermissionsHandler(mapper, objectIdExtractor))) r.Methods("PUT").Path("/sids/{sid}/permissions").Handler(jwtware.New(upsertMultiplePermissionsHandler(mapper, idextractor.MuxIdExtractor("sid")))) log.Println("listening on 8080") http.ListenAndServe(":8080", r) }
func PurchaseHintHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { id, err := extractor(r) if err != nil { return http.StatusBadRequest } userId := context.Get(r, "user").(*jwt.Token).Claims["id"].(string) result, err := mapper.PreparedQueryIntoBytes("SELECT purchase_hint(%v)", id, userId) if err != nil { log.Println(err) return http.StatusInternalServerError } purchaseResult, _ := strconv.Atoi(string(result)) log.Println("hint purchase achieved the following result: ", purchaseResult) switch { case purchaseResult == 0: //hint purchase without errors return -1 case purchaseResult == 1: //balance not sufficient return 420 case purchaseResult == 2: //already purchased return http.StatusConflict case purchaseResult == 3: //hint not found return http.StatusNotFound default: //something different went wrong return http.StatusInternalServerError } } return jwtware.New(createHandler(handlerFunc)) }
func ModulesPatchHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { id, err := extractor(r) if err != nil { return http.StatusInternalServerError } log.Println("got patch request for module") patch, err := jsonpatch.Decode(r.Body) if err != nil { log.Println("error while decoding json: ", err) return http.StatusBadRequest } userId := context.Get(r, "user").(*jwt.Token).Claims["id"].(string) options := map[string]interface{}{ "userId": userId, "id": id, "jwt": r.Header.Get("Authorization"), } compiler := lecturepatch.ForModules() err = mapper.ApplyPatch(patch, compiler, options) if err != nil { if err == lecturepatch.PermissionDeniedError { log.Println(err) return http.StatusUnauthorized } else { log.Println("error while applying module patch: ", err) return http.StatusBadRequest } } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func ModulesTreeHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { id, err := extractor(r) if err != nil { log.Println("error with extractor in ModulesTreeHandler") return http.StatusBadRequest } dr, err := paginator.ParseDepth(r.URL) if err != nil { log.Println("error parsing depth request in ModulesTreeHandler") return http.StatusInternalServerError } result, err := mapper.PreparedQueryIntoBytes("SELECT get_module_tree(%v)", id, dr.Descendants, dr.Ancestors) if err != nil { log.Println(err) return http.StatusInternalServerError } reader := bytes.NewReader(result) _, err = io.Copy(w, reader) if err != nil { log.Println(err) } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func ExerciseHistoryHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { pr, err := paginator.ParsePages(r.URL) if err != nil { return http.StatusInternalServerError } id, err := extractor(r) if err != nil { return http.StatusInternalServerError } limit := pr.Size skip := pr.Size * pr.Number if pr.Number == -1 || pr.Size == -1 { skip = -1 } var result []byte if ids, ok := r.URL.Query()["module_id"]; ok { result, err = mapper.PreparedQueryIntoBytes("SELECT get_exercise_history(%v)", id, limit, skip, ids[0]) } else { result, err = mapper.PreparedQueryIntoBytes("SELECT get_exercise_history(%v)", id, limit, skip) } if err != nil { return http.StatusNotFound } reader := bytes.NewReader(result) _, err = io.Copy(w, reader) if err != nil { log.Println(err) } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func TopicCreateHandler(mapper *pgmapper.Mapper) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { var topic = make(map[string]interface{}) err := json.NewDecoder(r.Body).Decode(&topic) if err != nil { log.Println("error while decoding new topic json: ", err) return http.StatusBadRequest } err = mapper.Execute("SELECT add_topic(%v)", topic["id"], topic["name"], topic["description"], topic["officers"]) if err != nil { log.Println("error while inserting new topic into database") return http.StatusBadRequest // TODO it could be an internal server error as well. need distinction } client := serviceclient.New("acl-service") aclEntity, _ := json.Marshal(topic) resp, err := client.Post("/objects", "application/json", bytes.NewReader(aclEntity), "Authorization", r.Header.Get("Authorization")) if err != nil { log.Println("error while creating acl-object: ", err) return http.StatusInternalServerError } if resp.StatusCode >= 300 { log.Println("got unexpected statuscode from acl-service while creating object: ", resp.StatusCode) return http.StatusInternalServerError } return http.StatusCreated } return jwtware.New(createHandler(handlerFunc)) }
func buildUploadHandler(host string) http.Handler { backend := mongofs.New(host, "media", "fs") uploadHandler := UploadHandler(backend) return jwtware.New( groupware.New(groupware.DefaultOptions( uploadHandler))) }
func ExerciseStartHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { user := context.Get(r, "user") id := user.(*jwt.Token).Claims["id"] exerciseId, err := extractor(r) if err != nil { return http.StatusInternalServerError } err = mapper.Execute("select start_exercise(%v)", exerciseId, id) if err != nil { return http.StatusNotFound } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func TopicBalanceHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { id, err := extractor(r) if err != nil { return http.StatusInternalServerError } result, err := mapper.PreparedQueryIntoBytes("Select get_balances(%v)", id) if err != nil { return http.StatusNotFound } reader := bytes.NewReader(result) _, err = io.Copy(w, reader) if err != nil { log.Println(err) } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func TopicRemoveOfficerHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { id, err := extractor(r) if err != nil { return http.StatusInternalServerError } var officer string err = json.NewDecoder(r.Body).Decode(officer) if err != nil { return http.StatusBadRequest } err = mapper.Execute("SELECT remove_officer(%v)", id, officer) if err != nil { return http.StatusInternalServerError } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func ModulesGetHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { id, err := extractor(r) if err != nil { log.Println("error with extractor in ModulesGetHandler") return http.StatusInternalServerError } result, err := mapper.QueryIntoBytes(`SELECT details from module_details where id = $1`, id) if err != nil { return http.StatusNotFound } reader := bytes.NewReader(result) _, err = io.Copy(w, reader) if err != nil { log.Println(err) } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func TopicCollectionHandler(mapper *pgmapper.Mapper) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { pageRequest, err := paginator.ParsePages(r.URL) if err != nil { return http.StatusInternalServerError } result, err := mapper.PreparedQueryIntoBytes("SELECT * from query_topics(%v)", pageRequest.Number*pageRequest.Size, pageRequest.Size) if err != nil { log.Println(err) return http.StatusInternalServerError } reader := bytes.NewReader(result) _, err = io.Copy(w, reader) if err != nil { log.Println(err) } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func GetHintHandler(mapper *pgmapper.Mapper, extractor idextractor.Extractor) http.Handler { handlerFunc := func(w http.ResponseWriter, r *http.Request) int { id, err := extractor(r) if err != nil { return http.StatusBadRequest } userId := context.Get(r, "user").(*jwt.Token).Claims["id"].(string) result, err := mapper.PreparedQueryIntoBytes("SELECT get_hint(%v)", userId, id) switch { case err != nil: return http.StatusInternalServerError case len(result) == 0: return http.StatusPaymentRequired } reader := bytes.NewReader(result) _, err = io.Copy(w, reader) if err != nil { log.Println(err) } return -1 } return jwtware.New(createHandler(handlerFunc)) }
func jwtWrapper(next http.Handler, auth bool) http.Handler { if !auth { return next } return jwtware.New(next) }
func buildDownloadHandler(host string) http.Handler { backend := mongofs.New(host, "media", "fs") return jwtware.New(http.FileServer(backend)) }