Expand a few repositories to support user groups.

This commit is contained in:
James Cole
2025-02-09 09:30:44 +01:00
parent c61389037d
commit 53e46895aa
22 changed files with 121 additions and 76 deletions

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest; use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
@@ -41,6 +42,8 @@ class TransactionController extends Controller
private TransactionGroupRepositoryInterface $groupRepository; private TransactionGroupRepositoryInterface $groupRepository;
private JournalRepositoryInterface $repository; private JournalRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
/** /**
* TransactionController constructor. * TransactionController constructor.
*/ */
@@ -51,10 +54,12 @@ class TransactionController extends Controller
function ($request, $next) { function ($request, $next) {
/** @var User $user */ /** @var User $user */
$user = auth()->user(); $user = auth()->user();
$userGroup = $this->validateUserGroup($request);
$this->repository = app(JournalRepositoryInterface::class); $this->repository = app(JournalRepositoryInterface::class);
$this->groupRepository = app(TransactionGroupRepositoryInterface::class); $this->groupRepository = app(TransactionGroupRepositoryInterface::class);
$this->repository->setUser($user); $this->repository->setUser($user);
$this->groupRepository->setUser($user); $this->groupRepository->setUser($user);
$this->groupRepository->setUserGroup($userGroup);
return $next($request); return $next($request);
} }

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\V2\AbstractTransformer; use FireflyIII\Transformers\V2\AbstractTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@@ -59,6 +60,7 @@ abstract class Controller extends BaseController
use AuthorizesRequests; use AuthorizesRequests;
use DispatchesJobs; use DispatchesJobs;
use ValidatesRequests; use ValidatesRequests;
use ValidatesUserGroupTrait;
protected const string CONTENT_TYPE = 'application/vnd.api+json'; protected const string CONTENT_TYPE = 'application/vnd.api+json';
protected const string JSON_CONTENT_TYPE = 'application/json'; protected const string JSON_CONTENT_TYPE = 'application/json';

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Models\Transaction;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\Transaction\StoreRequest; use FireflyIII\Api\V1\Requests\Models\Transaction\StoreRequest;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Events\StoredTransactionGroup; use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Exceptions\DuplicateTransactionException; use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
@@ -37,6 +38,7 @@ use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use League\Fractal\Resource\Item; use League\Fractal\Resource\Item;
@@ -49,6 +51,8 @@ class StoreController extends Controller
private TransactionGroupRepositoryInterface $groupRepository; private TransactionGroupRepositoryInterface $groupRepository;
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
/** /**
* TransactionController constructor. * TransactionController constructor.
*/ */
@@ -59,9 +63,11 @@ class StoreController extends Controller
function ($request, $next) { function ($request, $next) {
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $admin = auth()->user();
$userGroup = $this->validateUserGroup($request);
$this->groupRepository = app(TransactionGroupRepositoryInterface::class); $this->groupRepository = app(TransactionGroupRepositoryInterface::class);
$this->groupRepository->setUser($admin); $this->groupRepository->setUser($admin);
$this->groupRepository->setUserGroup($userGroup);
return $next($request); return $next($request);
} }
@@ -80,27 +86,23 @@ class StoreController extends Controller
{ {
app('log')->debug('Now in API StoreController::store()'); app('log')->debug('Now in API StoreController::store()');
$data = $request->getAll(); $data = $request->getAll();
$data['user'] = auth()->user()->id; $data['user'] = auth()->user();
$data['user_group'] = $this->userGroup;
Log::channel('audit') Log::channel('audit')->info('Store new transaction over API.', $data);
->info('Store new transaction over API.', $data)
;
try { try {
$transactionGroup = $this->groupRepository->store($data); $transactionGroup = $this->groupRepository->store($data);
} catch (DuplicateTransactionException $e) { } catch (DuplicateTransactionException $e) {
app('log')->warning('Caught a duplicate transaction. Return error message.'); app('log')->warning('Caught a duplicate transaction. Return error message.');
$validator = \Validator::make( $validator = Validator::make(['transactions' => [['description' => $e->getMessage()]]], ['transactions.0.description' => new IsDuplicateTransaction()]);
['transactions' => [['description' => $e->getMessage()]]],
['transactions.0.description' => new IsDuplicateTransaction()]
);
throw new ValidationException($validator); throw new ValidationException($validator);
} catch (FireflyException $e) { } catch (FireflyException $e) {
app('log')->warning('Caught an exception. Return error message.'); app('log')->warning('Caught an exception. Return error message.');
app('log')->error($e->getMessage()); app('log')->error($e->getMessage());
$message = sprintf('Internal exception: %s', $e->getMessage()); $message = sprintf('Internal exception: %s', $e->getMessage());
$validator = \Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]); $validator = Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]);
throw new ValidationException($validator); throw new ValidationException($validator);
} }
@@ -119,11 +121,11 @@ class StoreController extends Controller
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector $collector
->setUser($admin) ->setUser($admin)
->setUserGroup($this->userGroup)
// filter on transaction group. // filter on transaction group.
->setTransactionGroup($transactionGroup) ->setTransactionGroup($transactionGroup)
// all info needed for the API: // all info needed for the API:
->withAPIInformation() ->withAPIInformation();
;
$selectedGroup = $collector->getGroups()->first(); $selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) { if (null === $selectedGroup) {

View File

@@ -32,6 +32,7 @@ use FireflyIII\Models\AccountBalance;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface; use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Api\ExchangeRateConverter; use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Factory;
use FireflyIII\Models\Location; use FireflyIII\Models\Location;
use FireflyIII\Models\Tag; use FireflyIII\Models\Tag;
use FireflyIII\Models\UserGroup;
use FireflyIII\User; use FireflyIII\User;
/** /**
@@ -34,6 +35,7 @@ use FireflyIII\User;
class TagFactory class TagFactory
{ {
private User $user; private User $user;
private UserGroup $userGroup;
public function findOrCreate(string $tag): ?Tag public function findOrCreate(string $tag): ?Tag
{ {
@@ -102,5 +104,11 @@ class TagFactory
public function setUser(User $user): void public function setUser(User $user): void
{ {
$this->user = $user; $this->user = $user;
$this->userGroup = $user->userGroup;
}
public function setUserGroup(UserGroup $userGroup): void
{
$this->userGroup = $userGroup;
} }
} }

View File

@@ -29,6 +29,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup;
use FireflyIII\Rules\UniqueIban; use FireflyIII\Rules\UniqueIban;
use FireflyIII\Services\Internal\Update\AccountUpdateService; use FireflyIII\Services\Internal\Update\AccountUpdateService;
use FireflyIII\User; use FireflyIII\User;
@@ -216,12 +217,4 @@ class TransactionFactory
{ {
$this->reconciled = $reconciled; $this->reconciled = $reconciled;
} }
/**
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
*/
public function setUser(User $user): void
{
// empty function.
}
} }

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Factory;
use FireflyIII\Exceptions\DuplicateTransactionException; use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\UserGroup;
use FireflyIII\User; use FireflyIII\User;
/** /**
@@ -36,6 +37,7 @@ class TransactionGroupFactory
{ {
private TransactionJournalFactory $journalFactory; private TransactionJournalFactory $journalFactory;
private User $user; private User $user;
private UserGroup $userGroup;
/** /**
* TransactionGroupFactory constructor. * TransactionGroupFactory constructor.
@@ -54,7 +56,8 @@ class TransactionGroupFactory
public function create(array $data): TransactionGroup public function create(array $data): TransactionGroup
{ {
app('log')->debug('Now in TransactionGroupFactory::create()'); app('log')->debug('Now in TransactionGroupFactory::create()');
$this->journalFactory->setUser($this->user); $this->journalFactory->setUser($data['user']);
$this->journalFactory->setUserGroup($data['user_group']);
$this->journalFactory->setErrorOnHash($data['error_if_duplicate_hash'] ?? false); $this->journalFactory->setErrorOnHash($data['error_if_duplicate_hash'] ?? false);
try { try {
@@ -76,7 +79,7 @@ class TransactionGroupFactory
$group = new TransactionGroup(); $group = new TransactionGroup();
$group->user()->associate($this->user); $group->user()->associate($this->user);
$group->userGroup()->associate($data['user_group'] ?? $this->user->userGroup); $group->userGroup()->associate($data['user_group']);
$group->title = $title; $group->title = $title;
$group->save(); $group->save();
@@ -92,4 +95,8 @@ class TransactionGroupFactory
{ {
$this->user = $user; $this->user = $user;
} }
public function setUserGroup(UserGroup $userGroup): void {
$this->userGroup = $userGroup;
}
} }

View File

@@ -34,6 +34,7 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalMeta; use FireflyIII\Models\TransactionJournalMeta;
use FireflyIII\Models\UserGroup;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
@@ -69,6 +70,7 @@ class TransactionJournalFactory
private PiggyBankRepositoryInterface $piggyRepository; private PiggyBankRepositoryInterface $piggyRepository;
private TransactionTypeRepositoryInterface $typeRepository; private TransactionTypeRepositoryInterface $typeRepository;
private User $user; private User $user;
private UserGroup $userGroup;
/** /**
* Constructor. * Constructor.
@@ -176,8 +178,6 @@ class TransactionJournalFactory
if (true === FireflyConfig::get('utc', false)->data) { if (true === FireflyConfig::get('utc', false)->data) {
$carbon->setTimezone('UTC'); $carbon->setTimezone('UTC');
} }
// $carbon->setTimezone('UTC');
try { try {
// validate source and destination using a new Validator. // validate source and destination using a new Validator.
$this->validateAccounts($row); $this->validateAccounts($row);
@@ -228,7 +228,7 @@ class TransactionJournalFactory
$journal = TransactionJournal::create( $journal = TransactionJournal::create(
[ [
'user_id' => $this->user->id, 'user_id' => $this->user->id,
'user_group_id' => $this->user->user_group_id, 'user_group_id' => $this->userGroup->id,
'transaction_type_id' => $type->id, 'transaction_type_id' => $type->id,
'bill_id' => $billId, 'bill_id' => $billId,
'transaction_currency_id' => $currency->id, 'transaction_currency_id' => $currency->id,
@@ -244,7 +244,6 @@ class TransactionJournalFactory
/** Create two transactions. */ /** Create two transactions. */
$transactionFactory = app(TransactionFactory::class); $transactionFactory = app(TransactionFactory::class);
$transactionFactory->setUser($this->user);
$transactionFactory->setJournal($journal); $transactionFactory->setJournal($journal);
$transactionFactory->setAccount($sourceAccount); $transactionFactory->setAccount($sourceAccount);
$transactionFactory->setCurrency($currency); $transactionFactory->setCurrency($currency);
@@ -263,7 +262,6 @@ class TransactionJournalFactory
/** @var TransactionFactory $transactionFactory */ /** @var TransactionFactory $transactionFactory */
$transactionFactory = app(TransactionFactory::class); $transactionFactory = app(TransactionFactory::class);
$transactionFactory->setUser($this->user);
$transactionFactory->setJournal($journal); $transactionFactory->setJournal($journal);
$transactionFactory->setAccount($destinationAccount); $transactionFactory->setAccount($destinationAccount);
$transactionFactory->setAccountInformation($destInfo); $transactionFactory->setAccountInformation($destInfo);
@@ -405,6 +403,7 @@ class TransactionJournalFactory
public function setUser(User $user): void public function setUser(User $user): void
{ {
$this->user = $user; $this->user = $user;
$this->userGroup = $user->userGroup;
$this->currencyRepository->setUser($this->user); $this->currencyRepository->setUser($this->user);
$this->tagFactory->setUser($user); $this->tagFactory->setUser($user);
$this->billRepository->setUser($this->user); $this->billRepository->setUser($this->user);
@@ -414,6 +413,17 @@ class TransactionJournalFactory
$this->accountRepository->setUser($this->user); $this->accountRepository->setUser($this->user);
} }
public function setUserGroup(UserGroup $userGroup): void {
$this->userGroup = $userGroup;
$this->currencyRepository->setUserGroup($userGroup);
$this->tagFactory->setUserGroup($userGroup);
$this->billRepository->setUserGroup($userGroup);
$this->budgetRepository->setUserGroup($userGroup);
$this->categoryRepository->setUserGroup($userGroup);
$this->piggyRepository->setUserGroup($userGroup);
$this->accountRepository->setUserGroup($userGroup);
}
private function reconciliationSanityCheck(?Account $sourceAccount, ?Account $destinationAccount): array private function reconciliationSanityCheck(?Account $sourceAccount, ?Account $destinationAccount): array
{ {
app('log')->debug(sprintf('Now in %s', __METHOD__)); app('log')->debug(sprintf('Now in %s', __METHOD__));

View File

@@ -40,6 +40,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Services\Internal\Destroy\AccountDestroyService; use FireflyIII\Services\Internal\Destroy\AccountDestroyService;
use FireflyIII\Services\Internal\Update\AccountUpdateService; use FireflyIII\Services\Internal\Update\AccountUpdateService;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
@@ -51,7 +52,8 @@ use Illuminate\Support\Collection;
*/ */
class AccountRepository implements AccountRepositoryInterface class AccountRepository implements AccountRepositoryInterface
{ {
private User $user; use UserGroupTrait;
/** /**
* Moved here from account CRUD. * Moved here from account CRUD.

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\Location;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -148,6 +149,7 @@ interface AccountRepositoryInterface
public function searchAccountNr(string $query, array $types, int $limit): Collection; public function searchAccountNr(string $query, array $types, int $limit): Collection;
public function setUser(null|Authenticatable|User $user): void; public function setUser(null|Authenticatable|User $user): void;
public function setUserGroup(UserGroup $userGroup): void;
public function store(array $data): Account; public function store(array $data): Account;

View File

@@ -38,6 +38,7 @@ use FireflyIII\Services\Internal\Destroy\BillDestroyService;
use FireflyIII\Services\Internal\Update\BillUpdateService; use FireflyIII\Services\Internal\Update\BillUpdateService;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Query\JoinClause; use Illuminate\Database\Query\JoinClause;
@@ -51,8 +52,7 @@ use Illuminate\Support\Facades\Log;
class BillRepository implements BillRepositoryInterface class BillRepository implements BillRepositoryInterface
{ {
use CreatesObjectGroups; use CreatesObjectGroups;
use UserGroupTrait;
private User $user;
public function billEndsWith(string $query, int $limit): Collection public function billEndsWith(string $query, int $limit): Collection
{ {
@@ -294,13 +294,6 @@ class BillRepository implements BillRepositoryInterface
return $result; return $result;
} }
public function setUser(null|Authenticatable|User $user): void
{
if ($user instanceof User) {
$this->user = $user;
}
}
public function getPaginator(int $size): LengthAwarePaginator public function getPaginator(int $size): LengthAwarePaginator
{ {
return $this->user->bills() return $this->user->bills()

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Repositories\Bill;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Models\UserGroup;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
@@ -39,6 +40,7 @@ interface BillRepositoryInterface
public function billEndsWith(string $query, int $limit): Collection; public function billEndsWith(string $query, int $limit): Collection;
public function billStartsWith(string $query, int $limit): Collection; public function billStartsWith(string $query, int $limit): Collection;
public function setUserGroup(UserGroup $userGroup): void;
/** /**
* Add correct order to bills. * Add correct order to bills.

View File

@@ -41,6 +41,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\BudgetDestroyService; use FireflyIII\Services\Internal\Destroy\BudgetDestroyService;
use FireflyIII\Support\Http\Api\ExchangeRateConverter; use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
@@ -52,7 +53,7 @@ use Illuminate\Support\Facades\Log;
*/ */
class BudgetRepository implements BudgetRepositoryInterface class BudgetRepository implements BudgetRepositoryInterface
{ {
private User $user; use UserGroupTrait;
public function budgetEndsWith(string $query, int $limit): Collection public function budgetEndsWith(string $query, int $limit): Collection
{ {
@@ -154,13 +155,6 @@ class BudgetRepository implements BudgetRepositoryInterface
return $return; return $return;
} }
public function setUser(null|Authenticatable|User $user): void
{
if ($user instanceof User) {
$this->user = $user;
}
}
public function getActiveBudgets(): Collection public function getActiveBudgets(): Collection
{ {
return $this->user->budgets()->where('active', true) return $this->user->budgets()->where('active', true)

View File

@@ -27,6 +27,7 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\AutoBudget; use FireflyIII\Models\AutoBudget;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Models\UserGroup;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -39,6 +40,7 @@ interface BudgetRepositoryInterface
public function budgetEndsWith(string $query, int $limit): Collection; public function budgetEndsWith(string $query, int $limit): Collection;
public function budgetStartsWith(string $query, int $limit): Collection; public function budgetStartsWith(string $query, int $limit): Collection;
public function setUserGroup(UserGroup $userGroup): void;
/** /**
* Returns the amount that is budgeted in a period. * Returns the amount that is budgeted in a period.

View File

@@ -33,6 +33,7 @@ use FireflyIII\Models\RecurrenceTransactionMeta;
use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleAction;
use FireflyIII\Services\Internal\Destroy\CategoryDestroyService; use FireflyIII\Services\Internal\Destroy\CategoryDestroyService;
use FireflyIII\Services\Internal\Update\CategoryUpdateService; use FireflyIII\Services\Internal\Update\CategoryUpdateService;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -43,7 +44,7 @@ use Illuminate\Support\Facades\Log;
*/ */
class CategoryRepository implements CategoryRepositoryInterface class CategoryRepository implements CategoryRepositoryInterface
{ {
private User $user; use UserGroupTrait;
public function categoryEndsWith(string $query, int $limit): Collection public function categoryEndsWith(string $query, int $limit): Collection
{ {

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Repositories\Category;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Models\UserGroup;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -87,6 +88,7 @@ interface CategoryRepositoryInterface
public function searchCategory(string $query, int $limit): Collection; public function searchCategory(string $query, int $limit): Collection;
public function setUser(null|Authenticatable|User $user): void; public function setUser(null|Authenticatable|User $user): void;
public function setUserGroup(UserGroup $userGroup): void;
/** /**
* @throws FireflyException * @throws FireflyException

View File

@@ -36,6 +36,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -48,7 +49,8 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
{ {
use ModifiesPiggyBanks; use ModifiesPiggyBanks;
private User $user; use UserGroupTrait;
public function destroyAll(): void public function destroyAll(): void
{ {

View File

@@ -29,6 +29,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\PiggyBank; use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankRepetition; use FireflyIII\Models\PiggyBankRepetition;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -136,6 +137,7 @@ interface PiggyBankRepositoryInterface
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool; public function setOrder(PiggyBank $piggyBank, int $newOrder): bool;
public function setUser(null|Authenticatable|User $user): void; public function setUser(null|Authenticatable|User $user): void;
public function setUserGroup(UserGroup $userGroup): void;
/** /**
* Store new piggy bank. * Store new piggy bank.

View File

@@ -43,6 +43,7 @@ use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService; use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
use FireflyIII\Services\Internal\Update\GroupUpdateService; use FireflyIII\Services\Internal\Update\GroupUpdateService;
use FireflyIII\Support\NullArrayObject; use FireflyIII\Support\NullArrayObject;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
@@ -53,7 +54,7 @@ use Illuminate\Support\Collection;
*/ */
class TransactionGroupRepository implements TransactionGroupRepositoryInterface class TransactionGroupRepository implements TransactionGroupRepositoryInterface
{ {
private User $user; use UserGroupTrait;
public function countAttachments(int $journalId): int public function countAttachments(int $journalId): int
{ {
@@ -163,13 +164,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $result; return $result;
} }
public function setUser(null|Authenticatable|User $user): void
{
if ($user instanceof User) {
$this->user = $user;
}
}
/** /**
* Get the note text for a journal (by ID). * Get the note text for a journal (by ID).
*/ */
@@ -408,7 +402,8 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
{ {
/** @var TransactionGroupFactory $factory */ /** @var TransactionGroupFactory $factory */
$factory = app(TransactionGroupFactory::class); $factory = app(TransactionGroupFactory::class);
$factory->setUser($this->user); $factory->setUser($data['user']);
$factory->setUserGroup($data['user_group']);
try { try {
return $factory->create($data); return $factory->create($data);

View File

@@ -28,6 +28,7 @@ use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Location; use FireflyIII\Models\Location;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\UserGroup;
use FireflyIII\Support\NullArrayObject; use FireflyIII\Support\NullArrayObject;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
@@ -98,6 +99,7 @@ interface TransactionGroupRepositoryInterface
public function getTags(int $journalId): array; public function getTags(int $journalId): array;
public function setUser(null|Authenticatable|User $user): void; public function setUser(null|Authenticatable|User $user): void;
public function setUserGroup(UserGroup $userGroup): void;
/** /**
* Create a new transaction group. * Create a new transaction group.

View File

@@ -38,6 +38,7 @@ use Illuminate\Support\Facades\Log;
*/ */
trait ValidatesUserGroupTrait trait ValidatesUserGroupTrait
{ {
protected ?UserGroup $userGroup = null;
/** /**
* An "undocumented" filter * An "undocumented" filter
* *
@@ -98,7 +99,7 @@ trait ValidatesUserGroupTrait
foreach ($roles as $role) { foreach ($roles as $role) {
if ($user->hasRoleInGroupOrOwner($group, $role)) { if ($user->hasRoleInGroupOrOwner($group, $role)) {
Log::debug(sprintf('validateUserGroup: User has role "%s" in group #%d, return the group.', $role->value, $groupId)); Log::debug(sprintf('validateUserGroup: User has role "%s" in group #%d, return the group.', $role->value, $groupId));
$this->userGroup = $group;
return $group; return $group;
} }
Log::debug(sprintf('validateUserGroup: User does NOT have role "%s" in group #%d, continue searching.', $role->value, $groupId)); Log::debug(sprintf('validateUserGroup: User does NOT have role "%s" in group #%d, continue searching.', $role->value, $groupId));

View File

@@ -24,30 +24,46 @@ declare(strict_types=1);
namespace FireflyIII\Support\Repositories\UserGroup; namespace FireflyIII\Support\Repositories\UserGroup;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\GroupMembership; use FireflyIII\Models\GroupMembership;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Facades\Log;
/** /**
* Trait UserGroupTrait * Trait UserGroupTrait
*/ */
trait UserGroupTrait trait UserGroupTrait
{ {
protected User $user; protected ?User $user = null;
protected UserGroup $userGroup; protected ?UserGroup $userGroup = null;
public function getUserGroup(): UserGroup public function getUserGroup(): UserGroup
{ {
return $this->userGroup; return $this->userGroup;
} }
public function checkUserGroupAccess(UserRoleEnum $role): bool
{
$result = $this->user->hasRoleInGroupOrOwner($this->userGroup, $role);
if($result) {
Log::debug(sprintf('User #%d has role %s in group #%d or is owner/full.', $this->user->id, $role->value, $this->userGroup->id));
return true;
}
Log::warning(sprintf('User #%d DOES NOT have role %s in group #%d.', $this->user->id, $role->value, $this->userGroup->id));
return false;
}
/** /**
* TODO This method does not check if the user has access to this particular user group. * TODO This method does not check if the user has access to this particular user group.
*/ */
public function setUserGroup(UserGroup $userGroup): void public function setUserGroup(UserGroup $userGroup): void
{ {
if (null === $this->user) {
Log::warning(sprintf('User is not set in repository %s', get_class($this)));
}
$this->userGroup = $userGroup; $this->userGroup = $userGroup;
} }
@@ -62,7 +78,9 @@ trait UserGroupTrait
throw new FireflyException(sprintf('User #%d has no user group.', $user->id)); throw new FireflyException(sprintf('User #%d has no user group.', $user->id));
} }
$this->userGroup = $user->userGroup; $this->userGroup = $user->userGroup;
return;
} }
throw new FireflyException(sprintf('Object is of class %s, not User.', get_class($user)));
} }
/** /**
@@ -72,8 +90,7 @@ trait UserGroupTrait
{ {
$memberships = GroupMembership::where('user_id', $this->user->id) $memberships = GroupMembership::where('user_id', $this->user->id)
->where('user_group_id', $userGroupId) ->where('user_group_id', $userGroupId)
->count() ->count();
;
if (0 === $memberships) { if (0 === $memberships) {
throw new FireflyException(sprintf('User #%d has no access to administration #%d', $this->user->id, $userGroupId)); throw new FireflyException(sprintf('User #%d has no access to administration #%d', $this->user->id, $userGroupId));
} }
@@ -83,6 +100,6 @@ trait UserGroupTrait
if (null === $userGroup) { if (null === $userGroup) {
throw new FireflyException(sprintf('Cannot find administration for user #%d', $this->user->id)); throw new FireflyException(sprintf('Cannot find administration for user #%d', $this->user->id));
} }
$this->userGroup = $userGroup; $this->setUserGroup($userGroup);
} }
} }