// delete world data func (a *MinecraftApi) Delete(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) u := user.Current(ctx) if u == nil { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusUnauthorized) loginURL, err := user.LoginURL(ctx, "") if err != nil { log.Errorf(ctx, "get user login URL error, %s", err.Error()) w.WriteHeader(http.StatusInternalServerError) return } w.Write([]byte(fmt.Sprintf(`{"loginURL":"%s"}`, loginURL))) return } if user.IsAdmin(ctx) == false { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusForbidden) return } keyStr := r.FormValue("key") key, err := datastore.DecodeKey(keyStr) if err != nil { log.Infof(ctx, "invalid key, %v", r.Body) w.WriteHeader(http.StatusBadRequest) w.Write([]byte(`{"message": "invalid key."}`)) return } err = datastore.RunInTransaction(ctx, func(c context.Context) error { return datastore.Delete(ctx, key) }, nil) if err != nil { log.Errorf(ctx, "Minecraft Delete Error. error = %s", err.Error()) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(`{}`) }
func TestUsers(t *testing.T) { // Only run the test if APPENGINE_DEV_APPSERVER is explicitly set. if os.Getenv("APPENGINE_DEV_APPSERVER") == "" { t.Skip("APPENGINE_DEV_APPSERVER not set") } inst, err := NewInstance(nil) if err != nil { t.Fatalf("NewInstance: %v", err) } defer inst.Close() req, err := inst.NewRequest("GET", "http://example.com/page", nil) if err != nil { t.Fatalf("NewRequest: %v", err) } ctx := appengine.NewContext(req) if user := user.Current(ctx); user != nil { t.Errorf("user.Current initially %v, want nil", user) } u := &user.User{ Email: "*****@*****.**", Admin: true, } Login(u, req) if got := user.Current(ctx); got.Email != u.Email { t.Errorf("user.Current: %v, want %v", got, u) } if admin := user.IsAdmin(ctx); !admin { t.Errorf("user.IsAdmin: %t, want true", admin) } Logout(req) if user := user.Current(ctx); user != nil { t.Errorf("user.Current after logout %v, want nil", user) } }
func (u userImpl) IsAdmin() bool { return user.IsAdmin(u.aeCtx) }
// adminHandler serves an administrative interface. func adminHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) if !user.IsAdmin(c) { http.Error(w, "forbidden", http.StatusForbidden) return } var newLink *Link var doErr error if r.Method == "POST" { key := r.FormValue("key") switch r.FormValue("do") { case "Add": newLink = &Link{key, r.FormValue("target")} doErr = putLink(c, newLink) case "Delete": k := datastore.NewKey(c, kind, key, 0, nil) doErr = datastore.Delete(c, k) default: http.Error(w, "unknown action", http.StatusBadRequest) } err := memcache.Delete(c, cacheKey(key)) if err != nil && err != memcache.ErrCacheMiss { log.Warningf(c, "%q: %v", key, err) } } var links []*Link _, err := datastore.NewQuery(kind).Order("Key").GetAll(c, &links) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Errorf(c, "%v", err) return } // Put the new link in the list if it's not there already. // (Eventual consistency means that it might not show up // immediately, which might be confusing for the user.) if newLink != nil && doErr == nil { found := false for i := range links { if links[i].Key == newLink.Key { found = true break } } if !found { links = append([]*Link{newLink}, links...) } newLink = nil } var data = struct { BaseURL string Prefix string Links []*Link New *Link Error error }{baseURL, prefix, links, newLink, doErr} if err := adminTemplate.Execute(w, &data); err != nil { log.Criticalf(c, "adminTemplate: %v", err) } }
// ServeHTTP handles Primary <-> Replica linking request. func (lp LinkToPrimaryHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) if !user.IsAdmin(c) { url, err := user.LoginURL(c, r.URL.String()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Redirect(w, r, url, http.StatusFound) return } t := r.FormValue("t") ticket, err := DecodeLinkTicket(t) if err != nil { log.Errorf(c, "failed to decode: %v", r.Method) http.Error(w, err.Error(), http.StatusInternalServerError) return } action := fmt.Sprintf("LinkToPrimary:%s", t) switch r.Method { case "GET": token, err := xsrf.Generate(c, user.Current(c).String(), action) if err != nil { log.Errorf(c, "failed to create xsrf token: %v", err) http.Error(w, "internal server error", http.StatusInternalServerError) return } linkingTemplate.Execute(w, linkingData{ PrimaryID: ticket.GetPrimaryId(), PrimaryURL: ticket.GetPrimaryUrl(), GeneratedBy: ticket.GetGeneratedBy(), XSRFToken: token, }) case "POST": err := xsrf.Check(c, r.FormValue("xsrf_token"), user.Current(c).String(), action) if err != nil { log.Errorf(c, "invalid xsrf token: %v", err) http.Error(w, "internal server error", http.StatusInternalServerError) return } err = BecomeReplica(c, ticket, user.Current(c).String()) if err != nil { log.Errorf(c, "failed to be replica: %v", err) linkingDoneTemplate.Execute(w, linkingDoneData{ Success: false, ErrorMsg: err.Error(), }) return } linkingDoneTemplate.Execute(w, linkingDoneData{ Success: true, PrimaryID: ticket.GetPrimaryId(), PrimaryURL: ticket.GetPrimaryUrl(), }) default: log.Errorf(c, "method does not match we want: %v", r.Method) w.Header().Set("Allow", "GET,POST") http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } }
// list instance func (a *ServerApi) List(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) u := user.Current(ctx) if u == nil { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusUnauthorized) loginURL, err := user.LoginURL(ctx, "") if err != nil { log.Errorf(ctx, "get user login URL error, %s", err.Error()) w.WriteHeader(http.StatusInternalServerError) return } w.Write([]byte(fmt.Sprintf(`{"loginURL":"%s"}`, loginURL))) return } if user.IsAdmin(ctx) == false { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusForbidden) return } client := &http.Client{ Transport: &oauth2.Transport{ Source: google.AppEngineTokenSource(ctx, compute.ComputeScope), Base: &urlfetch.Transport{Context: ctx}, }, } s, err := compute.New(client) if err != nil { log.Errorf(ctx, "ERROR compute.New: %s", err) w.WriteHeader(http.StatusInternalServerError) return } is := compute.NewInstancesService(s) instances, cursor, err := listInstance(ctx, is, "asia-northeast1-b") if err != nil { log.Errorf(ctx, "ERROR compute.Instance List: %s", err) w.WriteHeader(http.StatusInternalServerError) return } var res []MinecraftApiResponse for _, item := range instances { res = append(res, MinecraftApiResponse{ InstanceName: item.Name, Zone: item.Zone, IPAddr: item.NetworkInterfaces[0].AccessConfigs[0].NatIP, Status: item.Status, CreationTimestamp: item.CreationTimestamp, }) } apiRes := MinecraftApiListResponse{ Items: res, Cursor: cursor, } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiRes) }
// update world data func (a *MinecraftApi) Put(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) u := user.Current(ctx) if u == nil { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusUnauthorized) loginURL, err := user.LoginURL(ctx, "") if err != nil { log.Errorf(ctx, "get user login URL error, %s", err.Error()) w.WriteHeader(http.StatusInternalServerError) return } w.Write([]byte(fmt.Sprintf(`{"loginURL":"%s"}`, loginURL))) return } if user.IsAdmin(ctx) == false { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusForbidden) return } var minecraft Minecraft err := json.NewDecoder(r.Body).Decode(&minecraft) if err != nil { log.Infof(ctx, "rquest body, %v", r.Body) w.WriteHeader(http.StatusBadRequest) w.Write([]byte(`{"message": "invalid request."}`)) return } defer r.Body.Close() key, err := datastore.DecodeKey(minecraft.KeyStr) if err != nil { log.Infof(ctx, "invalid key, %v", r.Body) w.WriteHeader(http.StatusBadRequest) w.Write([]byte(`{"message": "invalid key."}`)) return } minecraft.Key = key err = datastore.RunInTransaction(ctx, func(c context.Context) error { var entity Minecraft err := datastore.Get(ctx, key, &entity) if err != datastore.ErrNoSuchEntity && err != nil { return err } entity.IPAddr = minecraft.IPAddr entity.Zone = minecraft.Zone entity.JarVersion = minecraft.JarVersion entity.UpdatedAt = time.Now() _, err = datastore.Put(ctx, key, &entity) if err != nil { return err } return nil }, nil) if err != nil { log.Errorf(ctx, "Minecraft Put Error. error = %s", err.Error()) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(minecraft) }