func ustring(u *user.User) string { if u == nil { return "" } else { return u.String() } }
func addEntry(w http.ResponseWriter, r *http.Request, c appengine.Context, u *user.User, t EntryType) error { date, err := time.Parse("2006-01-02", r.FormValue("date")) if err != nil { return err } e := Entry{Date: date, User: u.String(), Type: t} switch t { case Payment: amount, err := ParseCents(r.FormValue("amount")) if err != nil { return err } e.Amount = amount if len(r.FormValue("IsLoan")) != 0 { e.Type = Loan } case RateChange: rate, err := strconv.ParseFloat(r.FormValue("rate"), 32) if err != nil { return err } e.Rate = float32(rate) } log.Println("entry", e) if _, err := datastore.Put(c, datastore.NewIncompleteKey(c, "Entry", nil), &e); err != nil { return err } http.Redirect(w, r, "/", http.StatusFound) return nil }
func InvalidUserPage(c appengine.Context, w http.ResponseWriter, r *http.Request, u *user.User) { w.Header().Set("Content-Type", "text/html") w.WriteHeader(http.StatusForbidden) logoutUrl, err := LogoutURL(c, r) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err := notAllowedTemplate.Execute(w, notAllowedParams{u.String(), logoutUrl}); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
func articleGo(context appengine.Context, user *user.User, request *http.Request) (data Data, err error) { id := request.FormValue("id") if id != "" { var userkey *datastore.Key var userdata UserData userkey, userdata, err = mustGetUserData(context, user.String()) if err != nil { return } article := getArticleById(userdata.Articles, id) userdata, err = selected(context, userdata, article) if err != nil { return } _, err = putUserData(context, userkey, userdata) if err != nil { return } } url := request.FormValue("url") if url != "" { return Redirect{URL: url}, nil } return }
func feedPOST(context appengine.Context, user *user.User, request *http.Request) (data Data, err error) { var userdata UserData var userkey *datastore.Key userkey, userdata, err = mustGetUserData(context, user.String()) if err != nil { return } if request.FormValue("clear") != "" { err = unsubscribeAll(context, &userdata) } if request.FormValue("input") == "json" { err = feedJSONPOST(context, &userdata, request) } else if request.FormValue("input") == "opml" { err = feedOPMLPOST(context, &userdata, request) } else if request.FormValue("input") == "form" || request.FormValue("url") != "" { err = subscribe(context, &userdata, request.FormValue("url"), false) } if err != nil { return } _, err = putUserData(context, userkey, userdata) if err != nil { return } redirect := Redirect{URL: "/app"} return redirect, nil }
func feedDELETE(context appengine.Context, user *user.User, request *http.Request) (data Data, err error) { var userdata UserData var userkey *datastore.Key userkey, userdata, err = mustGetUserData(context, user.String()) if err != nil { return } if request.FormValue("url") != "" { err = unsubscribe(context, &userdata, request.FormValue("url")) } else { err = unsubscribeAll(context, &userdata) } if err != nil { return } _, err = putUserData(context, userkey, userdata) if err != nil { return } redirect := Redirect{URL: "/app"} return redirect, nil }
func CreateUserAppengine(c appengine.Context, appengineUser *user.User) (*User, error) { u := &User{ Key: UserKey(c, appengineUser.ID), Name: appengineUser.String(), Email: appengineUser.Email, AuthDomain: appengineUser.AuthDomain, IsAdmin: user.IsAdmin(c), FederatedIdentity: appengineUser.FederatedIdentity, FederatedProvider: appengineUser.FederatedProvider, } if err := SaveUser(c, u); err != nil { c.Errorf("SaveUser error: " + err.Error()) } return u, nil }
func CreateUserFromAppengine(c appengine.Context, appengineUser *user.User) (*User, error) { u := &User{ UserId: appengineUser.ID, Name: appengineUser.String(), Email: appengineUser.Email, AuthDomain: appengineUser.AuthDomain, IsAdmin: user.IsAdmin(c), FederatedIdentity: appengineUser.FederatedIdentity, FederatedProvider: appengineUser.FederatedProvider, } initUser(u) if err := entity.Put(c, u); err != nil { return nil, err } return u, nil }
func save_user(w http.ResponseWriter, c appengine.Context, u *user.User) { el := Record{ GroupId: "11", Name: u.String(), ID: u.ID, Email: u.Email, AuthDomain: u.AuthDomain, ReceivedAt: time.Now(), } _, err := datastore.Put( c, datastore.NewIncompleteKey(c, "records", nil), &el, ) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }
func feedGET(context appengine.Context, user *user.User, request *http.Request) (data Data, err error) { u := request.FormValue("url") if u != "" { return feedURLGET(context, u) } feedData := FeedData{User: user.String()} var userdata UserData _, userdata, err = mustGetUserData(context, user.String()) if err != nil { return } for _, feed := range userdata.Feeds { var item Feed for _, defaultFeed := range builtinFeeds { if defaultFeed.URL == feed { item = defaultFeed break } } if item.URL == "" { _, err = GetFirst(context, "Feed", "URL", feed, &item) if err != nil { printError(context, err, feed) err = nil continue } } feedData.Feeds = append(feedData.Feeds, item) } feedData.SuggestedFeeds, err = getSuggestedFeeds(context, userdata) if err != nil { return } return feedData, nil }
// API to insert a new door. Requires "displayName", "regId" and "devId" of the // device. Only admins can execute this API at the moment. func insertDoor( r *http.Request, c appengine.Context, u *user.User) (*[]ApiDoor, error) { displayName := r.FormValue("displayName") if displayName == "" { return nil, Err{"'displayName' required.", http.StatusBadRequest} } regId := r.FormValue("regId") if regId == "" { return nil, Err{"'regId' required.", http.StatusBadRequest} } devId := r.FormValue("devId") if devId == "" { return nil, Err{"'devId' required.", http.StatusBadRequest} } if !u.Admin { return nil, Err{"You are not an admin.", http.StatusForbidden} } // TODO(robert): Wrap these in a txn. uKey := ds.NewKey(c, "User", u.ID, 0, nil) if err := getOrCreateUser(c, uKey, &User{u.String()}); err != nil { return nil, err } d := Door{displayName, regId, devId} dKey, err := ds.Put(c, ds.NewIncompleteKey(c, "Door", nil), &d) if err != nil { return nil, err } if _, err = ds.Put(c, ds.NewIncompleteKey(c, "Permission", nil), &Permission{uKey, dKey, LevelOwner}); err != nil { c.Errorf( "Created door (%s) but owner permission creation failed.", dKey.Encode()) return nil, err } return &[]ApiDoor{ApiDoor{dKey.Encode(), d.DisplayName, d.RegId, d.DevId}}, nil }
// fetch the user's own library (not necessarily their current library) // checks memcache first, then datastore. Populates the cache // returns the key, library and a boolean that is true if the library is new func getOwnLibrary(c appengine.Context, u *user.User) (*datastore.Key, *Library, bool) { uid := u.ID if len(uid) == 0 { uid = u.Email } init := false lid := datastore.NewKey(c, "Library", uid, 0, nil) l := &Library{} _, err := memcache.Gob.Get(c, lid.Encode(), l) if err == memcache.ErrCacheMiss { err = datastore.Get(c, lid, l) if err == datastore.ErrNoSuchEntity { l = &Library{uid, 0, u.String(), ""} lid, err = datastore.Put(c, lid, l) check(err) init = true } memcache.Gob.Set(c, &memcache.Item{Key: lid.Encode(), Object: l}) } return lid, l, init }
// Message_page presents a simple message page and presents the user // with a link that leads to a followup page. func Message_page(w http.ResponseWriter, r *http.Request, login_user *user.User, msg string, return_msg string, return_url string) { c := appengine.NewContext(r) tmpl, err := template.ParseFiles("header.html", "message.html") if err != nil { ServeError(&c, w, err) return } type TV struct { User string LoggedIn bool Msg string ReturnUrl string ReturnMsg string LogoutUrl string } template_values := new(TV) if login_user != nil { template_values.User = login_user.String() } else { template_values.User = "" } template_values.LoggedIn = login_user != nil template_values.Msg = msg template_values.ReturnUrl = return_url template_values.ReturnMsg = return_msg if err := tmpl.ExecuteTemplate(w, "message.html", template_values); err != nil { c.Errorf("Failed to execute template: %v", err) } }
func insertPermission( r *http.Request, c appengine.Context, u *user.User) (*[]Permission, error) { dKey, err := ds.DecodeKey(r.FormValue("doorKey")) if err != nil { return nil, ErrNoDoorKey } uKey := ds.NewKey(c, "User", u.ID, 0, nil) cnt := 0 cnt, err = ds.NewQuery("Permission"). Filter("userKey=", uKey). Filter("doorKey=", dKey). Count(c) if err != nil { return nil, err } if cnt > 0 { return nil, ErrApplyReject } if err = ds.Get(c, dKey, &Door{}); err != nil { if err == ds.ErrNoSuchEntity { err = ErrApplyReject } return nil, err } // Create user if doesn't already exist. if err := getOrCreateUser(c, uKey, &User{u.String()}); err != nil { return nil, err } // Create pending permission to door. p := Permission{uKey, dKey, LevelPending} if _, err = ds.Put(c, ds.NewIncompleteKey(c, "Permission", nil), &p); err != nil { return nil, err } return &[]Permission{p}, nil }
func deleter(w http.ResponseWriter, r *http.Request, c appengine.Context, u *user.User) error { keyID := r.FormValue("KeyID") log.Print("deleter", keyID) if keyID == "" { return fmt.Errorf("attempt to delete with null key") } key, err := datastore.DecodeKey(keyID) log.Print("err", err, "key", key) if err != nil { return err } var e Entry if err = datastore.Get(c, key, &e); err != nil { return err } e.Deleted = true e.DeleteUser = u.String() if _, err = datastore.Put(c, key, &e); err != nil { return err } log.Print("redirecting") http.Redirect(w, r, "/", http.StatusFound) return nil }
func subscribeUser(context appengine.Context, user *user.User, url string) (err error) { var userdata UserData var userkey *datastore.Key userkey, userdata, err = mustGetUserData(context, user.String()) if err != nil { return } err = subscribe(context, &userdata, url, false) if err != nil { return } _, err = putUserData(context, userkey, userdata) return }
// Check_access determines whether the given user has permission to // access the given project. func Check_access(user *user.User, pkey string, c *appengine.Context, w *http.ResponseWriter, r *http.Request) bool { user_name := strings.ToLower(user.String()) keyparts := strings.Split(pkey, "::") owner := keyparts[0] // A user can always access his or her own projects. if user_name == strings.ToLower(owner) { return true } // Otherwise, check if the project is shared with the user. key := datastore.NewKey(*c, "SharingByUser", user_name, 0, nil) var sbuser SharingByUser err := datastore.Get(*c, key, &sbuser) if err == datastore.ErrNoSuchEntity { check_access_failed(nil, c, w, r, user) return false } else if err != nil { check_access_failed(&err, c, w, r, user) return false } L := Clean_split(sbuser.Projects, ",") for _, x := range L { if pkey == x { return true } } check_access_failed(nil, c, w, r, user) return false }
func article(context appengine.Context, user *user.User, request *http.Request, count int) (data Data, err error) { articleData := ArticleData{Source: "/article"} if count == 0 { return articleData, nil } var userdata UserData var userkey *datastore.Key userkey, userdata, err = mustGetUserData(context, user.String()) if err != nil { return } if count > len(userdata.Articles) { // var defaultUser UserData // _, defaultUser, err = mustGetUserData(context, "default") // userdata.Articles = defaultUser.Articles printInfo(context, "refresh") refreshDelay.Call(context, "false") return Redirect{URL: "/feed"}, nil } for _, article := range userdata.Articles[0:count] { var articleCache ArticleCache _, err = memcache.Gob.Get(context, article.ID, &articleCache) if err == memcache.ErrCacheMiss { err = nil var feedCache FeedCache feedCache, err = getSubscriptionURL(context, article.FeedURL) if err != nil { printError(context, err, article.FeedURL) err = nil continue } for _, articleCache = range feedCache.Articles { if articleCache.ID == article.ID { break } } } else if err != nil { printError(context, err, article.ID) err = nil continue } if articleCache.URL != "" { articleData.Articles = append(articleData.Articles, articleCache) } } if count > len(articleData.Articles) { printInfo(context, "refresh") refreshDelay.Call(context, "false") return Redirect{URL: "/feed"}, nil } userdata.Articles = userdata.Articles[count:] userdata.TotalRead += int64(count) _, err = putUserData(context, userkey, userdata) if request.FormValue("output") == "redirect" { return Redirect{URL: articleData.Articles[0].URL}, nil } return articleData, err }