// PostSubmission creates a new submission. func PostSubmission(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) { p, ok := passenger.FromContext(ctx) if !ok { return http.StatusUnauthorized, nil } if r.Method != "POST" { return http.StatusMethodNotAllowed, nil } resultKey, err := datastore.DecodeKey(mux.Vars(r)["resultKey"]) if !util.HasParent(p.UserKey, resultKey) { return http.StatusBadRequest, errors.New("cannot submit answer for other users") } taskKey, err := datastore.DecodeKey(mux.Vars(r)["taskKey"]) // Note: When more task kinds are added, see controllers.CreateFinalResult. switch taskKey.Kind() { case model.CodeTaskKind: return runner.HandleCodeSubmission(ctx, w, r, resultKey, taskKey) // TODO(victorbalan, flowlo): Use correct kind when possible. case "QuestionTask": return http.StatusInternalServerError, errors.New("question submissions are not yet implemented") default: return http.StatusBadRequest, errors.New("Unknown submission kind.") } }
func put(rw http.ResponseWriter, req *http.Request) { c := appengine.NewContext(req) u := user.Current(c) m := req.FormValue("message") s := req.FormValue("encoded_key") // fmt.Fprintf(rw, "Key 1: %v", s) p := req.FormValue("parent_key") var t, ut string var op bool var k *datastore.Key // make/decode keys if s == "" { if p == "" { k = datastore.NewIncompleteKey(c, "post", nil) op = true } else { pk, err := datastore.DecodeKey(p) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } k = datastore.NewIncompleteKey(c, "post", pk) op = false } t = time.Now().Format("Jan 2, 2006 3:04 PM") ut = "" } else { k, err := datastore.DecodeKey(s) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } mypost := Post{} err = datastore.Get(c, k, &mypost) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } ut = time.Now().Format("Jan 2, 2006 3:04 PM") t = mypost.PostDate op = mypost.OP } // data := url.Values{} // data.Set("encoded_key", k.Encode()) // r, _ := http.NewRequest("POST", "/view", bytes.NewBufferString(data.Encode())) newpost := Post{Author: u.String(), Message: m, UpdateDate: ut, PostDate: t, OP: op} _, err := datastore.Put(c, k, &newpost) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } // http.Redirect(rw, r, "/view", http.StatusOK) http.Redirect(rw, req, "/", http.StatusTemporaryRedirect) }
// AddEvent - Add an Event and save to Datastore func AddEvent(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) // Set the timestamps at := time.Now() const timeformat = "2006-01-02 15:04:05 -0700" st, _ := time.Parse(timeformat, r.FormValue("start_time")) et, _ := time.Parse(timeformat, r.FormValue("end_time")) dt, _ := time.Parse(timeformat, r.FormValue("door_time")) // Create the event object e1 := Event{ StartDate: st, EndDate: et, DateAdded: at, DoorTime: dt, Name: r.FormValue("headline"), Description: r.FormValue("description"), URL: r.FormValue("event_url"), Image: r.FormValue("poster_file"), } // Load the Venue Key if len(r.FormValue("venue")) > 0 { venue, err := datastore.DecodeKey(r.FormValue("venue")) fmt.Fprintf(w, "%+v", venue) if err != nil { JSONError(&w, err.Error()) return } e1.Venue = venue } // Load the Promoter Key if len(r.FormValue("promoter")) > 0 { promoter, err := datastore.DecodeKey(r.FormValue("promoter")) if err != nil { JSONError(&w, err.Error()) return } e1.Promoter = promoter fmt.Fprintf(w, "%+v", e1) } // Add the event to the Datastore k, err := e1.Store(ctx) if err != nil { JSONError(&w, err.Error()) return } e1.DatastoreKey = *k return }
func (h urlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { c := h.getContext(r) ds := appwrap.NewAppengineDatastore(c) monitorTimeout := time.Minute * 30 if appengine.IsDevAppServer() { monitorTimeout = time.Second * 10 } if strings.HasSuffix(r.URL.Path, "/map-monitor") || strings.HasSuffix(r.URL.Path, "/reduce-monitor") { if jobKeyStr := r.FormValue("jobKey"); jobKeyStr == "" { http.Error(w, "jobKey parameter required", http.StatusBadRequest) } else if jobKey, err := datastore.DecodeKey(jobKeyStr); err != nil { http.Error(w, fmt.Sprintf("invalid jobKey: %s", err.Error()), http.StatusBadRequest) } else if strings.HasSuffix(r.URL.Path, "/map-monitor") { w.WriteHeader(mapMonitorTask(c, ds, h.pipeline, jobKey, r, monitorTimeout)) } else { w.WriteHeader(reduceMonitorTask(c, ds, h.pipeline, jobKey, r, monitorTimeout)) } return } var taskKey *datastore.Key var err error if taskKeyStr := r.FormValue("taskKey"); taskKeyStr == "" { http.Error(w, "taskKey parameter required", http.StatusBadRequest) return } else if taskKey, err = datastore.DecodeKey(taskKeyStr); err != nil { http.Error(w, fmt.Sprintf("invalid taskKey: %s", err.Error()), http.StatusBadRequest) return } if strings.HasSuffix(r.URL.Path, "/reduce") { reduceTask(c, ds, h.baseUrl, h.pipeline, taskKey, w, r) } else if strings.HasSuffix(r.URL.Path, "/map") { mapTask(c, ds, h.baseUrl, h.pipeline, taskKey, w, r) } else if strings.HasSuffix(r.URL.Path, "/mapstatus") || strings.HasSuffix(r.URL.Path, "/reducestatus") { updateTask(ds, taskKey, "", 0, r.FormValue("msg"), nil) } else { http.Error(w, "unknown request url", http.StatusNotFound) return } }
func deleteData(res http.ResponseWriter, req *http.Request) { ctx := appengine.NewContext(req) u := user.Current(ctx) keyVal := req.FormValue("keyVal") key, err := datastore.DecodeKey(keyVal) if err != nil { http.Error(res, "Invalid data", http.StatusBadRequest) log.Warningf(ctx, err.Error()) return } var l list err = datastore.Get(ctx, key, &l) if err != nil { http.Error(res, "Invalid data", http.StatusBadRequest) log.Warningf(ctx, err.Error()) return } if l.Owner != u.Email { http.Error(res, "Not authorized to delete this entry", http.StatusUnauthorized) log.Warningf(ctx, err.Error()) return } err = datastore.Delete(ctx, key) if err != nil { http.Error(res, "Server Error", http.StatusInternalServerError) log.Errorf(ctx, err.Error()) return } }
// ChallengeByKey loads a challenge by key. func ChallengeByKey(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) { if r.Method != "GET" { return http.StatusMethodNotAllowed, nil } p, ok := passenger.FromContext(ctx) if !ok { return http.StatusUnauthorized, nil } key, err := datastore.DecodeKey(mux.Vars(r)["key"]) if err != nil { return http.StatusInternalServerError, err } var challenge model.Challenge err = datastore.Get(ctx, key, &challenge) if err != nil { return http.StatusInternalServerError, err } e := json.NewEncoder(w) if parent := p.UserKey.Parent(); parent == nil { // The current user is a coder so we must also create a result. e.Encode(challenge.Key(key)) } else { // TODO(pbochis): If a company representativemakes the request // we also include Tasks in the response. e.Encode(challenge.Key(key)) } return http.StatusOK, nil }
// GetChallengesForCompany queries all the challenges defined by a company. func GetChallengesForCompany(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) { if r.Method != "GET" { return http.StatusMethodNotAllowed, nil } _, ok := passenger.FromContext(ctx) if !ok { return http.StatusUnauthorized, nil } key, err := datastore.DecodeKey(mux.Vars(r)["key"]) if err != nil { return http.StatusInternalServerError, err } var challenges model.Challenges keys, err := model.NewQueryForChallenge(). Ancestor(key). GetAll(ctx, &challenges) if err != nil { return http.StatusInternalServerError, err } json.NewEncoder(w).Encode(challenges.Key(keys)) return http.StatusOK, nil }
// GET http://localhost:8080/profiles/ahdkZXZ-ZmVkZXJhdGlvbi1zZXJ2aWNlc3IVCxIIcHJvZmlsZXMYgICAgICAgAoM // func (u ProfileApi) read(r *restful.Request, w *restful.Response) { c := appengine.NewContext(r.Request) // Decode the request parameter to determine the key for the entity. k, err := datastore.DecodeKey(r.PathParameter("profile-id")) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Retrieve the entity from the datastore. p := Profile{} if err := datastore.Get(c, k, &p); err != nil { if err.Error() == "datastore: no such entity" { http.Error(w, err.Error(), http.StatusNotFound) } else { http.Error(w, err.Error(), http.StatusInternalServerError) } return } // Check we own the profile before allowing them to view it. // Optionally, return a 404 instead to help prevent guessing ids. // TODO: Allow admins access. if p.Email != user.Current(c).String() { http.Error(w, "You do not have access to this resource", http.StatusForbidden) return } w.WriteEntity(p) }
// Handle performs an upgrade from HTTP to WebSocket. It hijacks the connection // and registers it in the global pool. func Handle(w http.ResponseWriter, r *http.Request) { m := r.URL.Query() result := m.Get("result") if result == "" { http.Error(w, "Bad Request: missing parameter \"result\"", http.StatusBadRequest) return } key, err := datastore.DecodeKey(result) if err != nil { http.Error(w, "Bad Request: cannot decode \"result\"", http.StatusBadRequest) return } conn, err := upgrader.Upgrade(w, r, nil) if err != nil { // NOTE: Returning a HTTP error is done by upgrader. return } conns.Lock() conns.m[ktoi(key)] = conn conns.Unlock() reader(conn) }
func adminUpdateTask(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) tid := r.FormValue("taskKey") k, err := datastore.DecodeKey(tid) if err != nil { panic(err) } task := &Task{} if err := datastore.Get(c, k, task); err != nil { log.Warningf(c, "Error getting task %v: %v", k, err) http.Error(w, err.Error(), 404) return } task.Name = r.FormValue("name") task.Description = r.FormValue("description") task.Value = asInt(r.FormValue("value")) task.Period = asInt(r.FormValue("period")) task.Disabled = mightParseBool(r.FormValue("disabled")) task.Automatic = mightParseBool(r.FormValue("automatic")) task.Assignee = r.FormValue("assignee") if _, err := datastore.Put(c, k, task); err != nil { log.Warningf(c, "Error storing task %v, %+v: %v", k, task, err) http.Error(w, err.Error(), 500) return } w.WriteHeader(204) }
func view(rw http.ResponseWriter, req *http.Request) { s := req.FormValue("encoded_key") c := appengine.NewContext(req) k, err := datastore.DecodeKey(s) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } posts := []Post{} q := datastore.NewQuery("post").Ancestor(k).Order("PostDate") keys, err := q.GetAll(c, &posts) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } threads := []Thread{} for i, value := range posts { threads = append(threads, Thread{value, keys[i].Encode()}) } t := template.Must(template.ParseFiles("assets/post.html")) t.ExecuteTemplate(rw, "Post", struct { Parent string Thread []Thread }{ s, threads, }) }
func GetProfileForUser(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) { _, ok := passenger.FromContext(ctx) if !ok { return http.StatusUnauthorized, nil } var userKey *datastore.Key if userKey, err = datastore.DecodeKey(mux.Vars(r)["key"]); err != nil { return http.StatusInternalServerError, err } var profiles []model.Profile keys, err := model.NewQueryForProfile(). Ancestor(userKey). Limit(1). GetAll(ctx, &profiles) if err != nil { return http.StatusInternalServerError, err } if len(keys) != 1 { return http.StatusNotFound, nil } json.NewEncoder(w).Encode(profiles[0].Key(keys[0])) return }
func editpost(rw http.ResponseWriter, req *http.Request) { c := appengine.NewContext(req) s := req.FormValue("encoded_key") k, err := datastore.DecodeKey(s) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } mypost := Post{} err = datastore.Get(c, k, &mypost) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if mypost.Author == user.Current(c).String() { message := mypost.Message title := "Edit a Post" t := template.Must(template.ParseFiles("assets/edit.html")) t.ExecuteTemplate(rw, "New", struct { Title string Message string ID string Parent string }{Title: title, Message: message, ID: s}) } else { http.Redirect(rw, req, "/", http.StatusOK) } }
func GetResult(ctx context.Context, w http.ResponseWriter, r *http.Request) (int, error) { if !util.CheckMethod(r, "GET") { return http.StatusMethodNotAllowed, nil } resultKey, err := datastore.DecodeKey(mux.Vars(r)["resultKey"]) if err != nil { return http.StatusBadRequest, err } var result model.Result if err := datastore.Get(ctx, resultKey, &result); err != nil { return http.StatusInternalServerError, nil } p, ok := passenger.FromContext(ctx) if !ok { return http.StatusUnauthorized, nil } if p.UserKey.Parent() != nil { json.NewEncoder(w).Encode(result.Key(resultKey)) return http.StatusOK, nil } if !util.HasParent(resultKey, p.UserKey) { return http.StatusUnauthorized, nil } return createFinalResult(ctx, w, resultKey, result) }
// FinalSubmission makes the last submission final. func FinalSubmission(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) { if r.Method != "POST" { return http.StatusMethodNotAllowed, nil } p, ok := passenger.FromContext(ctx) if !ok { return http.StatusUnauthorized, nil } var resultKey *datastore.Key if resultKey, err = datastore.DecodeKey(mux.Vars(r)["resultKey"]); err != nil { return http.StatusInternalServerError, err } if !util.HasParent(p.User, resultKey) { return http.StatusBadRequest, errors.New("cannot submit answer for other users") } var index int if index, err = strconv.Atoi(mux.Vars(r)["index"]); err != nil { return http.StatusInternalServerError, err } if len(r.URL.Query()["submissionKey"]) == 0 { return http.StatusOK, nil } var submissionKey *datastore.Key if submissionKey, err = datastore.DecodeKey(r.URL.Query()["submissionKey"][0]); err != nil { return http.StatusInternalServerError, err } var result model.Result if err = datastore.Get(ctx, resultKey, &result); err != nil { return http.StatusInternalServerError, err } result.FinalSubmissions[index] = submissionKey if _, err = result.Put(ctx, resultKey); err != nil { return http.StatusInternalServerError, err } w.Write([]byte("OK")) return }
func (cdb ComplaintDB) UpdateAnyComplaint(complaint types.Complaint) error { if k, err := datastore.DecodeKey(complaint.DatastoreKey); err != nil { return err } else { complaint.Version = kComplaintVersion _, err := datastore.Put(cdb.Ctx(), k, &complaint) return err } }
// decodeKey safely decodes the specified key string, returning // nil if there is a decoding error. func decodeKey(k string) *datastore.Key { if k == "" { return nil } key, err := datastore.DecodeKey(k) if err != nil { return nil } return key }
func makeStatusUpdateFunc(c context.Context, ds appwrap.Datastore, pipeline MapReducePipeline, urlStr string, taskKey string) StatusUpdateFunc { return func(format string, paramList ...interface{}) { msg := fmt.Sprintf(format, paramList...) if key, err := datastore.DecodeKey(taskKey); err != nil { logError(c, "failed to decode task key for status: %s", err) } else if _, err := updateTask(ds, key, "", 0, msg, nil); err != nil { logError(c, "failed to update task status: %s", err) } } }
func DecodeDatastoreKey(d *Decoder) (*ds.Key, error) { v, err := d.DecodeString() if err != nil { return nil, err } if v == "" { return nil, nil } return ds.DecodeKey(v) }
// SaveBoardState commits the state to the datastore func SaveBoardState(c context.Context, state *BoardState) (*BoardState, error) { sessionKey, err := datastore.DecodeKey(state.SessionID) if err != nil { return nil, err } stateModel := &boardStateModel{} stateModel.parentKey = sessionKey stateModel.lastModified = time.Now() stateModel.key, err = datastore.Put(c, datastore.NewIncompleteKey(c, "BoardState", stateModel.parentKey), stateModel) if err != nil { return nil, err } // Initialize the result result := &BoardState{ ID: stateModel.key.Encode(), SessionID: stateModel.parentKey.Encode(), LastModified: time.Now(), Players: make(map[string]*Player), } // Save the players for k, v := range state.Players { p := &playerModel{ Name: k, Location: v.Location, } p.parentKey = stateModel.key p.key, err = datastore.Put(c, datastore.NewIncompleteKey(c, "PlayerState", p.parentKey), p) if err != nil { return nil, err } for _, card := range v.Hand { cardModel := &cardModel{ Name: card.Name, Color: card.Color, } cardModel.parentKey = p.key cardModel.key, err = datastore.Put(c, datastore.NewIncompleteKey(c, "PlayerCard", p.parentKey), cardModel) if err != nil { return nil, err } } // Added player to result result.Players[k] = &Player{ Location: p.Location, Hand: v.Hand, } } return result, nil }
// PUT http://localhost:8080/profiles/ahdkZXZ-ZmVkZXJhdGlvbi1zZXJ2aWNlc3IVCxIIcHJvZmlsZXMYgICAgICAgAoM // {"first_name": "Ivan", "nick_name": "Socks", "last_name": "Hawkes"} // func (u *ProfileApi) update(r *restful.Request, w *restful.Response) { c := appengine.NewContext(r.Request) // Decode the request parameter to determine the key for the entity. k, err := datastore.DecodeKey(r.PathParameter("profile-id")) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // Marshall the entity from the request into a struct. p := new(Profile) err = r.ReadEntity(&p) if err != nil { w.WriteError(http.StatusNotAcceptable, err) return } // Retrieve the old entity from the datastore. old := Profile{} if err := datastore.Get(c, k, &old); err != nil { if err.Error() == "datastore: no such entity" { http.Error(w, err.Error(), http.StatusNotFound) } else { http.Error(w, err.Error(), http.StatusInternalServerError) } return } // Check we own the profile before allowing them to update it. // Optionally, return a 404 instead to help prevent guessing ids. // TODO: Allow admins access. if old.Email != user.Current(c).String() { http.Error(w, "You do not have access to this resource", http.StatusForbidden) return } // Since the whole entity is re-written, we need to assign any invariant fields again // e.g. the owner of the entity. p.Email = user.Current(c).String() // Keep track of the last modification date. p.LastModified = time.Now() // Attempt to overwrite the old entity. _, err = datastore.Put(c, k, p) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Let them know it succeeded. w.WriteHeader(http.StatusNoContent) }
func submissionsAddHandler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) if err := r.ParseForm(); err != nil { serveErr(ctx, err, w) return } ID, _, err := datastore.AllocateIDs(ctx, "Podcast", nil, 1) if err != nil { serveErr(ctx, err, w) return } date, err := time.Parse(yyyymmdd, r.FormValue("date")) if err != nil { serveErr(ctx, err, w) return } podcast := Podcast{ ID: ID, Show: r.FormValue("show"), Title: r.FormValue("title"), Desc: r.FormValue("desc"), URL: template.URL(r.FormValue("url")), MediaURL: template.URL(r.FormValue("media_url")), RuntimeSec: r.FormValue("runtime"), Size: r.FormValue("size"), Date: date, Added: time.Now(), } if _, err := datastore.Put(ctx, datastore.NewKey(ctx, "Podcast", "", ID, nil), &podcast); err != nil { serveErr(ctx, err, w) return } key, err := datastore.DecodeKey(r.FormValue("key")) if err != nil { serveErr(ctx, err, w) return } if err := datastore.Delete(ctx, key); err != nil { serveErr(ctx, err, w) return } if err := memcache.Delete(ctx, cacheKey); err != nil { log.Errorf(ctx, "memcache delete error %v", err) } successTmpl.ExecuteTemplate(w, "base", nil) }
func GetTestResultsForSubmission(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) { if r.Method != "GET" { return http.StatusMethodNotAllowed, nil } // TODO(victorbalan): Check if user is company or if user is parent of result // else return http.StatusUnauthorized _, ok := passenger.FromContext(ctx) if !ok { return http.StatusUnauthorized, nil } submissionKey, err := datastore.DecodeKey(mux.Vars(r)["key"]) if err != nil { return http.StatusNotFound, err } keys, err := datastore.NewQuery(""). Ancestor(submissionKey). Filter("__key__ >", submissionKey). KeysOnly(). GetAll(ctx, nil) if err != nil { return http.StatusInternalServerError, err } if len(keys) == 0 { json.NewEncoder(w).Encode([]string{}) return http.StatusOK, nil } switch keys[0].Kind() { case model.JunitTestResultKind: var results model.JunitTestResults _, err = datastore.NewQuery(keys[0].Kind()). Ancestor(submissionKey). GetAll(ctx, &results) if err != nil { return http.StatusInternalServerError, err } json.NewEncoder(w).Encode(results) case model.DiffTestResultKind: var results model.DiffTestResults _, err = datastore.NewQuery(keys[0].Kind()). Ancestor(submissionKey). GetAll(ctx, &results) if err != nil { return http.StatusInternalServerError, err } json.NewEncoder(w).Encode(results) default: w.Write([]byte("[]")) } return http.StatusOK, nil }
func Templates(ctx context.Context, w http.ResponseWriter, r *http.Request) (int, error) { if r.Method != "GET" { return http.StatusMethodNotAllowed, nil } taskKey, err := datastore.DecodeKey(mux.Vars(r)["key"]) if err != nil { return http.StatusBadRequest, err } ls := r.URL.Query()["language"] var t model.Task if err = datastore.Get(ctx, taskKey, &t); err != nil { return http.StatusInternalServerError, nil } // TODO(flowlo): Use correct duration. expiry := time.Now().Add(time.Hour * 2) var urls []string expose := func(objs []model.StoredObject) error { for _, obj := range objs { u, err := util.Expose(obj.Bucket, obj.Name, expiry) if err != nil { return err } urls = append(urls, u) } return nil } if len(ls) == 0 { for _, objs := range t.Templates { if err := expose(objs); err != nil { return http.StatusInternalServerError, err } } } else { for _, l := range ls { if err := expose(t.Templates[l]); err != nil { return http.StatusInternalServerError, err } } } if len(urls) == 0 { w.Write([]byte("[]")) } else { json.NewEncoder(w).Encode(urls) } return http.StatusOK, nil }
// AddBooking - Associate a performer to an event func AddBooking(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) const timeformat = "2006-01-02 15:04:05 -0700" st, _ := time.Parse(timeformat, r.FormValue("set_time")) // Create the Venue object p1 := Booking{ SetTime: st, } // Load the Performer Key if len(r.FormValue("performer")) > 0 { performer, err := datastore.DecodeKey(r.FormValue("performer")) if err != nil { JSONError(&w, err.Error()) return } p1.PerformerKey = *performer } // Load the Event Key if len(r.FormValue("event")) > 0 { event, err := datastore.DecodeKey(r.FormValue("event")) if err != nil { JSONError(&w, err.Error()) return } p1.EventKey = *event } // Add the booking to the Datastore k, err := p1.Store(ctx) if err != nil { JSONError(&w, err.Error()) return } p1.DatastoreKey = k return }
func GetResultForUserChallenge(ctx context.Context, w http.ResponseWriter, r *http.Request) (int, error) { if r.Method != "GET" { return http.StatusMethodNotAllowed, nil } userKey, err := datastore.DecodeKey(mux.Vars(r)["userKey"]) if err != nil { return http.StatusBadRequest, err } challengeKey, err := datastore.DecodeKey(mux.Vars(r)["challengeKey"]) if err != nil { return http.StatusBadRequest, err } keys, err := model.NewQueryForProfile(). Ancestor(userKey). Limit(1). KeysOnly(). GetAll(ctx, nil) if err != nil { return http.StatusInternalServerError, err } if len(keys) != 1 { return http.StatusNotFound, nil } var results model.Results resultKeys, err := model.NewQueryForResult(). Filter("Challenge =", challengeKey). Ancestor(keys[0]). Limit(1). GetAll(ctx, &results) if err != nil { return http.StatusInternalServerError, err } if len(resultKeys) != 1 { return http.StatusNotFound, nil } json.NewEncoder(w).Encode(results[0].Key(resultKeys[0])) return http.StatusOK, nil }
// ClaimTicket - Verify the ticket and claim it func ClaimTicket(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) // Define container variables var hash []byte sig1 := new(big.Int) sig2 := new(big.Int) // Assign the variables sig1.SetString(vars["sig1"], 10) sig2.SetString(vars["sig2"], 10) hash = []byte(vars["hash"]) if VerifySignature(sig1, sig2, hash) { // Signature has been successfully verified, Claim it in the datastore ctx := appengine.NewContext(r) var t Ticket key, err := datastore.DecodeKey(vars["hash"]) // Check for decoding errors if err != nil { JSONError(&w, "Unable to Decode Key from provided hash") return } // Map the results to the receiving object if err = t.Load(ctx, *key); err != nil { JSONError(&w, "Unable to Retrieve Key") return } // Check for ticket validity if t.Valid == false { JSONError(&w, "Ticket has been invalidated") return } if t.Claimed == true { JSONError(&w, "Ticket has already been claimed") return } // All good, update the ticket to claimed and resave it t.Claimed = true t.Store(ctx) fmt.Fprintf(w, "%#v", t) return } JSONError(&w, "Unable to Verify Signature") return }
// Handle performs an upgrade from HTTP to WebSocket. It hijacks the connection // and registers it in the global pool. func Handle(w http.ResponseWriter, r *http.Request) { m := r.URL.Query() result := m.Get("result") if result == "" { http.Error(w, "Bad Request: missing parameter \"result\"", http.StatusBadRequest) return } key, err := datastore.DecodeKey(result) if err != nil { http.Error(w, "Bad Request: cannot decode \"result\"", http.StatusBadRequest) return } ws, err := upgrader.Upgrade(w, r, nil) if err != nil { // NOTE: Returning an HTTP error is done by upgrader. return } id := ktoi(key) conns.Lock() conns.m[ktoi(key)] = ws conns.Unlock() // Advance deadline if we receive a pong. // TODO(flowlo): maybe check whether the contents of the // message actually match those of a pending ping. ws.SetPongHandler(func(_ string) error { return ws.SetReadDeadline(time.Now().Add(pongWait)) }) // Periodically ping the client, so the pong handler will // advance the read deadline. go ping(ws, id) // Read infinitely. This is needed because otherwise // our pong handler will never be triggered. // Although we discard all application messages, // errors need to be handled, i.e. in case the // connection dies and times out, because no pong // was reveived within pongWait. for { _, _, err := ws.ReadMessage() if err != nil { die(id, err) return } } }
// AddTicket - Adds a valid ticket for the event and stores it in the datastore func AddTicket(w http.ResponseWriter, r *http.Request) { var buffer bytes.Buffer vars := mux.Vars(r) // Load the event datastore key event, err := datastore.DecodeKey(vars["eventId"]) if err != nil { panic(err) } // Create an appengine context ctx := appengine.NewContext(r) // fmt.Fprintf("%#v",ctx) // Build the ticket entry t := Ticket{ OrderID: r.FormValue("order_id"), EventKey: event, Valid: true, } // Store the ticket k, err := t.Store(ctx) if err != nil { panic(err) } // Create the Ticket Num var ticketnum = TicketNumber{ID: []byte(k.Encode())} ticketnum.sign() // Generate the text string to encode buffer.WriteString(ticketnum.Sig1.String()) buffer.WriteString("/") buffer.WriteString(ticketnum.Sig2.String()) buffer.WriteString("/") buffer.WriteString(string(k.Encode())) // Generate the QR code for the hash and two signatures code, err := qr.Encode(buffer.String(), qr.L) code.Scale = 2 if err != nil { panic(err) } imgByte := code.PNG() w.Header().Set("Content-Type", "image/png") w.Header().Set("Content-Disposition", `inline; filename="`+k.Encode()+`"`) w.WriteHeader(http.StatusOK) w.Write(imgByte) }
func gameFromRequest(r *http.Request) (*Game, error) { ctx := appengine.NewContext(r) k, err := datastore.DecodeKey(r.FormValue("g")) if err != nil { return nil, fmt.Errorf("invalid game ID: %v", err) } var g Game if err := datastore.Get(ctx, k, &g); err != nil { return nil, err } return &g, nil }