Better detection of server and console modes
This commit is contained in:
parent
3828a8deae
commit
9169bdeeec
3 changed files with 54 additions and 16 deletions
|
@ -33,14 +33,16 @@ App::post('/v1/teams')
|
|||
->label('sdk.response.model', Response::MODEL_TEAM)
|
||||
->param('name', null, new Text(128), 'Team name. Max length: 128 chars.')
|
||||
->param('roles', ['owner'], new ArrayList(new Key()), 'Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.', true)
|
||||
->action(function ($name, $roles, $response, $user, $projectDB, $mode) {
|
||||
->action(function ($name, $roles, $response, $user, $projectDB) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var bool $mode */
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
$isPreviliggedUser = Auth::isPreviliggedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
|
||||
$team = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_TEAMS,
|
||||
'$permissions' => [
|
||||
|
@ -48,7 +50,7 @@ App::post('/v1/teams')
|
|||
'write' => ['team:{self}/owner'],
|
||||
],
|
||||
'name' => $name,
|
||||
'sum' => ($mode !== APP_MODE_ADMIN && $user->getId()) ? 1 : 0,
|
||||
'sum' => ($isPreviliggedUser || $isAppUser) ? 0 : 1,
|
||||
'dateCreated' => \time(),
|
||||
]);
|
||||
|
||||
|
@ -58,7 +60,7 @@ App::post('/v1/teams')
|
|||
throw new Exception('Failed saving team to DB', 500);
|
||||
}
|
||||
|
||||
if ($mode !== APP_MODE_ADMIN && $user->getId()) { // Don't add user on server mode
|
||||
if (!$isPreviliggedUser && !$isAppUser) { // Don't add user on server mode
|
||||
$membership = new Document([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
'$permissions' => [
|
||||
|
@ -88,7 +90,7 @@ App::post('/v1/teams')
|
|||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($team, Response::MODEL_TEAM)
|
||||
;
|
||||
}, ['response', 'user', 'projectDB', 'mode']);
|
||||
}, ['response', 'user', 'projectDB']);
|
||||
|
||||
App::get('/v1/teams')
|
||||
->desc('List Teams')
|
||||
|
@ -246,14 +248,16 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
->param('name', '', new Text(128), 'New team member name. Max length: 128 chars.', true)
|
||||
->param('roles', [], new ArrayList(new Key()), 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.')
|
||||
->param('url', '', function ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['clients']) // TODO add our own built-in confirm page
|
||||
->action(function ($teamId, $email, $name, $roles, $url, $response, $project, $user, $projectDB, $locale, $audits, $mails, $mode) {
|
||||
->action(function ($teamId, $email, $name, $roles, $url, $response, $project, $user, $projectDB, $locale, $audits, $mails) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $mails */
|
||||
/** @var bool $mode */
|
||||
|
||||
$isPreviliggedUser = Auth::isPreviliggedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
|
||||
$name = (empty($name)) ? $email : $name;
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
|
@ -323,7 +327,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
}
|
||||
}
|
||||
|
||||
if (!$isOwner && APP_MODE_ADMIN !== $mode && $user->getId()) { // Not owner, not admin, not app (server)
|
||||
if (!$isOwner && !$isPreviliggedUser && !$isAppUser) { // Not owner, not admin, not app (server)
|
||||
throw new Exception('User is not allowed to send invitations for this team', 401);
|
||||
}
|
||||
|
||||
|
@ -339,12 +343,12 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
'teamId' => $team->getId(),
|
||||
'roles' => $roles,
|
||||
'invited' => \time(),
|
||||
'joined' => (APP_MODE_ADMIN === $mode || !$user->getId()) ? \time() : 0,
|
||||
'confirm' => (APP_MODE_ADMIN === $mode || !$user->getId()),
|
||||
'joined' => ($isPreviliggedUser || $isAppUser) ? \time() : 0,
|
||||
'confirm' => ($isPreviliggedUser || $isAppUser),
|
||||
'secret' => Auth::hash($secret),
|
||||
]);
|
||||
|
||||
if (APP_MODE_ADMIN === $mode || !$user->getId()) { // Allow admin to create membership
|
||||
if ($isPreviliggedUser || $isAppUser) { // Allow admin to create membership
|
||||
Authorization::disable();
|
||||
$membership = $projectDB->createDocument($membership->getArrayCopy());
|
||||
|
||||
|
@ -395,7 +399,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
->setParam('{{text-cta}}', '#ffffff')
|
||||
;
|
||||
|
||||
if (APP_MODE_ADMIN !== $mode && $user->getId()) { // No need in comfirmation when in admin or app mode
|
||||
if (!$isPreviliggedUser && !$isAppUser) { // No need in comfirmation when in admin or app mode
|
||||
$mails
|
||||
->setParam('event', 'teams.membership.create')
|
||||
->setParam('from', ($project->getId() === 'console') ? '' : \sprintf($locale->getText('account.emails.team'), $project->getAttribute('name')))
|
||||
|
@ -420,7 +424,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
'name' => $name,
|
||||
])), Response::MODEL_MEMBERSHIP)
|
||||
;
|
||||
}, ['response', 'project', 'user', 'projectDB', 'locale', 'audits', 'mails', 'mode']);
|
||||
}, ['response', 'project', 'user', 'projectDB', 'locale', 'audits', 'mails']);
|
||||
|
||||
App::get('/v1/teams/:teamId/memberships')
|
||||
->desc('Get Team Memberships')
|
||||
|
|
|
@ -382,8 +382,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
|
|||
|
||||
$session = Auth::decodeSession(
|
||||
$request->getCookie(Auth::$cookieName, // Get sessions
|
||||
$request->getCookie(Auth::$cookieName.'_legacy', // Get fallback session from old clients (no SameSite support)
|
||||
$request->getHeader('x-appwrite-key', '')))); // Get API Key
|
||||
$request->getCookie(Auth::$cookieName.'_legacy', '')));// Get fallback session from old clients (no SameSite support)
|
||||
|
||||
// Get fallback session from clients who block 3rd-party cookies
|
||||
$response->addHeader('X-Debug-Fallback', 'false');
|
||||
|
|
|
@ -23,7 +23,6 @@ class Auth
|
|||
const USER_ROLE_OWNER = 4;
|
||||
const USER_ROLE_APP = 5;
|
||||
const USER_ROLE_SYSTEM = 6;
|
||||
const USER_ROLE_ALL = '*';
|
||||
|
||||
/**
|
||||
* Token Types.
|
||||
|
@ -206,4 +205,40 @@ class Auth
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Previligged User?
|
||||
*
|
||||
* @param array $roles
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isPreviliggedUser(array $roles): bool
|
||||
{
|
||||
if(
|
||||
array_key_exists('role:'.self::USER_ROLE_OWNER, $roles) ||
|
||||
array_key_exists('role:'.self::USER_ROLE_DEVELOPER, $roles) ||
|
||||
array_key_exists('role:'.self::USER_ROLE_ADMIN, $roles)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is App User?
|
||||
*
|
||||
* @param array $roles
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isAppUser(array $roles): bool
|
||||
{
|
||||
if(array_key_exists('role:'.self::USER_ROLE_APP, $roles)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue