feat(account): #49 replace group_id with user_id, as data sharing is a whole new complicated topic
This commit was merged in pull request #60.
This commit is contained in:
@@ -8,13 +8,13 @@ import (
|
|||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// While it may be duplicated to check for groupIds in the database access, it serves as a security layer
|
// While it may be duplicated to check for userId in the database access, it serves as a security layer
|
||||||
type Account interface {
|
type Account interface {
|
||||||
Insert(groupId uuid.UUID, account *types.Account) error
|
Insert(userId uuid.UUID, account *types.Account) error
|
||||||
Update(groupId uuid.UUID, account *types.Account) error
|
Update(userId uuid.UUID, account *types.Account) error
|
||||||
GetAll(groupId uuid.UUID) ([]*types.Account, error)
|
GetAll(userId uuid.UUID) ([]*types.Account, error)
|
||||||
Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, error)
|
Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error)
|
||||||
Delete(groupId uuid.UUID, id uuid.UUID) error
|
Delete(userId uuid.UUID, id uuid.UUID) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccountSqlite struct {
|
type AccountSqlite struct {
|
||||||
@@ -25,11 +25,11 @@ func NewAccountSqlite(db *sqlx.DB) *AccountSqlite {
|
|||||||
return &AccountSqlite{db: db}
|
return &AccountSqlite{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db AccountSqlite) Insert(groupId uuid.UUID, account *types.Account) error {
|
func (db AccountSqlite) Insert(userId uuid.UUID, account *types.Account) error {
|
||||||
|
|
||||||
_, err := db.db.Exec(`
|
_, err := db.db.Exec(`
|
||||||
INSERT INTO account (id, group_id, name, current_balance, oink_balance, created_at, created_by)
|
INSERT INTO account (id, user_id, name, current_balance, oink_balance, created_at, created_by)
|
||||||
VALUES (?,?,?,?,?,?,?)`, account.Id, groupId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy)
|
VALUES (?,?,?,?,?,?,?)`, account.Id, userId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error inserting account: %v", err)
|
log.Error("Error inserting account: %v", err)
|
||||||
return types.ErrInternal
|
return types.ErrInternal
|
||||||
@@ -38,7 +38,7 @@ func (db AccountSqlite) Insert(groupId uuid.UUID, account *types.Account) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error {
|
func (db AccountSqlite) Update(userId uuid.UUID, account *types.Account) error {
|
||||||
|
|
||||||
log.Info("Updating account: %v", account)
|
log.Info("Updating account: %v", account)
|
||||||
r, err := db.db.Exec(`
|
r, err := db.db.Exec(`
|
||||||
@@ -51,7 +51,7 @@ func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error
|
|||||||
updated_at = ?,
|
updated_at = ?,
|
||||||
updated_by = ?
|
updated_by = ?
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
AND group_id = ?`, account.Name, account.CurrentBalance, account.LastTransaction, account.OinkBalance, account.UpdatedAt, account.UpdatedBy, account.Id, groupId)
|
AND user_id = ?`, account.Name, account.CurrentBalance, account.LastTransaction, account.OinkBalance, account.UpdatedAt, account.UpdatedBy, account.Id, userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error updating account: %v", err)
|
log.Error("Error updating account: %v", err)
|
||||||
return types.ErrInternal
|
return types.ErrInternal
|
||||||
@@ -70,17 +70,17 @@ func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db AccountSqlite) GetAll(groupId uuid.UUID) ([]*types.Account, error) {
|
func (db AccountSqlite) GetAll(userId uuid.UUID) ([]*types.Account, error) {
|
||||||
|
|
||||||
accounts := make([]*types.Account, 0)
|
accounts := make([]*types.Account, 0)
|
||||||
err := db.db.Select(&accounts, `
|
err := db.db.Select(&accounts, `
|
||||||
SELECT
|
SELECT
|
||||||
id, group_id, name,
|
id, user_id, name,
|
||||||
current_balance, last_transaction, oink_balance,
|
current_balance, last_transaction, oink_balance,
|
||||||
created_at, created_by, updated_at, updated_by
|
created_at, created_by, updated_at, updated_by
|
||||||
FROM account
|
FROM account
|
||||||
WHERE group_id = ?
|
WHERE user_id = ?
|
||||||
ORDER BY name`, groupId)
|
ORDER BY name`, userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Could not getAll accounts: %v", err)
|
log.Error("Could not getAll accounts: %v", err)
|
||||||
return nil, types.ErrInternal
|
return nil, types.ErrInternal
|
||||||
@@ -89,17 +89,17 @@ func (db AccountSqlite) GetAll(groupId uuid.UUID) ([]*types.Account, error) {
|
|||||||
return accounts, nil
|
return accounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db AccountSqlite) Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, error) {
|
func (db AccountSqlite) Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error) {
|
||||||
|
|
||||||
account := &types.Account{}
|
account := &types.Account{}
|
||||||
err := db.db.Get(account, `
|
err := db.db.Get(account, `
|
||||||
SELECT
|
SELECT
|
||||||
id, group_id, name,
|
id, user_id, name,
|
||||||
current_balance, last_transaction, oink_balance,
|
current_balance, last_transaction, oink_balance,
|
||||||
created_at, created_by, updated_at, updated_by
|
created_at, created_by, updated_at, updated_by
|
||||||
FROM account
|
FROM account
|
||||||
WHERE group_id = ?
|
WHERE user_id = ?
|
||||||
AND id = ?`, groupId, id)
|
AND id = ?`, userId, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Could not get accounts: %v", err)
|
log.Error("Could not get accounts: %v", err)
|
||||||
return nil, types.ErrInternal
|
return nil, types.ErrInternal
|
||||||
@@ -108,9 +108,9 @@ func (db AccountSqlite) Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, er
|
|||||||
return account, nil
|
return account, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db AccountSqlite) Delete(groupId uuid.UUID, id uuid.UUID) error {
|
func (db AccountSqlite) Delete(userId uuid.UUID, id uuid.UUID) error {
|
||||||
|
|
||||||
res, err := db.db.Exec("DELETE FROM account WHERE id = ? and group_id = ?", id, groupId)
|
res, err := db.db.Exec("DELETE FROM account WHERE id = ? and user_id = ?", id, userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error deleting account: %v", err)
|
log.Error("Error deleting account: %v", err)
|
||||||
return types.ErrInternal
|
return types.ErrInternal
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ func (db AuthSqlite) DeleteUser(userId uuid.UUID) error {
|
|||||||
return types.ErrInternal
|
return types.ErrInternal
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = tx.Exec("DELETE FROM account WHERE group_id = ?", userId)
|
_, err = tx.Exec("DELETE FROM account WHERE user_id = ?", userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
log.Error("Could not delete accounts: %v", err)
|
log.Error("Could not delete accounts: %v", err)
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ func TestIntegrationAuth(t *testing.T) {
|
|||||||
resp, err = httpClient.Do(req)
|
resp, err = httpClient.Do(req)
|
||||||
timeEnd := time.Now()
|
timeEnd := time.Now()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
if timeEnd.Sub(timeStart) > 260*time.Millisecond || timeEnd.Sub(timeStart) <= 250*time.Millisecond {
|
if timeEnd.Sub(timeStart) > 260*time.Millisecond || timeEnd.Sub(timeStart) < 250*time.Millisecond {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
t.Logf("Time did not match: %v", timeEnd.Sub(timeStart))
|
t.Logf("Time did not match: %v", timeEnd.Sub(timeStart))
|
||||||
}
|
}
|
||||||
@@ -929,7 +929,7 @@ func TestIntegrationAuth(t *testing.T) {
|
|||||||
err = db.QueryRow("SELECT COUNT(*) FROM user WHERE user_id = ?", userId).Scan(&rows)
|
err = db.QueryRow("SELECT COUNT(*) FROM user WHERE user_id = ?", userId).Scan(&rows)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 0, rows)
|
assert.Equal(t, 0, rows)
|
||||||
err = db.QueryRow("SELECT COUNT(*) FROM account WHERE group_id = ?", userId).Scan(&rows)
|
err = db.QueryRow("SELECT COUNT(*) FROM account WHERE user_id = ?", userId).Scan(&rows)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 0, rows)
|
assert.Equal(t, 0, rows)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
CREATE TABLE account (
|
CREATE TABLE account (
|
||||||
id TEXT NOT NULL UNIQUE PRIMARY KEY,
|
id TEXT NOT NULL UNIQUE PRIMARY KEY,
|
||||||
group_id TEXT NOT NULL,
|
user_id TEXT NOT NULL,
|
||||||
|
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
|
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ func (service AccountImpl) Add(user *types.User, name string) (*types.Account, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
account := &types.Account{
|
account := &types.Account{
|
||||||
Id: newId,
|
Id: newId,
|
||||||
GroupId: user.Id,
|
UserId: user.Id,
|
||||||
|
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ func (service AccountImpl) Delete(user *types.User, id uuid.UUID) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if account.GroupId != user.Id {
|
if account.UserId != user.Id {
|
||||||
return types.ErrUnauthorized
|
return types.ErrUnauthorized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ func TestMoneyCalculation(t *testing.T) {
|
|||||||
// // GIVEN
|
// // GIVEN
|
||||||
// timestamp := time.Date(2020, 01, 01, 0, 0, 0, 0, time.UTC)
|
// timestamp := time.Date(2020, 01, 01, 0, 0, 0, 0, time.UTC)
|
||||||
//
|
//
|
||||||
// groupId := uuid.New()
|
// userId := uuid.New()
|
||||||
//
|
//
|
||||||
// account := types.Account{
|
// account := types.Account{
|
||||||
// Id: uuid.New(),
|
// Id: uuid.New(),
|
||||||
// GroupId: groupId,
|
// UserId: userId,
|
||||||
//
|
//
|
||||||
// Type: "Bank",
|
// Type: "Bank",
|
||||||
// Name: "Bank",
|
// Name: "Bank",
|
||||||
@@ -31,7 +31,7 @@ func TestMoneyCalculation(t *testing.T) {
|
|||||||
// // The PiggyBank is a fictional account. The money it "holds" is actually in the Account
|
// // The PiggyBank is a fictional account. The money it "holds" is actually in the Account
|
||||||
// piggyBank := types.PiggyBank{
|
// piggyBank := types.PiggyBank{
|
||||||
// Id: uuid.New(),
|
// Id: uuid.New(),
|
||||||
// GroupId: groupId,
|
// UserId: userId,
|
||||||
//
|
//
|
||||||
// AccountId: account.Id,
|
// AccountId: account.Id,
|
||||||
// Name: "Car",
|
// Name: "Car",
|
||||||
@@ -41,7 +41,7 @@ func TestMoneyCalculation(t *testing.T) {
|
|||||||
//
|
//
|
||||||
// savingsPlan := types.SavingsPlan{
|
// savingsPlan := types.SavingsPlan{
|
||||||
// Id: uuid.New(),
|
// Id: uuid.New(),
|
||||||
// GroupId: groupId,
|
// UserId: userId,
|
||||||
// PiggyBankId: piggyBank.Id,
|
// PiggyBankId: piggyBank.Id,
|
||||||
//
|
//
|
||||||
// MonthlySaving: 10,
|
// MonthlySaving: 10,
|
||||||
@@ -51,7 +51,7 @@ func TestMoneyCalculation(t *testing.T) {
|
|||||||
//
|
//
|
||||||
// transaction1 := types.Transaction{
|
// transaction1 := types.Transaction{
|
||||||
// Id: uuid.New(),
|
// Id: uuid.New(),
|
||||||
// GroupId: groupId,
|
// UserId: userId,
|
||||||
//
|
//
|
||||||
// AccountId: account.Id,
|
// AccountId: account.Id,
|
||||||
//
|
//
|
||||||
@@ -61,7 +61,7 @@ func TestMoneyCalculation(t *testing.T) {
|
|||||||
//
|
//
|
||||||
// transaction2 := types.Transaction{
|
// transaction2 := types.Transaction{
|
||||||
// Id: uuid.New(),
|
// Id: uuid.New(),
|
||||||
// GroupId: groupId,
|
// UserId: userId,
|
||||||
//
|
//
|
||||||
// AccountId: account.Id,
|
// AccountId: account.Id,
|
||||||
// PiggyBankId: &piggyBank.Id,
|
// PiggyBankId: &piggyBank.Id,
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Id uuid.UUID
|
Id uuid.UUID
|
||||||
GroupId uuid.UUID
|
|
||||||
Email string
|
Email string
|
||||||
EmailVerified bool
|
EmailVerified bool
|
||||||
EmailVerifiedAt *time.Time
|
EmailVerifiedAt *time.Time
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import (
|
|||||||
//
|
//
|
||||||
// If it becomes necessary to precalculate snapshots for performance reasons, this can be done in the future. But the transaction should always be the source of truth.
|
// If it becomes necessary to precalculate snapshots for performance reasons, this can be done in the future. But the transaction should always be the source of truth.
|
||||||
type Transaction struct {
|
type Transaction struct {
|
||||||
Id uuid.UUID
|
Id uuid.UUID
|
||||||
GroupId uuid.UUID
|
UserId uuid.UUID
|
||||||
|
|
||||||
AccountId uuid.UUID
|
AccountId uuid.UUID
|
||||||
// nil indicates that the transaction is not yet associated with a piggy bank
|
// nil indicates that the transaction is not yet associated with a piggy bank
|
||||||
@@ -37,8 +37,8 @@ type Transaction struct {
|
|||||||
|
|
||||||
// The Account holds money
|
// The Account holds money
|
||||||
type Account struct {
|
type Account struct {
|
||||||
Id uuid.UUID
|
Id uuid.UUID
|
||||||
GroupId uuid.UUID `db:"group_id"`
|
UserId uuid.UUID `db:"user_id"`
|
||||||
|
|
||||||
// Custom Name of the account, e.g. "Bank", "Cash", "Credit Card"
|
// Custom Name of the account, e.g. "Bank", "Cash", "Credit Card"
|
||||||
Name string
|
Name string
|
||||||
@@ -57,8 +57,8 @@ type Account struct {
|
|||||||
|
|
||||||
// The PiggyBank is a fictional account. The money it "holds" is actually in the Account
|
// The PiggyBank is a fictional account. The money it "holds" is actually in the Account
|
||||||
type PiggyBank struct {
|
type PiggyBank struct {
|
||||||
Id uuid.UUID
|
Id uuid.UUID
|
||||||
GroupId uuid.UUID
|
UserId uuid.UUID
|
||||||
|
|
||||||
AccountId uuid.UUID
|
AccountId uuid.UUID
|
||||||
Name string
|
Name string
|
||||||
@@ -73,8 +73,8 @@ type PiggyBank struct {
|
|||||||
|
|
||||||
// The SavingsPlan is applied every interval to the PiggyBank/Account as a transaction
|
// The SavingsPlan is applied every interval to the PiggyBank/Account as a transaction
|
||||||
type SavingsPlan struct {
|
type SavingsPlan struct {
|
||||||
Id uuid.UUID
|
Id uuid.UUID
|
||||||
GroupId uuid.UUID
|
UserId uuid.UUID
|
||||||
|
|
||||||
PiggyBankId uuid.UUID
|
PiggyBankId uuid.UUID
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user