mirror of
https://github.com/openziti/zrok.git
synced 2026-08-24 02:34:20 -05:00
Merge branch 'main' into v2.0.1_unshare_ownership
This commit is contained in:
@@ -18,6 +18,8 @@ FEATURE: New `zrok2 delete access` subcommand that allows end users to clean up
|
||||
|
||||
FIX: Security hardening for the `/unaccess` endpoint.
|
||||
|
||||
FIX: Always return success on reset password request, even if account not found... unless there was actually an error.
|
||||
|
||||
## v2.0.0
|
||||
|
||||
FEATURE: Major changes to how "unique names" and "reserved sharing" work. See the [zrok v2 Migration Guide](https://docs.zrok.io) for details. Reserved sharing, including the `zrok reserve`, `zrok release` and `zrok share reserved` commands have been removed. Namespaces and reserved names replace these concepts in a much more powerful, flexible way which can accomplish what reserved sharing did in a much better way. (https://github.com/openziti/zrok/issues/726)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
stderrors "errors"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/michaelquigley/df/dl"
|
||||
"github.com/openziti/zrok/v2/controller/store"
|
||||
@@ -25,8 +27,6 @@ func (handler *resetPasswordRequestHandler) Handle(params account.ResetPasswordR
|
||||
}
|
||||
dl.Infof("received reset password request for email '%v'", params.Body.EmailAddress)
|
||||
|
||||
var token string
|
||||
|
||||
trx, err := str.Begin()
|
||||
if err != nil {
|
||||
dl.Errorf("error starting transaction for request '%v': %v", params.Body.EmailAddress, err)
|
||||
@@ -34,15 +34,19 @@ func (handler *resetPasswordRequestHandler) Handle(params account.ResetPasswordR
|
||||
}
|
||||
defer func() { _ = trx.Rollback() }()
|
||||
|
||||
token, err = CreateToken()
|
||||
a, err := str.FindAccountWithEmail(params.Body.EmailAddress, trx)
|
||||
if err != nil {
|
||||
dl.Errorf("error creating token for '%v': %v", params.Body.EmailAddress, err)
|
||||
if stderrors.Is(err, store.ErrAccountNotFound) {
|
||||
dl.Infof("received reset password request for unknown email '%v'", params.Body.EmailAddress)
|
||||
return account.NewResetPasswordRequestCreated()
|
||||
}
|
||||
dl.Errorf("error looking up account for '%v': %v", params.Body.EmailAddress, err)
|
||||
return account.NewResetPasswordRequestInternalServerError()
|
||||
}
|
||||
|
||||
a, err := str.FindAccountWithEmail(params.Body.EmailAddress, trx)
|
||||
token, err := CreateToken()
|
||||
if err != nil {
|
||||
dl.Errorf("no account found for '%v': %v", params.Body.EmailAddress, err)
|
||||
dl.Errorf("error creating token for '%v': %v", params.Body.EmailAddress, err)
|
||||
return account.NewResetPasswordRequestInternalServerError()
|
||||
}
|
||||
|
||||
|
||||
+19
-11
@@ -1,8 +1,11 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
stderrors "errors"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/pkg/errors"
|
||||
pkgerrors "github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Account struct {
|
||||
@@ -15,14 +18,16 @@ type Account struct {
|
||||
Deleted bool
|
||||
}
|
||||
|
||||
var ErrAccountNotFound = stderrors.New("account not found")
|
||||
|
||||
func (str *Store) CreateAccount(a *Account, trx *sqlx.Tx) (int, error) {
|
||||
stmt, err := trx.Prepare("insert into accounts (email, salt, password, token, limitless) values (lower($1), $2, $3, $4, $5) returning id")
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "error preparing accounts insert statement")
|
||||
return 0, pkgerrors.Wrap(err, "error preparing accounts insert statement")
|
||||
}
|
||||
var id int
|
||||
if err := stmt.QueryRow(a.Email, a.Salt, a.Password, a.Token, a.Limitless).Scan(&id); err != nil {
|
||||
return 0, errors.Wrap(err, "error executing accounts insert statement")
|
||||
return 0, pkgerrors.Wrap(err, "error executing accounts insert statement")
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
@@ -30,7 +35,7 @@ func (str *Store) CreateAccount(a *Account, trx *sqlx.Tx) (int, error) {
|
||||
func (str *Store) GetAccount(id int, trx *sqlx.Tx) (*Account, error) {
|
||||
a := &Account{}
|
||||
if err := trx.QueryRowx("select * from accounts where id = $1", id).StructScan(a); err != nil {
|
||||
return nil, errors.Wrap(err, "error selecting account by id")
|
||||
return nil, pkgerrors.Wrap(err, "error selecting account by id")
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
@@ -38,7 +43,10 @@ func (str *Store) GetAccount(id int, trx *sqlx.Tx) (*Account, error) {
|
||||
func (str *Store) FindAccountWithEmail(email string, trx *sqlx.Tx) (*Account, error) {
|
||||
a := &Account{}
|
||||
if err := trx.QueryRowx("select * from accounts where email = lower($1) and not deleted", email).StructScan(a); err != nil {
|
||||
return nil, errors.Wrap(err, "error selecting account by email")
|
||||
if stderrors.Is(err, sql.ErrNoRows) {
|
||||
return nil, ErrAccountNotFound
|
||||
}
|
||||
return nil, pkgerrors.Wrap(err, "error selecting account by email")
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
@@ -46,7 +54,7 @@ func (str *Store) FindAccountWithEmail(email string, trx *sqlx.Tx) (*Account, er
|
||||
func (str *Store) FindAccountWithEmailAndDeleted(email string, trx *sqlx.Tx) (*Account, error) {
|
||||
a := &Account{}
|
||||
if err := trx.QueryRowx("select * from accounts where email = lower($1)", email).StructScan(a); err != nil {
|
||||
return nil, errors.Wrap(err, "error selecting acount by email")
|
||||
return nil, pkgerrors.Wrap(err, "error selecting acount by email")
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
@@ -54,7 +62,7 @@ func (str *Store) FindAccountWithEmailAndDeleted(email string, trx *sqlx.Tx) (*A
|
||||
func (str *Store) FindAccountWithToken(token string, trx *sqlx.Tx) (*Account, error) {
|
||||
a := &Account{}
|
||||
if err := trx.QueryRowx("select * from accounts where token = $1 and not deleted", token).StructScan(a); err != nil {
|
||||
return nil, errors.Wrap(err, "error selecting account by token")
|
||||
return nil, pkgerrors.Wrap(err, "error selecting account by token")
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
@@ -62,11 +70,11 @@ func (str *Store) FindAccountWithToken(token string, trx *sqlx.Tx) (*Account, er
|
||||
func (str *Store) UpdateAccount(a *Account, trx *sqlx.Tx) (int, error) {
|
||||
stmt, err := trx.Prepare("update accounts set email=lower($1), salt=$2, password=$3, token=$4, limitless=$5 where id = $6")
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "error preparing accounts update statement")
|
||||
return 0, pkgerrors.Wrap(err, "error preparing accounts update statement")
|
||||
}
|
||||
var id int
|
||||
if _, err := stmt.Exec(a.Email, a.Salt, a.Password, a.Token, a.Limitless, a.Id); err != nil {
|
||||
return 0, errors.Wrap(err, "error executing accounts update statement")
|
||||
return 0, pkgerrors.Wrap(err, "error executing accounts update statement")
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
@@ -74,10 +82,10 @@ func (str *Store) UpdateAccount(a *Account, trx *sqlx.Tx) (int, error) {
|
||||
func (str *Store) DeleteAccount(id int, trx *sqlx.Tx) error {
|
||||
stmt, err := trx.Prepare("update accounts set deleted = true where id = $1")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error preparing accounts delete statement")
|
||||
return pkgerrors.Wrap(err, "error preparing accounts delete statement")
|
||||
}
|
||||
if _, err := stmt.Exec(id); err != nil {
|
||||
return errors.Wrap(err, "error executing accounts delete statement")
|
||||
return pkgerrors.Wrap(err, "error executing accounts delete statement")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
stderrors "errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFindAccountWithEmailReturnsNotFoundSentinel(t *testing.T) {
|
||||
str, err := Open(&Config{Path: ":memory:", Type: "sqlite3"})
|
||||
require.NoError(t, err)
|
||||
|
||||
trx, err := str.Begin()
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = trx.Rollback() }()
|
||||
|
||||
account, err := str.FindAccountWithEmail("missing@test.com", trx)
|
||||
require.Nil(t, account)
|
||||
require.ErrorIs(t, err, ErrAccountNotFound)
|
||||
require.True(t, stderrors.Is(err, ErrAccountNotFound))
|
||||
}
|
||||
|
||||
func TestFindAccountWithEmailFindsExistingAccount(t *testing.T) {
|
||||
str, err := Open(&Config{Path: ":memory:", Type: "sqlite3"})
|
||||
require.NoError(t, err)
|
||||
|
||||
trx, err := str.Begin()
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = trx.Rollback() }()
|
||||
|
||||
_, err = str.CreateAccount(&Account{
|
||||
Email: "test@test.com",
|
||||
Password: "password",
|
||||
Token: "token",
|
||||
Salt: "salt",
|
||||
}, trx)
|
||||
require.NoError(t, err)
|
||||
|
||||
account, err := str.FindAccountWithEmail("TEST@test.com", trx)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, account)
|
||||
require.Equal(t, "test@test.com", account.Email)
|
||||
}
|
||||
Reference in New Issue
Block a user