예제 #1
0
파일: data_test.go 프로젝트: jackc/tpr
func TestDataUsersLifeCycle(t *testing.T) {
	pool := newConnPool(t)

	input := &data.User{
		Name:           data.NewString("test"),
		Email:          data.NewString("*****@*****.**"),
		PasswordDigest: data.NewBytes([]byte("digest")),
		PasswordSalt:   data.NewBytes([]byte("salt")),
	}
	userID, err := data.CreateUser(pool, input)
	if err != nil {
		t.Fatal(err)
	}

	user, err := data.SelectUserByName(pool, input.Name.Value)
	if err != nil {
		t.Fatal(err)
	}
	if user.ID.Value != userID {
		t.Errorf("Expected %v, got %v", userID, user.ID)
	}
	if user.Name != input.Name {
		t.Errorf("Expected %v, got %v", input.Name, user.Name)
	}
	if user.Email != input.Email {
		t.Errorf("Expected %v, got %v", input.Email, user.Email)
	}
	if bytes.Compare(user.PasswordDigest.Value, input.PasswordDigest.Value) != 0 {
		t.Errorf("Expected user (%v) and input (%v) PasswordDigest to match, but they did not", user.PasswordDigest, input.PasswordDigest)
	}
	if bytes.Compare(user.PasswordSalt.Value, input.PasswordSalt.Value) != 0 {
		t.Errorf("Expected user (%v), and input (%v) PasswordSalt to match, but they did not", user.PasswordSalt, input.PasswordSalt)
	}

	user, err = data.SelectUserByEmail(pool, input.Email.Value)
	if err != nil {
		t.Fatal(err)
	}
	if user.ID.Value != userID {
		t.Errorf("Expected %v, got %v", userID, user.ID)
	}
	if user.Name != input.Name {
		t.Errorf("Expected %v, got %v", input.Name, user.Name)
	}
	if user.Email != input.Email {
		t.Errorf("Expected %v, got %v", input.Email, user.Email)
	}
	if bytes.Compare(user.PasswordDigest.Value, input.PasswordDigest.Value) != 0 {
		t.Errorf("Expected user (%v) and input (%v) PasswordDigest to match, but they did not", user.PasswordDigest, input.PasswordDigest)
	}
	if bytes.Compare(user.PasswordSalt.Value, input.PasswordSalt.Value) != 0 {
		t.Errorf("Expected user (%v), and input (%v) PasswordSalt to match, but they did not", user.PasswordSalt, input.PasswordSalt)
	}

	user, err = data.SelectUserByPK(pool, userID)
	if err != nil {
		t.Fatal(err)
	}
	if user.ID.Value != userID {
		t.Errorf("Expected %v, got %v", userID, user.ID)
	}
	if user.Name != input.Name {
		t.Errorf("Expected %v, got %v", input.Name, user.Name)
	}
	if user.Email != input.Email {
		t.Errorf("Expected %v, got %v", input.Email, user.Email)
	}
	if bytes.Compare(user.PasswordDigest.Value, input.PasswordDigest.Value) != 0 {
		t.Errorf("Expected user (%v) and input (%v) PasswordDigest to match, but they did not", user.PasswordDigest, input.PasswordDigest)
	}
	if bytes.Compare(user.PasswordSalt.Value, input.PasswordSalt.Value) != 0 {
		t.Errorf("Expected user (%v), and input (%v) PasswordSalt to match, but they did not", user.PasswordSalt, input.PasswordSalt)
	}
}
예제 #2
0
파일: http.go 프로젝트: jackc/tpr
func RequestPasswordResetHandler(w http.ResponseWriter, req *http.Request, env *environment) {
	pwr := &data.PasswordReset{}
	pwr.RequestTime = data.NewTime(time.Now())

	if host, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
		if ip := net.ParseIP(host); ip != nil {
			mask := net.CIDRMask(len(ip)*8, len(ip)*8)
			pwr.RequestIP = data.NewIPNet(net.IPNet{IP: ip, Mask: mask})
		}
	}

	token, err := genLostPasswordToken()
	if err != nil {
		w.WriteHeader(500)
		fmt.Fprintln(w, `Internal server error`)
		env.logger.Error("getLostPasswordToken failed", "error", err)
		return
	}
	pwr.Token = data.NewString(token)

	var reset struct {
		Email string `json:"email"`
	}

	decoder := json.NewDecoder(req.Body)
	if err := decoder.Decode(&reset); err != nil {
		w.WriteHeader(422)
		fmt.Fprintf(w, "Error decoding request: %v", err)
		return
	}
	if reset.Email == "" {
		w.WriteHeader(422)
		fmt.Fprint(w, "Error decoding request: missing email")
		return
	}

	pwr.Email = data.NewString(reset.Email)

	user, err := data.SelectUserByEmail(env.pool, reset.Email)
	switch err {
	case nil:
		pwr.UserID = user.ID
	case data.ErrNotFound:
	default:
		w.WriteHeader(500)
		fmt.Fprintln(w, `Internal server error`)
		return
	}

	err = data.InsertPasswordReset(env.pool, pwr)
	if err != nil {
		w.WriteHeader(500)
		fmt.Fprintln(w, `Internal server error`)
		env.logger.Error("repo.CreatePasswordReset failed", "error", err)
		return
	}

	if user == nil {
		env.logger.Warn("Password reset requested for missing email", "email", reset.Email)
		return
	}

	if env.mailer == nil {
		w.WriteHeader(500)
		fmt.Fprintln(w, `Internal server error`)
		env.logger.Error("Mail is not configured -- cannot send password reset email")
		return
	}

	err = env.mailer.SendPasswordResetMail(reset.Email, token)
	if err != nil {
		w.WriteHeader(500)
		fmt.Fprintln(w, `Internal server error`)
		env.logger.Error("env.mailer.SendPasswordResetMail failed", "error", err)
		return
	}
}