// currentUser extracts the user information stored in current session.
//
// If there is no existing session, identity toolkit token is checked. If the
// token is valid, a new session is created.
//
// If any error happens, nil is returned.
func currentUser(r *http.Request) *User {
	c := appengine.NewContext(r)
	s, _ := cookieStore.Get(r, sessionName)
	if s.IsNew {
		// Create an identity toolkit client associated with the GAE context.
		client, err := gitkit.NewWithContext(c, gitkitClient)
		if err != nil {
			aelog.Errorf(c, "Failed to create a gitkit.Client with a context: %s", err)
			return nil
		}

		// Extract the token string from request.
		ts := client.TokenFromRequest(r)
		if ts == "" {
			return nil
		}
		// Check the token issue time. Only accept token that is no more than 15
		// minitues old even if it's still valid.
		token, err := client.ValidateToken(ts)
		if err != nil {
			aelog.Errorf(c, "Invalid token %s: %s", ts, err)
			return nil
		}
		if time.Now().Sub(token.IssueAt) > 15*time.Minute {
			aelog.Infof(c, "Token %s is too old. Issused at: %s", ts, token.IssueAt)
			return nil
		}
		// Fetch user info.
		u, err := client.UserByLocalID(token.LocalID)
		if err != nil {
			aelog.Errorf(c, "Failed to fetch user info for %s[%s]: %s", token.Email, token.LocalID, err)
			return nil
		}
		return &User{
			ID:            u.LocalID,
			Email:         u.Email,
			Name:          u.DisplayName,
			EmailVerified: u.EmailVerified,
		}
	} else {
		// Extracts user from current session.
		v, ok := s.Values[sessionUserKey]
		if !ok {
			aelog.Errorf(c, "no user found in current session")
		}
		return v.(*User)
	}
}
Example #2
0
func handleOOBAction(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	// Create an identity toolkit client associated with the GAE context.
	client, err := gitkit.NewWithContext(c, gitkitClient)
	if err != nil {
		aelog.Errorf(c, "Failed to create a gitkit.Client with a context: %s", err)
		w.Write([]byte(gitkit.ErrorResponse(err)))
		return
	}
	resp, err := client.GenerateOOBCode(r)
	if err != nil {
		aelog.Errorf(c, "Failed to get an OOB code: %s", err)
		w.Write([]byte(gitkit.ErrorResponse(err)))
		return
	}
	msg := &mail.Message{
		Sender: "FavWeekday Support <*****@*****.**>",
	}
	switch resp.Action {
	case gitkit.OOBActionResetPassword:
		msg.Subject = "Reset your FavWeekday account password"
		msg.HTMLBody = fmt.Sprintf(emailTemplateResetPassword, resp.Email, resp.OOBCodeURL.String())
		msg.To = []string{resp.Email}
	case gitkit.OOBActionChangeEmail:
		msg.Subject = "FavWeekday account email address change confirmation"
		msg.HTMLBody = fmt.Sprintf(emailTemplateChangeEmail, resp.Email, resp.NewEmail, resp.OOBCodeURL.String())
		msg.To = []string{resp.NewEmail}
	case gitkit.OOBActionVerifyEmail:
		msg.Subject = "FavWeekday account registration confirmation"
		msg.HTMLBody = fmt.Sprintf(emailTemplateVerifyEmail, resp.OOBCodeURL.String())
		msg.To = []string{resp.Email}
	}
	c2 := aeOrig.NewContext(r)
	if err := mail.Send(c2, msg); err != nil {
		aelog.Errorf(c, "Failed to send %s message to user %s: %s", resp.Action, resp.Email, err)
		w.Write([]byte(gitkit.ErrorResponse(err)))
		return
	}
	w.Write([]byte(gitkit.SuccessResponse()))
}
Example #3
0
/*

Failed to delete user {ID:14423325142879445183 Email:[email protected]
Name:Peter Buchmann EmailVerified:true}:
googleapi: Error 400: INVALID_LOCAL_ID, invalid

Failed to delete 00880189686365773816


Failed to delete user {ID: }: googleapi: Error 400: INVALID_LOCAL_ID, invalid
*/
func handleDeleteAccount(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	var (
		client *gitkit.Client
		err    error
	)
	// Check if there is a signed in user.
	u := CurrentUser(r)
	if u == nil {
		aelog.Errorf(c, "No signed in user for updating")
		goto out
	}
	// Validate XSRF token first.
	if !xsrftoken.Valid(r.PostFormValue(xsrfTokenName), xsrfKey, u.ID, deleteAccountURL) {
		aelog.Errorf(c, "XSRF token validation failed")
		goto out
	}
	// Create an identity toolkit client associated with the GAE context.
	client, err = gitkit.NewWithContext(c, gitkitClient)
	if err != nil {
		aelog.Errorf(c, "Failed to create a gitkit.Client with a context: %s", err)
		goto out
	}
	// Delete account.
	err = client.DeleteUser(&gitkit.User{LocalID: u.ID})
	if err != nil {
		aelog.Errorf(c, "Failed to delete user %v %v: %s", u.ID, u.Email, err)
		goto out
	}
	// Account deletion succeeded.
	// Call sign out to clear session and identity toolkit token.
	aelog.Infof(c, "Account deletion succeeded")

	handleSignOut(w, r)
	return
out:
	http.Redirect(w, r, successLandingURL, http.StatusFound)
}