func registerPaperStudent(w http.ResponseWriter, r *http.Request) *webapp.Error { if r.Method != "POST" { w.WriteHeader(http.StatusMethodNotAllowed) fmt.Fprintf(w, "Method not allowed") return nil } c := appengine.NewContext(r) user, class, werr := classAndUser(w, r) if werr != nil { return werr } token, ok := checkToken(c, user.ID, r.URL.Path, r.FormValue(auth.TokenFieldName)) if !ok { return webapp.UnauthorizedError(fmt.Errorf("Invalid auth token")) } fields, err := webapp.ParseRequiredValues(r, "firstname", "lastname", "email", "type") if err != nil { return missingFields(w) } acct, err := account.WithEmail(c, fields["email"]) switch err { case nil: // Register with existing account break case account.ErrUserNotFound: // Need to create a paper account for this registration. This account will not be stored. info := account.Info{ FirstName: fields["firstname"], LastName: fields["lastname"], Email: fields["email"], } if phone := fields["phone"]; phone != "" { info.Phone = phone } acct = account.Paper(info, class.ID) break default: return webapp.InternalError(fmt.Errorf("failed to look up account for %q: %s", fields["email"], err)) } var student *students.Student if fields["type"] == "dropin" { // TODO(rwsims): The date here should really be the end time of the // class on the given day. date, err := parseLocalDate(r.FormValue("date")) if err != nil { return invalidData(w, "Invalid date; please use mm/dd/yyyy format") } student = students.NewDropIn(acct, class, date) } else { student = students.New(acct, class) } switch err := student.Add(c, time.Now()); err { case nil: break case students.ErrClassIsFull: if err := classFullPage.Execute(w, class); err != nil { return webapp.InternalError(err) } default: return webapp.InternalError(fmt.Errorf("failed to write student: %s", err)) } token.Delete(c) http.Redirect(w, r, fmt.Sprintf("/roster?class=%d", class.ID), http.StatusSeeOther) return nil }
func newAccount(w http.ResponseWriter, r *http.Request) *webapp.Error { target := continueTarget(r) c := appengine.NewContext(r) u := user.Current(c) if u == nil { webapp.RedirectToLogin(w, r, "/") return nil } if _, err := account.ForUser(c, u); err != account.ErrUserNotFound { if err != nil { return webapp.InternalError(fmt.Errorf("failed to account for current user: %s", err)) } http.Redirect(w, r, "/", http.StatusFound) return nil } id, err := account.ID(u) if err != nil { return webapp.InternalError(err) } if r.Method == "POST" { token, err := auth.TokenForRequest(c, id, r.URL.Path) if err != nil { return webapp.UnauthorizedError(fmt.Errorf("no stored token for request")) } if !token.IsValid(r.FormValue(auth.TokenFieldName), time.Now()) { return webapp.UnauthorizedError(fmt.Errorf("invalid XSRF token")) } fields, err := webapp.ParseRequiredValues(r, "email", "firstname", "lastname") if err != nil { // TODO(rwsims): Clean up this error reporting. w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "Please go back and enter all required data.") return nil } claim := account.NewClaimedEmail(c, id, fields["email"]) switch err := claim.Claim(c); { case err == nil: break case err == account.ErrEmailAlreadyClaimed: // TODO(rwsims): Clean up this error reporting. w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "That email is already in use; please use a different email") return nil default: return webapp.InternalError(fmt.Errorf("failed to claim email %q: %s", claim.Email, err)) } info := account.Info{ FirstName: fields["firstname"], LastName: fields["lastname"], Email: fields["email"], } if phone := r.FormValue("phone"); phone != "" { info.Phone = phone } acct, err := account.New(u, info) if err != nil { return webapp.InternalError(fmt.Errorf("failed to create user account: %s", err)) } if err := acct.Put(c); err != nil { return webapp.InternalError(fmt.Errorf("failed to write new user account: %s", err)) } if err := acct.SendConfirmation(c); err != nil { c.Errorf("Failed to send confirmation email to %q: %s", acct.Email, err) } http.Redirect(w, r, target, http.StatusSeeOther) token.Delete(c) return nil } token, err := auth.NewToken(id, r.URL.Path, time.Now()) if err != nil { return webapp.InternalError(fmt.Errorf("failed to create auth token: %s", err)) } if err := token.Store(c); err != nil { return webapp.InternalError(fmt.Errorf("failed to store token: %s", err)) } data := map[string]interface{}{ "Target": target, "Token": token.Encode(), } if err := newAccountPage.Execute(w, data); err != nil { return webapp.InternalError(err) } return nil }