feat: create system user accounts

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-07-19 06:55:01 -04:00
parent 681e059870
commit c736e3ebf9
7 changed files with 112 additions and 52 deletions
+19
View File
@@ -23,6 +23,7 @@ use KTXF\Resource\Identifier\EntityIdentifier;
use KTXF\Resource\Identifier\ResourceIdentifier;
use KTXF\Resource\Identifier\ResourceIdentifiers;
use KTXF\Resource\Identifier\ServiceIdentifier;
use KTXF\Mail\Provider\ProviderBaseInterface;
use KTXF\Resource\Provider\ResourceServiceLocationInterface;
use KTXF\Routing\Attributes\AuthenticatedRoute;
use KTXM\MailManager\Manager;
@@ -82,6 +83,24 @@ class DefaultController extends ControllerAbstract {
$tenantId = $this->tenantIdentity->identifier();
$userId = $this->userIdentity->identifier();
// acting-user override: only the reserved system context is permitted,
// gated on the system mail management permission
if ($user !== null && $user !== $userId) {
if ($user !== ProviderBaseInterface::USER_SYSTEM || !$this->userIdentity->hasPermission('mail_manager.system')) {
return new JsonResponse([
'version' => $version,
'transaction' => $transaction,
'operation' => $operation,
'status' => 'error',
'data' => [
'code' => JsonResponse::HTTP_FORBIDDEN,
'message' => 'Not permitted to act as user: ' . $user
]
], JsonResponse::HTTP_FORBIDDEN);
}
$userId = $user;
}
try {
if ($operation !== null) {
+14 -6
View File
@@ -236,7 +236,14 @@ class Manager {
$serviceId = $provider->serviceCreate($tenantId, $userId, $service);
// Fetch and return the created service
return $provider->serviceFetch($tenantId, $userId, $serviceId);
$createdService = $provider->serviceFetch($tenantId, $userId, $serviceId);
if ($createdService === null) {
throw new \RuntimeException(
"Provider '$providerId' created service '$serviceId', but it could not be fetched"
);
}
return $createdService;
}
/**
@@ -1264,9 +1271,13 @@ class Manager {
}
public function entitySubmit(string $tenantId, string $userId, AddressInterface|string $sender, EntityIdentifierInterface|null $source = null, MessagePropertiesMutableInterface|array|null $message = null): EntitySubmitResult {
$service = $this->serviceFindByAddress($tenantId, $userId, $sender);
if ($sender instanceof AddressInterface === false) {
$sender = new Address($sender);
}
$service = $this->serviceFindByAddress($tenantId, $userId, $sender->getAddress());
if ($service === null || $service->getEnabled() === false) {
throw new InvalidArgumentException("Service not found for sender '{$sender}' or service is disabled");
throw new InvalidArgumentException("Service not found for sender '{$sender->getAddress()}' or service is disabled");
}
if ($service instanceof ServiceEntitySubmitInterface === false) {
throw new InvalidArgumentException("Service '{$service->identifier()}' does not support entity submission");
@@ -1276,9 +1287,6 @@ class Manager {
throw new InvalidArgumentException("At least one of source or message must be provided for entity submission");
}
if ($sender instanceof AddressInterface === false) {
$sender = new Address($sender);
}
if ($message !== null && $message instanceof MessagePropertiesMutableInterface === false) {
$message = $service->entityFresh()->getProperties()->jsonDeserialize($message);
}
+5
View File
@@ -50,6 +50,11 @@ class Module extends ModuleInstanceAbstract implements ModuleBrowserInterface
'description' => 'View and access the mail manager module',
'group' => 'Mail Management'
],
'mail_manager.system' => [
'label' => 'Manage System Mail',
'description' => 'Manage system mail accounts and routing rules (act in the reserved system user context)',
'group' => 'Mail Management'
],
];
}