Page MenuHomePhorge

D5048.1775269262.diff
No OneTemporary

Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None

D5048.1775269262.diff

diff --git a/config.prod/src/database/seeds/ImapAdminSeeder.php b/config.prod/src/database/seeds/ImapAdminSeeder.php
--- a/config.prod/src/database/seeds/ImapAdminSeeder.php
+++ b/config.prod/src/database/seeds/ImapAdminSeeder.php
@@ -16,11 +16,10 @@
*/
public function run()
{
- User::create(
- [
- 'email' => \config('services.imap.admin_login'),
- 'password' => \config('services.imap.admin_password')
- ]
- );
+ $user = new \App\User();
+ $user->email = \config('services.imap.admin_login');
+ $user->password = \config('services.imap.admin_password');
+ $user->role = \App\User::ROLE_SERVICE;
+ $user->save();
}
}
diff --git a/src/app/Console/Commands/User/CreateCommand.php b/src/app/Console/Commands/User/CreateCommand.php
--- a/src/app/Console/Commands/User/CreateCommand.php
+++ b/src/app/Console/Commands/User/CreateCommand.php
@@ -44,7 +44,7 @@
$existingDeletedUser = null;
$packagesToAssign = [];
- if ($role === User::ROLE_ADMIN || $role === User::ROLE_RESELLER) {
+ if ($role === User::ROLE_ADMIN || $role === User::ROLE_RESELLER || $role === User::ROLE_SERVICE) {
if ($error = $this->validateUserWithRole($email)) {
$this->error($error);
return 1;
diff --git a/src/app/Console/Commands/User/ResyncCommand.php b/src/app/Console/Commands/User/ResyncCommand.php
--- a/src/app/Console/Commands/User/ResyncCommand.php
+++ b/src/app/Console/Commands/User/ResyncCommand.php
@@ -59,7 +59,8 @@
if ($deletedUsers) {
$deletedUsers = $deletedUsers->where(function ($query) use ($with_ldap) {
- $query = $query->where('status', '&', User::STATUS_IMAP_READY);
+ $query = $query->where('role', '!=', User::ROLE_SERVICE)
+ ->where('status', '&', User::STATUS_IMAP_READY);
if ($with_ldap) {
$query->orWhere('status', '&', User::STATUS_LDAP_READY);
}
@@ -68,7 +69,8 @@
if ($createdUsers) {
$createdUsers = $createdUsers->where(function ($query) use ($with_ldap) {
- $query = $query->whereNot('status', '&', User::STATUS_IMAP_READY)
+ $query = $query->where('role', '!=', User::ROLE_SERVICE)
+ ->whereNot('status', '&', User::STATUS_IMAP_READY)
->orWhereNot('status', '&', User::STATUS_ACTIVE);
if ($with_ldap) {
$query->orWhereNot('status', '&', User::STATUS_LDAP_READY);
diff --git a/src/app/Console/Commands/User/SetRoleCommand.php b/src/app/Console/Commands/User/SetRoleCommand.php
--- a/src/app/Console/Commands/User/SetRoleCommand.php
+++ b/src/app/Console/Commands/User/SetRoleCommand.php
@@ -38,13 +38,6 @@
if ($role === 'null') {
$this->info("Removing role.");
$role = null;
- } else {
- if ($role === User::ROLE_ADMIN || $role === User::ROLE_RESELLER) {
- $this->info("Setting role {$role}.");
- } else {
- $this->error("Invalid role {$role}.");
- return 1;
- }
}
$user->role = $role;
$user->save();
diff --git a/src/app/Http/Controllers/API/AuthController.php b/src/app/Http/Controllers/API/AuthController.php
--- a/src/app/Http/Controllers/API/AuthController.php
+++ b/src/app/Http/Controllers/API/AuthController.php
@@ -88,6 +88,11 @@
return response()->json(['status' => 'error', 'message' => self::trans('auth.failed')], 401);
}
+ if ($user->role == \App\User::ROLE_SERVICE) {
+ \Log::debug("[Auth] Login with service account not allowed: {$request->email}");
+ return response()->json(['status' => 'error', 'message' => self::trans('auth.failed')], 401);
+ }
+
return self::logonResponse($user, $request->password, $request->secondfactor);
}
diff --git a/src/app/Jobs/User/CreateJob.php b/src/app/Jobs/User/CreateJob.php
--- a/src/app/Jobs/User/CreateJob.php
+++ b/src/app/Jobs/User/CreateJob.php
@@ -39,10 +39,11 @@
if ($user->role) {
\Log::info("Ignoring user with a role");
- // Admins/resellers don't reside in LDAP (for now)
+ // Admins/resellers/service accounts don't reside in LDAP (for now)
return;
}
+ // TODO: this can be removed in favor of the above once we are sure the role is set everywhere.
if ($user->email == \config('services.imap.admin_login')) {
\Log::info("Ignoring imap admin");
// Ignore Cyrus admin account
diff --git a/src/app/Observers/UserObserver.php b/src/app/Observers/UserObserver.php
--- a/src/app/Observers/UserObserver.php
+++ b/src/app/Observers/UserObserver.php
@@ -36,6 +36,10 @@
*/
public function created(User $user)
{
+ if ($user->role == \App\User::ROLE_SERVICE) {
+ return;
+ }
+
$settings = [
'country' => \App\Utils::countryForRequest(),
'currency' => \config('app.currency'),
@@ -80,6 +84,10 @@
*/
public function deleted(User $user)
{
+ if ($user->role == \App\User::ROLE_SERVICE) {
+ return;
+ }
+
// Remove the user from existing groups
$wallet = $user->wallet();
if ($wallet && $wallet->owner) {
@@ -104,6 +112,10 @@
*/
public function deleting(User $user)
{
+ if ($user->role == \App\User::ROLE_SERVICE) {
+ return;
+ }
+
// Remove owned users/domains/groups/resources/etc
self::removeRelatedObjects($user, $user->isForceDeleting());
@@ -140,6 +152,10 @@
*/
public function restored(User $user)
{
+ if ($user->role == \App\User::ROLE_SERVICE) {
+ return;
+ }
+
// We need at least the user domain so it can be created in ldap.
// FIXME: What if the domain is owned by someone else?
$domain = $user->domain();
@@ -163,6 +179,10 @@
*/
public function updated(User $user)
{
+ if ($user->role == \App\User::ROLE_SERVICE) {
+ return;
+ }
+
if (!$user->trashed()) {
\App\Jobs\User\UpdateJob::dispatch($user->id);
}
diff --git a/src/app/User.php b/src/app/User.php
--- a/src/app/User.php
+++ b/src/app/User.php
@@ -65,6 +65,7 @@
public const ROLE_ADMIN = 'admin';
public const ROLE_RESELLER = 'reseller';
+ public const ROLE_SERVICE = 'service';
/** @var int The allowed states for this object used in StatusPropertyTrait */
private int $allowed_states = self::STATUS_NEW |
@@ -196,7 +197,7 @@
*/
public function canRead($object): bool
{
- if ($this->role == 'admin') {
+ if ($this->role == self::ROLE_ADMIN) {
return true;
}
@@ -204,8 +205,8 @@
return true;
}
- if ($this->role == 'reseller') {
- if ($object instanceof User && $object->role == 'admin') {
+ if ($this->role == self::ROLE_RESELLER) {
+ if ($object instanceof User && $object->role == self::ROLE_ADMIN) {
return false;
}
@@ -242,12 +243,12 @@
return true;
}
- if ($this->role == 'admin') {
+ if ($this->role == self::ROLE_ADMIN) {
return true;
}
- if ($this->role == 'reseller') {
- if ($object instanceof User && $object->role == 'admin') {
+ if ($this->role == self::ROLE_RESELLER) {
+ if ($object instanceof User && $object->role == self::ROLE_ADMIN) {
return false;
}
@@ -678,7 +679,7 @@
*/
public function setRoleAttribute($role)
{
- if ($role !== null && !in_array($role, [self::ROLE_ADMIN, self::ROLE_RESELLER])) {
+ if ($role !== null && !in_array($role, [self::ROLE_ADMIN, self::ROLE_RESELLER, self::ROLE_SERVICE])) {
throw new \Exception("Invalid role: {$role}");
}
diff --git a/src/tests/Feature/Controller/AuthTest.php b/src/tests/Feature/Controller/AuthTest.php
--- a/src/tests/Feature/Controller/AuthTest.php
+++ b/src/tests/Feature/Controller/AuthTest.php
@@ -200,6 +200,27 @@
return $json['access_token'];
}
+ /**
+ * Test service account login attempt
+ */
+ public function testLoginServiceAccount(): void
+ {
+ $user = $this->getTestUser('cyrus-admin');
+ $user->role = \App\User::ROLE_SERVICE;
+ $user->password = 'simple123';
+ $user->save();
+
+ // Request with service account
+ $post = ['email' => 'cyrus-admin', 'password' => 'simple123'];
+ $response = $this->post("api/auth/login", $post);
+ $response->assertStatus(401);
+
+ $json = $response->json();
+
+ $this->assertSame('error', $json['status']);
+ $this->assertSame('Invalid username or password.', $json['message']);
+ }
+
/**
* Test /api/auth/login with geo-lockin
*/
diff --git a/src/tests/Feature/Controller/NGINXTest.php b/src/tests/Feature/Controller/NGINXTest.php
--- a/src/tests/Feature/Controller/NGINXTest.php
+++ b/src/tests/Feature/Controller/NGINXTest.php
@@ -328,7 +328,9 @@
$response = $this->postWithBody("api/webhooks/cyrus-sasl", "john kolab.org fail");
$response->assertStatus(403);
- $this->getTestUser('cyrus-admin');
+ $serviceUser = $this->getTestUser('cyrus-admin');
+ $serviceUser->role = \App\User::ROLE_SERVICE;
+ $serviceUser->save();
// service-account Pass
$response = $this->postWithBody("api/webhooks/cyrus-sasl", "cyrus-admin $pass");

File Metadata

Mime Type
text/plain
Expires
Sat, Apr 4, 2:21 AM (1 d, 8 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18827760
Default Alt Text
D5048.1775269262.diff (9 KB)

Event Timeline