mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Add more project policies
This commit is contained in:
@@ -138,86 +138,6 @@ Http::patch('/v1/projects/:projectId/oauth2')
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
});
|
||||
|
||||
Http::patch('/v1/projects/:projectId/auth/session-alerts')
|
||||
->desc('Update project sessions emails')
|
||||
->groups(['api', 'projects'])
|
||||
->label('scope', 'projects.write')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'projects',
|
||||
group: 'auth',
|
||||
name: 'updateSessionAlerts',
|
||||
description: '/docs/references/projects/update-session-alerts.md',
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_PROJECT,
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('projectId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Project unique ID.', false, ['dbForPlatform'])
|
||||
->param('alerts', false, new Boolean(true), 'Set to true to enable session emails.')
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->action(function (string $projectId, bool $alerts, Response $response, Database $dbForPlatform) {
|
||||
|
||||
$project = $dbForPlatform->getDocument('projects', $projectId);
|
||||
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$auths = $project->getAttribute('auths', []);
|
||||
$auths['sessionAlerts'] = $alerts;
|
||||
|
||||
$dbForPlatform->updateDocument('projects', $project->getId(), $project
|
||||
->setAttribute('auths', $auths));
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
});
|
||||
|
||||
Http::patch('/v1/projects/:projectId/auth/memberships-privacy')
|
||||
->desc('Update project memberships privacy attributes')
|
||||
->groups(['api', 'projects'])
|
||||
->label('scope', 'projects.write')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'projects',
|
||||
group: 'auth',
|
||||
name: 'updateMembershipsPrivacy',
|
||||
description: '/docs/references/projects/update-memberships-privacy.md',
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_PROJECT,
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('projectId', '', fn (Database $dbForPlatform) => new UID($dbForPlatform->getAdapter()->getMaxUIDLength()), 'Project unique ID.', false, ['dbForPlatform'])
|
||||
->param('userName', true, new Boolean(true), 'Set to true to show userName to members of a team.')
|
||||
->param('userEmail', true, new Boolean(true), 'Set to true to show email to members of a team.')
|
||||
->param('mfa', true, new Boolean(true), 'Set to true to show mfa to members of a team.')
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->action(function (string $projectId, bool $userName, bool $userEmail, bool $mfa, Response $response, Database $dbForPlatform) {
|
||||
$project = $dbForPlatform->getDocument('projects', $projectId);
|
||||
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$auths = $project->getAttribute('auths', []);
|
||||
|
||||
$auths['membershipsUserName'] = $userName;
|
||||
$auths['membershipsUserEmail'] = $userEmail;
|
||||
$auths['membershipsMfa'] = $mfa;
|
||||
|
||||
$dbForPlatform->updateDocument('projects', $project->getId(), $project
|
||||
->setAttribute('auths', $auths));
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
});
|
||||
|
||||
Http::patch('/v1/projects/:projectId/auth/:method')
|
||||
->desc('Update project auth method status. Use this endpoint to enable or disable a given auth method for this project.')
|
||||
->groups(['api', 'projects'])
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Enable or disable session email alerts. When enabled, users will receive email notifications when new sessions are created.
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\Policies\MembershipPrivacy;
|
||||
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Boolean;
|
||||
|
||||
class Update extends Action
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'updateProjectMembershipPrivacyPolicy';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/project/policies/membership-privacy')
|
||||
->httpAlias('/v1/projects/:projectId/auth/memberships-privacy')
|
||||
->desc('Update membership privacy policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('event', 'policies.membership-privacy.update')
|
||||
->label('audits.event', 'policies.membership-privacy.update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: 'policies',
|
||||
name: 'updateMembershipPrivacyPolicy',
|
||||
description: <<<EOT
|
||||
Updating this policy allows you to control if team members can see other members information. When enabled, all team members can see ID, name, email, phone number, and MFA status of other members..
|
||||
EOT,
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_PROJECT,
|
||||
)
|
||||
],
|
||||
))
|
||||
->param('userId', null, new Boolean(), 'Set to true if you want make user ID visible to all team members, or false to hide it.')
|
||||
->param('userEmail', null, new Boolean(), 'Set to true if you want make user email visible to all team members, or false to hide it.')
|
||||
->param('userPhone', null, new Boolean(), 'Set to true if you want make user phone number visible to all team members, or false to hide it.')
|
||||
->param('userName', null, new Boolean(), 'Set to true if you want make user name visible to all team members, or false to hide it.')
|
||||
->param('userMFA', null, new Boolean(), 'Set to true if you want make user MFA status visible to all team members, or false to hide it.')
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(
|
||||
bool $userId,
|
||||
bool $userEmail,
|
||||
bool $userPhone,
|
||||
bool $userName,
|
||||
bool $userMFA,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
Authorization $authorization,
|
||||
): void {
|
||||
$auths = $project->getAttribute('auths', []);
|
||||
|
||||
$auths['membershipsUserName'] = $userName;
|
||||
$auths['membershipsUserEmail'] = $userEmail;
|
||||
$auths['membershipsMfa'] = $userMFA;
|
||||
$auths['membershipsUserId'] = $userId;
|
||||
$auths['membershipsUserPhone'] = $userPhone;
|
||||
|
||||
$updates = new Document([
|
||||
'auths' => $auths,
|
||||
]);
|
||||
|
||||
$project = $authorization->skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $updates));
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
}
|
||||
}
|
||||
+1
@@ -49,6 +49,7 @@ class Update extends Action
|
||||
)
|
||||
],
|
||||
))
|
||||
// TODO: Split into more toggles, simiplar to membership privacy policy
|
||||
->param('enabled', null, new Boolean(), 'Toggle password personal data policy. Set to true if you want to block passwords including user\'s personal data, or false to allow it. When changing this policy, existing passwords remain valid.')
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\Policies\SessionAlert;
|
||||
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Boolean;
|
||||
|
||||
class Update extends Action
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'updateProjectSessionAlertPolicy';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/project/policies/session-alert')
|
||||
->httpAlias('/v1/projects/:projectId/auth/session-alerts')
|
||||
->desc('Update session alert policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('event', 'policies.session-alert.update')
|
||||
->label('audits.event', 'policies.session-alert.update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: 'policies',
|
||||
name: 'updateSessionAlertPolicy',
|
||||
description: <<<EOT
|
||||
Updating this policy allows you to control if email alert is sent upon session creation. When enabled, and user signs into their account, they will be sent an email notification. There is an exception, the first session after a new sign up does not trigger an alert, even if the policy is enabled.
|
||||
EOT,
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_PROJECT,
|
||||
)
|
||||
],
|
||||
))
|
||||
->param('enabled', null, new Boolean(), 'Toggle session alert policy. Set to true if you want users to receive email notifications when a sessions are created for their users, or false to not send email alerts.')
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(
|
||||
bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
Authorization $authorization,
|
||||
): void {
|
||||
$auths = $project->getAttribute('auths', []);
|
||||
$auths['sessionAlerts'] = $enabled;
|
||||
|
||||
$updates = new Document([
|
||||
'auths' => $auths,
|
||||
]);
|
||||
|
||||
$project = $authorization->skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $updates));
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
}
|
||||
}
|
||||
@@ -120,6 +120,8 @@ class Create extends Action
|
||||
'membershipsUserName' => false,
|
||||
'membershipsUserEmail' => false,
|
||||
'membershipsMfa' => false,
|
||||
'membershipsUserId' => false,
|
||||
'membershipsUserPhone' => false,
|
||||
'invalidateSessions' => true
|
||||
];
|
||||
|
||||
|
||||
@@ -71,9 +71,11 @@ class Get extends Action
|
||||
}
|
||||
|
||||
$membershipsPrivacy = [
|
||||
'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? true,
|
||||
'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? true,
|
||||
'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? true,
|
||||
'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? false,
|
||||
'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? false,
|
||||
'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? false,
|
||||
'userId' => $project->getAttribute('auths', [])['membershipsUserId'] ?? false,
|
||||
'userPhone' => $project->getAttribute('auths', [])['membershipsUserPhone'] ?? false,
|
||||
];
|
||||
|
||||
$roles = $authorization->getRoles();
|
||||
@@ -113,6 +115,14 @@ class Get extends Action
|
||||
$membership->setAttribute('userEmail', $memberUser->getAttribute('email'));
|
||||
}
|
||||
|
||||
if ($membershipsPrivacy['userId']) {
|
||||
$membership->setAttribute('userId', $memberUser->getId());
|
||||
}
|
||||
|
||||
if ($membershipsPrivacy['userPhone']) {
|
||||
$membership->setAttribute('userPhone', $memberUser->getAttribute('phone'));
|
||||
}
|
||||
|
||||
$membership->setAttribute('teamName', $team->getAttribute('name'));
|
||||
|
||||
$response->dynamic($membership, Response::MODEL_MEMBERSHIP);
|
||||
|
||||
@@ -124,9 +124,11 @@ class XList extends Action
|
||||
$memberships = array_filter($memberships, fn (Document $membership) => !empty($membership->getAttribute('userId')));
|
||||
|
||||
$membershipsPrivacy = [
|
||||
'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? true,
|
||||
'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? true,
|
||||
'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? true,
|
||||
'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? false,
|
||||
'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? false,
|
||||
'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? false,
|
||||
'userId' => $project->getAttribute('auths', [])['membershipsUserId'] ?? false,
|
||||
'userPhone' => $project->getAttribute('auths', [])['membershipsUserPhone'] ?? false,
|
||||
];
|
||||
|
||||
$roles = $authorization->getRoles();
|
||||
@@ -167,6 +169,14 @@ class XList extends Action
|
||||
$membership->setAttribute('userEmail', $memberUser->getAttribute('email'));
|
||||
}
|
||||
|
||||
if ($membershipsPrivacy['userId']) {
|
||||
$membership->setAttribute('userId', $memberUser->getId());
|
||||
}
|
||||
|
||||
if ($membershipsPrivacy['userPhone']) {
|
||||
$membership->setAttribute('userPhone', $memberUser->getAttribute('phone'));
|
||||
}
|
||||
|
||||
$membership->setAttribute('teamName', $team->getAttribute('name'));
|
||||
|
||||
return $membership;
|
||||
|
||||
@@ -46,6 +46,12 @@ class Membership extends Model
|
||||
'default' => '',
|
||||
'example' => 'john@appwrite.io',
|
||||
])
|
||||
->addRule('userPhone', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'User phone number. Hide this attribute by toggling membership privacy in the Console.',
|
||||
'default' => '',
|
||||
'example' => '+1 555 555 5555',
|
||||
])
|
||||
->addRule('teamId', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Team ID.',
|
||||
|
||||
@@ -181,6 +181,18 @@ class Project extends Model
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authMembershipsUserId', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to show user IDs in the teams membership response.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authMembershipsUserPhone', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not to show user phone numbers in the teams membership response.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('authInvalidateSessions', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether or not all existing sessions should be invalidated on password change',
|
||||
@@ -475,6 +487,8 @@ class Project extends Model
|
||||
$document->setAttribute('authMembershipsUserName', $authValues['membershipsUserName'] ?? true);
|
||||
$document->setAttribute('authMembershipsUserEmail', $authValues['membershipsUserEmail'] ?? true);
|
||||
$document->setAttribute('authMembershipsMfa', $authValues['membershipsMfa'] ?? true);
|
||||
$document->setAttribute('authMembershipsUserId', $authValues['membershipsUserId'] ?? true);
|
||||
$document->setAttribute('authMembershipsUserPhone', $authValues['membershipsUserPhone'] ?? true);
|
||||
$document->setAttribute('authInvalidateSessions', $authValues['invalidateSessions'] ?? false);
|
||||
|
||||
foreach ($auth as $method) {
|
||||
|
||||
Reference in New Issue
Block a user