Example #1
0
// 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(`{}`)
}
Example #2
0
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)
	}
}
Example #3
0
func (u userImpl) IsAdmin() bool {
	return user.IsAdmin(u.aeCtx)
}
Example #4
0
// 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)
	}
}
Example #5
0
// 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
	}
}
Example #6
0
// 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)
}
Example #7
0
// 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)
}