mirror of https://github.com/sualko/cloud_bbb
Compare commits
19 Commits
f1033dceea
...
66150997b1
Author | SHA1 | Date |
---|---|---|
Jonas | 66150997b1 | |
Thibaut | e5bfcc8ec8 | |
Thibaut | dede2b2857 | |
Thibaut | 3c45a93ece | |
Nextcloud bot | 31bc8aeea1 | |
Thibaut | ad65b6803f | |
Sebastien Marinier | a00708ffa3 | |
Sebastien Marinier | 95f9425a80 | |
Sebastien Marinier | 1b15353dcb | |
Sebastien Marinier | 79518b9bac | |
Sebastien Marinier | ab80d613e7 | |
Sebastien Marinier | da0cc79b9e | |
Sebastien Marinier | 71fe272888 | |
Sebastien Marinier | 323e9df9f4 | |
Thibaut | 7233d21a85 | |
Sebastien Marinier | a9082d3a46 | |
Nextcloud bot | b7a864c658 | |
Nextcloud bot | 2f288e34c0 | |
brtbr | 093e286e0f |
|
@ -11,13 +11,23 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.4', '8']
|
||||
nextcloud-versions: ['stable25', 'stable26', 'stable27']
|
||||
php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3']
|
||||
nextcloud-versions: ['stable25', 'stable26', 'stable27', 'stable28']
|
||||
exclude:
|
||||
- php-versions: '7.4'
|
||||
nextcloud-versions: 'stable26'
|
||||
- php-versions: '7.4'
|
||||
nextcloud-versions: 'stable27'
|
||||
- php-versions: '7.4'
|
||||
nextcloud-versions: 'stable28'
|
||||
- php-versions: '8.2'
|
||||
nextcloud-versions: 'stable25'
|
||||
- php-versions: '8.3'
|
||||
nextcloud-versions: 'stable25'
|
||||
- php-versions: '8.3'
|
||||
nextcloud-versions: 'stable26'
|
||||
- php-versions: '8.3'
|
||||
nextcloud-versions: 'stable27'
|
||||
name: php${{ matrix.php-versions }} on ${{ matrix.nextcloud-versions }} unit tests
|
||||
env:
|
||||
CI: true
|
||||
|
|
|
@ -72,7 +72,7 @@ OC.L10N.register(
|
|||
"This message is shown to all users in the chat area after they joined." : "Ce message est affiché à tous les utilisateurs de l’espace de discussion après qu’ils l’ont rejoint.",
|
||||
"Sets a limit on the number of participants for this room. Zero means there is no limit." : "Fixe une limite au nombre de participants pour cette salle. Zéro signifie qu’il n’y a pas de limite.",
|
||||
"If enabled, the moderator is able to start the recording." : "Si activé, le modérateur peut lancer l'enregistrement.",
|
||||
"Explanation of the different concepts that constitute access options :<br>- Public: Anyone who has the link can join.- <br>Internal: Only Nextcloud users can join.- <br>Password: Only guests who have the password can join..- <br>Waiting room: A moderator must accept each guest before they can join.- <br>Restricted : Only selected users and groups can access this room." : "Explication des différents concepts qui constituent les options d’accès :<br>- Public : Toute personne possédant le lien peut rejoindre la conversation.- <br>Interne : Seuls les utilisateurs Nextcloud peuvent rejoindre la conversation.- <br>Mot de passe : Seuls les invités possédant le mot de passe peuvent rejoindre la conversation..- <br>Salle d’attente : Un modérateur doit accepter chaque invité avant qu’il ne puisse rejoindre la conversation.- <br>Restreint : Seuls les utilisateurs et groupes sélectionnés peuvent accéder à cette conversation.",
|
||||
"Explanation of the different concepts that constitute access options :<br>- Public: Anyone who has the link can join.- <br>Internal: Only Nextcloud users can join.- <br>Password: Only guests who have the password can join..- <br>Waiting room: A moderator must accept each guest before they can join.- <br>Restricted : Only selected users and groups can access this room." : "Explication des différents concepts qui constituent les options d’accès :<br>- Public : Toute personne possédant le lien peut rejoindre la conversation.- <br>Interne : Seuls les utilisateurs Nextcloud peuvent rejoindre la conversation.- <br>Mot de passe : Seuls les invités possédant le mot de passe peuvent rejoindre la conversation..- <br>Salle d’attente : Un modérateur doit accepter chaque invité avant qu’il ne puisse rejoindre la conversation.- <br>Restreint : Seuls les utilisateurs et groupes sélectionnés peuvent accéder à cette conversation. ",
|
||||
"A moderator is able to manage all participants in a meeting including kicking, muting or selecting a presenter. Users with the role moderator are also able to close a meeting or change the default settings." : "Un modérateur est en mesure de gérer tous les participants d'une réunion, incluant leur éjection de la salle, leur mise en sourdine ou la désignation d'un présentateur. Les utilisateurs ayant le rôle de modérateur peuvent également mettre fin à une réunion ou modifier les paramètres par défaut.",
|
||||
"If enabled, normal users have to wait until a moderator is in the room." : "Si activé, les utilisateurs devront attendre qu'un modérateur rejoigne la salle.",
|
||||
"If enabled, a moderator URL is generated which allows access with moderator permission." : "Si activé, une URL de modérateur est générée pour permettre l'accès avec les droits de modération.",
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"This message is shown to all users in the chat area after they joined." : "Ce message est affiché à tous les utilisateurs de l’espace de discussion après qu’ils l’ont rejoint.",
|
||||
"Sets a limit on the number of participants for this room. Zero means there is no limit." : "Fixe une limite au nombre de participants pour cette salle. Zéro signifie qu’il n’y a pas de limite.",
|
||||
"If enabled, the moderator is able to start the recording." : "Si activé, le modérateur peut lancer l'enregistrement.",
|
||||
"Explanation of the different concepts that constitute access options :<br>- Public: Anyone who has the link can join.- <br>Internal: Only Nextcloud users can join.- <br>Password: Only guests who have the password can join..- <br>Waiting room: A moderator must accept each guest before they can join.- <br>Restricted : Only selected users and groups can access this room." : "Explication des différents concepts qui constituent les options d’accès :<br>- Public : Toute personne possédant le lien peut rejoindre la conversation.- <br>Interne : Seuls les utilisateurs Nextcloud peuvent rejoindre la conversation.- <br>Mot de passe : Seuls les invités possédant le mot de passe peuvent rejoindre la conversation..- <br>Salle d’attente : Un modérateur doit accepter chaque invité avant qu’il ne puisse rejoindre la conversation.- <br>Restreint : Seuls les utilisateurs et groupes sélectionnés peuvent accéder à cette conversation.",
|
||||
"Explanation of the different concepts that constitute access options :<br>- Public: Anyone who has the link can join.- <br>Internal: Only Nextcloud users can join.- <br>Password: Only guests who have the password can join..- <br>Waiting room: A moderator must accept each guest before they can join.- <br>Restricted : Only selected users and groups can access this room." : "Explication des différents concepts qui constituent les options d’accès :<br>- Public : Toute personne possédant le lien peut rejoindre la conversation.- <br>Interne : Seuls les utilisateurs Nextcloud peuvent rejoindre la conversation.- <br>Mot de passe : Seuls les invités possédant le mot de passe peuvent rejoindre la conversation..- <br>Salle d’attente : Un modérateur doit accepter chaque invité avant qu’il ne puisse rejoindre la conversation.- <br>Restreint : Seuls les utilisateurs et groupes sélectionnés peuvent accéder à cette conversation. ",
|
||||
"A moderator is able to manage all participants in a meeting including kicking, muting or selecting a presenter. Users with the role moderator are also able to close a meeting or change the default settings." : "Un modérateur est en mesure de gérer tous les participants d'une réunion, incluant leur éjection de la salle, leur mise en sourdine ou la désignation d'un présentateur. Les utilisateurs ayant le rôle de modérateur peuvent également mettre fin à une réunion ou modifier les paramètres par défaut.",
|
||||
"If enabled, normal users have to wait until a moderator is in the room." : "Si activé, les utilisateurs devront attendre qu'un modérateur rejoigne la salle.",
|
||||
"If enabled, a moderator URL is generated which allows access with moderator permission." : "Si activé, une URL de modérateur est générée pour permettre l'accès avec les droits de modération.",
|
||||
|
|
|
@ -58,6 +58,7 @@ OC.L10N.register(
|
|||
"No matches" : "Nessuna corrispondenza",
|
||||
"admin" : "amministratore",
|
||||
"moderator" : "moderatore",
|
||||
"user" : "utente",
|
||||
"Name" : "Nome",
|
||||
"Access" : "Accesso",
|
||||
"Max" : "Massimo",
|
||||
|
@ -71,6 +72,7 @@ OC.L10N.register(
|
|||
"This message is shown to all users in the chat area after they joined." : "Questo messaggio è mostrato a tutti gli utenti nell'area di chat dopo il loro ingresso.",
|
||||
"Sets a limit on the number of participants for this room. Zero means there is no limit." : "Imposta un limite sul numero di partecipanti per questa stanza. Zero significa che non ci sono limiti.",
|
||||
"If enabled, the moderator is able to start the recording." : "Se abilitata, il moderatore è in grado di avviare la registrazione.",
|
||||
"Explanation of the different concepts that constitute access options :<br>- Public: Anyone who has the link can join.- <br>Internal: Only Nextcloud users can join.- <br>Password: Only guests who have the password can join..- <br>Waiting room: A moderator must accept each guest before they can join.- <br>Restricted : Only selected users and groups can access this room." : "Spiegazione dei diversi concetti che costituiscono l'accesso :<br>- Pubblico: chiunque abbia il link può partecipare.-<br>Interno: possono partecipare solo gli utenti Nextcloud.-<br>Password: possono partecipare solo gli ospiti che hanno la password..- <br>Sala d'attesa: un moderatore deve accettare ogni ospite prima che possa partecipare.- <br>Limitato: solo gli utenti e i gruppi selezionati possono accedere a questa stanza.",
|
||||
"A moderator is able to manage all participants in a meeting including kicking, muting or selecting a presenter. Users with the role moderator are also able to close a meeting or change the default settings." : "Un moderatore è in grado di gestire tutti i partecipanti a una riunione, inclusa l'espulsione, il silenziamento o la selezione di un relatore. Gli utenti con il ruolo di moderatore possono anche chiudere una riunione o modificare le impostazioni predefinite.",
|
||||
"If enabled, normal users have to wait until a moderator is in the room." : "Se abilitata, gli utenti normali devono attendere fino a quando un moderatore è nella stanza.",
|
||||
"If enabled, a moderator URL is generated which allows access with moderator permission." : "Se abilitata, viene generato un URL moderatore che consente l'accesso con l'autorizzazione del moderatore.",
|
||||
|
@ -114,7 +116,10 @@ OC.L10N.register(
|
|||
"Delete?" : "Vuoi eliminare?",
|
||||
"Could not delete record" : "Impossibile eliminare il record",
|
||||
"Server error" : "Errore del server",
|
||||
"Could not modify publishing state" : "Impossibile modificare lo stato di pubblicazione",
|
||||
"Open room" : "Stanza aperta",
|
||||
"Start" : "Avvia",
|
||||
"Clone room" : "Clona stanza",
|
||||
"Loading" : "Caricamento",
|
||||
"You are not allowed to change this option, because this room is shared with you." : "Non ti è consentito modificare questa opzione, poiché questa stanza è condivisa con te.",
|
||||
"Max. rooms" : "Num. massimo stanze",
|
||||
|
@ -130,8 +135,12 @@ OC.L10N.register(
|
|||
"URL has to start with HTTPS" : "L'URL deve iniziare con HTTPS",
|
||||
"URL has to contain the {token} placeholder" : "L'URL deve contenere il segnaposto {token}",
|
||||
"URL has to start with https:// and contain {token}. Additionally the {user} placeholder can be used." : "L'URL deve iniziare con https: // e contenere {token}. Inoltre è possibile utilizzare il segnaposto {user}.",
|
||||
"The file \"{filename}\" was uploaded to your room." : "Il file \"{filename}\" è stato caricato nella tua stanza.",
|
||||
"The file \"{filename}\" could not be uploaded to your room." : "Il file \"{filename}\" non è stato possibile caricarlo nella tua stanza.",
|
||||
"The file \"{filename}\" could not be uploaded to your room. Maybe your BigBlueButton server does not support this action." : "Il file \"{filename}\" non può essere caricato nella tua stanza. Forse il tuo server BigBlueButton non supporta questa azione.",
|
||||
"Send file to BBB" : "Invia file a BBB",
|
||||
"Send to" : "Invia a",
|
||||
"Start with" : "Inizia con",
|
||||
"Please select the room in which you like to use the file \"{filename}\"." : "Seleziona la stanza in cui vorresti usare il file \"{filename}\".",
|
||||
"No rooms available!" : "Nessuna stanza disponibile",
|
||||
"Send to BBB" : "Invia a BBB",
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
"No matches" : "Nessuna corrispondenza",
|
||||
"admin" : "amministratore",
|
||||
"moderator" : "moderatore",
|
||||
"user" : "utente",
|
||||
"Name" : "Nome",
|
||||
"Access" : "Accesso",
|
||||
"Max" : "Massimo",
|
||||
|
@ -69,6 +70,7 @@
|
|||
"This message is shown to all users in the chat area after they joined." : "Questo messaggio è mostrato a tutti gli utenti nell'area di chat dopo il loro ingresso.",
|
||||
"Sets a limit on the number of participants for this room. Zero means there is no limit." : "Imposta un limite sul numero di partecipanti per questa stanza. Zero significa che non ci sono limiti.",
|
||||
"If enabled, the moderator is able to start the recording." : "Se abilitata, il moderatore è in grado di avviare la registrazione.",
|
||||
"Explanation of the different concepts that constitute access options :<br>- Public: Anyone who has the link can join.- <br>Internal: Only Nextcloud users can join.- <br>Password: Only guests who have the password can join..- <br>Waiting room: A moderator must accept each guest before they can join.- <br>Restricted : Only selected users and groups can access this room." : "Spiegazione dei diversi concetti che costituiscono l'accesso :<br>- Pubblico: chiunque abbia il link può partecipare.-<br>Interno: possono partecipare solo gli utenti Nextcloud.-<br>Password: possono partecipare solo gli ospiti che hanno la password..- <br>Sala d'attesa: un moderatore deve accettare ogni ospite prima che possa partecipare.- <br>Limitato: solo gli utenti e i gruppi selezionati possono accedere a questa stanza.",
|
||||
"A moderator is able to manage all participants in a meeting including kicking, muting or selecting a presenter. Users with the role moderator are also able to close a meeting or change the default settings." : "Un moderatore è in grado di gestire tutti i partecipanti a una riunione, inclusa l'espulsione, il silenziamento o la selezione di un relatore. Gli utenti con il ruolo di moderatore possono anche chiudere una riunione o modificare le impostazioni predefinite.",
|
||||
"If enabled, normal users have to wait until a moderator is in the room." : "Se abilitata, gli utenti normali devono attendere fino a quando un moderatore è nella stanza.",
|
||||
"If enabled, a moderator URL is generated which allows access with moderator permission." : "Se abilitata, viene generato un URL moderatore che consente l'accesso con l'autorizzazione del moderatore.",
|
||||
|
@ -112,7 +114,10 @@
|
|||
"Delete?" : "Vuoi eliminare?",
|
||||
"Could not delete record" : "Impossibile eliminare il record",
|
||||
"Server error" : "Errore del server",
|
||||
"Could not modify publishing state" : "Impossibile modificare lo stato di pubblicazione",
|
||||
"Open room" : "Stanza aperta",
|
||||
"Start" : "Avvia",
|
||||
"Clone room" : "Clona stanza",
|
||||
"Loading" : "Caricamento",
|
||||
"You are not allowed to change this option, because this room is shared with you." : "Non ti è consentito modificare questa opzione, poiché questa stanza è condivisa con te.",
|
||||
"Max. rooms" : "Num. massimo stanze",
|
||||
|
@ -128,8 +133,12 @@
|
|||
"URL has to start with HTTPS" : "L'URL deve iniziare con HTTPS",
|
||||
"URL has to contain the {token} placeholder" : "L'URL deve contenere il segnaposto {token}",
|
||||
"URL has to start with https:// and contain {token}. Additionally the {user} placeholder can be used." : "L'URL deve iniziare con https: // e contenere {token}. Inoltre è possibile utilizzare il segnaposto {user}.",
|
||||
"The file \"{filename}\" was uploaded to your room." : "Il file \"{filename}\" è stato caricato nella tua stanza.",
|
||||
"The file \"{filename}\" could not be uploaded to your room." : "Il file \"{filename}\" non è stato possibile caricarlo nella tua stanza.",
|
||||
"The file \"{filename}\" could not be uploaded to your room. Maybe your BigBlueButton server does not support this action." : "Il file \"{filename}\" non può essere caricato nella tua stanza. Forse il tuo server BigBlueButton non supporta questa azione.",
|
||||
"Send file to BBB" : "Invia file a BBB",
|
||||
"Send to" : "Invia a",
|
||||
"Start with" : "Inizia con",
|
||||
"Please select the room in which you like to use the file \"{filename}\"." : "Seleziona la stanza in cui vorresti usare il file \"{filename}\".",
|
||||
"No rooms available!" : "Nessuna stanza disponibile",
|
||||
"Send to BBB" : "Invia a BBB",
|
||||
|
|
|
@ -48,7 +48,7 @@ OC.L10N.register(
|
|||
"Display name" : "显示名称",
|
||||
"Password" : "密码",
|
||||
"Join" : "加入",
|
||||
"Have an account? Log in." : "有一个账户吗?登录。",
|
||||
"Have an account? Log in." : "有一个账号?登录。",
|
||||
"Hello %s" : "%s 你好",
|
||||
"Name, group …" : "名称、群组 ...",
|
||||
"Group" : "群组",
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
"Display name" : "显示名称",
|
||||
"Password" : "密码",
|
||||
"Join" : "加入",
|
||||
"Have an account? Log in." : "有一个账户吗?登录。",
|
||||
"Have an account? Log in." : "有一个账号?登录。",
|
||||
"Hello %s" : "%s 你好",
|
||||
"Name, group …" : "名称、群组 ...",
|
||||
"Group" : "群组",
|
||||
|
|
|
@ -56,6 +56,8 @@ class Application extends App implements IBootstrap {
|
|||
|
||||
$context->registerMiddleware(JoinMiddleware::class);
|
||||
$context->registerMiddleware(HookMiddleware::class);
|
||||
|
||||
$context->registerCapability(Capabilities::class);
|
||||
}
|
||||
|
||||
public function boot(IBootContext $context): void {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\BigBlueButton\AppInfo;
|
||||
|
||||
use OCA\BigBlueButton\Permission;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\Capabilities\ICapability;
|
||||
use OCP\IUserSession;
|
||||
|
||||
class Capabilities implements ICapability {
|
||||
public function __construct(private IUserSession $userSession, private IAppManager $appManager, private Permission $permission) {
|
||||
}
|
||||
|
||||
public function getCapabilities(): array {
|
||||
$user = $this->userSession->getUser();
|
||||
if (!$user) {
|
||||
return [];
|
||||
}
|
||||
$restriction = $this->permission->getRestriction($user->getUID());
|
||||
$capabilities = array_filter($restriction->jsonSerialize(), function ($key) {
|
||||
return in_array($key, ['maxRooms', 'maxParticipants', 'allowRecording']);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
return [
|
||||
Application::ID => array_merge([
|
||||
'appVersion' => $this->appManager->getAppVersion(Application::ID),
|
||||
'isAllowedToCreateRoom' => $this->permission->isAllowedToCreateRoom($user->getUID()),
|
||||
], $capabilities)
|
||||
];
|
||||
}
|
||||
}
|
|
@ -118,7 +118,8 @@ class API {
|
|||
$joinMeetingParams->addUserData('bbb_skip_video_preview_on_first_join', !$room->getMediaCheck()); // 2.3
|
||||
|
||||
if ($room->getCleanLayout()) {
|
||||
$joinMeetingParams->addUserData('bbb_auto_swap_layout', true);
|
||||
$joinMeetingParams->addUserData('bbb_auto_swap_layout', true); // 2.5 and below // ToDo: remove in the future
|
||||
$joinMeetingParams->addUserData('bbb_hide_presentation_on_join', true); // 2.6 and up
|
||||
$joinMeetingParams->addUserData('bbb_show_participants_on_login', false);
|
||||
$joinMeetingParams->addUserData('bbb_show_public_chat_on_login', false);
|
||||
}
|
||||
|
|
|
@ -16,11 +16,13 @@ use OCP\AppFramework\Db\Entity;
|
|||
* @method void setMaxRooms(int $number)
|
||||
* @method void setMaxParticipants(int $number)
|
||||
* @method void setAllowRecording(bool $allow)
|
||||
* @method void setGroupName(string $groupName)
|
||||
*/
|
||||
class Restriction extends Entity implements JsonSerializable {
|
||||
public const ALL_ID = '';
|
||||
|
||||
protected $groupId;
|
||||
protected $groupName;
|
||||
protected $maxRooms = -1;
|
||||
protected $roomTypes = '[]';
|
||||
protected $maxParticipants = -1;
|
||||
|
@ -32,10 +34,15 @@ class Restriction extends Entity implements JsonSerializable {
|
|||
$this->addType('allowRecording', 'boolean');
|
||||
}
|
||||
|
||||
public function setGroupName(string $groupName) {
|
||||
$this->groupName = $groupName;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'groupId' => $this->groupId,
|
||||
'groupName' => $this->groupName,
|
||||
'maxRooms' => (int) $this->maxRooms,
|
||||
'roomTypes' => \json_decode($this->roomTypes),
|
||||
'maxParticipants' => (int) $this->maxParticipants,
|
||||
|
|
|
@ -19,8 +19,9 @@ class RestrictionMapper extends QBMapper {
|
|||
public function find(int $id): Restriction {
|
||||
/* @var $qb IQueryBuilder */
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from($this->tableName)
|
||||
$qb->select('r.*', 'g.displayname as groupName')
|
||||
->from($this->tableName, 'r')
|
||||
->leftJoin('r', 'groups', 'g', $qb->expr()->eq('r.group_id', 'g.gid'))
|
||||
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
|
||||
|
||||
return $this->findEntity($qb);
|
||||
|
@ -33,8 +34,9 @@ class RestrictionMapper extends QBMapper {
|
|||
public function findByGroupId(string $groupId): Restriction {
|
||||
/* @var $qb IQueryBuilder */
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from($this->tableName)
|
||||
$qb->select('r.*', 'g.displayname as groupName')
|
||||
->from($this->tableName, 'r')
|
||||
->leftJoin('r', 'groups', 'g', $qb->expr()->eq('r.group_id', 'g.gid'))
|
||||
->where($qb->expr()->eq('group_id', $qb->createNamedParameter($groupId)));
|
||||
|
||||
return $this->findEntity($qb);
|
||||
|
@ -46,8 +48,9 @@ class RestrictionMapper extends QBMapper {
|
|||
public function findByGroupIds(array $groupIds): array {
|
||||
/* @var $qb IQueryBuilder */
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from($this->tableName)
|
||||
$qb->select('r.*', 'g.displayname as groupName')
|
||||
->from($this->tableName, 'r')
|
||||
->leftJoin('r', 'groups', 'g', $qb->expr()->eq('r.group_id', 'g.gid'))
|
||||
->where($qb->expr()->in('group_id', $qb->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)));
|
||||
|
||||
/** @var array<Restriction> */
|
||||
|
@ -60,8 +63,9 @@ class RestrictionMapper extends QBMapper {
|
|||
public function findAll(): array {
|
||||
/* @var $qb IQueryBuilder */
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from($this->tableName);
|
||||
$qb->select('r.*', 'g.displayname as groupName')
|
||||
->from($this->tableName, 'r')
|
||||
->leftJoin('r', 'groups', 'g', $qb->expr()->eq('r.group_id', 'g.gid'));
|
||||
|
||||
/** @var array<Restriction> */
|
||||
return $this->findEntities($qb);
|
||||
|
|
|
@ -55,10 +55,13 @@ class Permission {
|
|||
}
|
||||
|
||||
public function isAllowedToCreateRoom(string $uid): bool {
|
||||
$numberOfCreatedRooms = count($this->roomService->findAll($uid, [], []));
|
||||
$restriction = $this->getRestriction($uid);
|
||||
if ($restriction->getMaxRooms() < 0) {
|
||||
return true;
|
||||
}
|
||||
$numberOfCreatedRooms = count($this->roomService->findByUserId($uid));
|
||||
|
||||
return $restriction->getMaxRooms() < 0 || $restriction->getMaxRooms() > $numberOfCreatedRooms;
|
||||
return $restriction->getMaxRooms() > $numberOfCreatedRooms;
|
||||
}
|
||||
|
||||
public function isUser(Room $room, ?string $uid): bool {
|
||||
|
|
|
@ -9,13 +9,18 @@ use OCA\BigBlueButton\Db\RestrictionMapper;
|
|||
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\IGroupManager;
|
||||
|
||||
class RestrictionService {
|
||||
/** @var RestrictionMapper */
|
||||
private $mapper;
|
||||
|
||||
public function __construct(RestrictionMapper $mapper) {
|
||||
/** @var IGroupManager */
|
||||
private $groupManager;
|
||||
|
||||
public function __construct(RestrictionMapper $mapper, IGroupManager $groupManager) {
|
||||
$this->mapper = $mapper;
|
||||
$this->groupManager = $groupManager;
|
||||
}
|
||||
|
||||
public function findAll(): array {
|
||||
|
@ -78,6 +83,10 @@ class RestrictionService {
|
|||
$restriction = new Restriction();
|
||||
|
||||
$restriction->setGroupId($groupId);
|
||||
$group = $this->groupManager->get($groupId);
|
||||
if ($group) {
|
||||
$restriction->setGroupName($group->getDisplayName());
|
||||
}
|
||||
|
||||
return $this->mapper->insert($restriction);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
"stylelint-config-recommended-scss": "^5.0.2",
|
||||
"stylelint-scss": "^4.2.0",
|
||||
"ts-loader": "^9.2.8",
|
||||
"typescript": "^4.0.2",
|
||||
"typescript": "^4.9.3",
|
||||
"url-loader": "^4.0.0",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^4.9.2",
|
||||
|
|
|
@ -83,7 +83,8 @@ class PermissionTest extends TestCase {
|
|||
|
||||
$this->roomService
|
||||
->expects($this->once())
|
||||
->method('findAll')
|
||||
->method('findByUserId')
|
||||
->with('foobar')
|
||||
->willReturn([
|
||||
$this->createRoom(1, 'foo'),
|
||||
$this->createRoom(2, 'bar'),
|
||||
|
|
|
@ -8,16 +8,19 @@ use OCA\BigBlueButton\Db\Restriction;
|
|||
use OCA\BigBlueButton\Db\RestrictionMapper;
|
||||
use OCA\BigBlueButton\Db\Room;
|
||||
use OCA\BigBlueButton\Service\RestrictionService;
|
||||
use OCP\IGroupManager;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RestrictionServiceTest extends TestCase {
|
||||
protected $mapper;
|
||||
protected $groupManager;
|
||||
protected $service;
|
||||
|
||||
public function setUp(): void {
|
||||
$this->mapper = $this->createMock(RestrictionMapper::class);
|
||||
$this->groupManager = $this->createMock(IGroupManager::class);
|
||||
|
||||
$this->service = new RestrictionService($this->mapper);
|
||||
$this->service = new RestrictionService($this->mapper, $this->groupManager);
|
||||
}
|
||||
|
||||
public function testFindByGroupIds() {
|
||||
|
|
|
@ -20,6 +20,7 @@ export enum Access {
|
|||
export interface Restriction {
|
||||
id: number;
|
||||
groupId: string;
|
||||
groupName: string;
|
||||
maxRooms: number;
|
||||
roomTypes: string[];
|
||||
maxParticipants: number;
|
||||
|
|
|
@ -37,6 +37,36 @@
|
|||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.bbb-qrcode-container {
|
||||
display: block;
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
margin: 3px;
|
||||
position: relative;
|
||||
cursor: zoom-in;
|
||||
|
||||
canvas {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
display: none;
|
||||
|
||||
&:checked + canvas {
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
box-shadow: 0 0 10px;
|
||||
box-shadow: 0 0 5px var(--color-box-shadow);
|
||||
cursor: zoom-out;
|
||||
border: 5px solid #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#bbb-root, #bbb-app {
|
||||
width: 100%;
|
||||
background-color: var(--color-main-background);
|
||||
|
@ -95,10 +125,6 @@ pre {
|
|||
}
|
||||
}
|
||||
|
||||
#bbb-react-root table tbody tr td {
|
||||
border-bottom: 1px solid var(--color-border-dark);
|
||||
}
|
||||
|
||||
#bbb-react-root,
|
||||
#bbb-restrictions {
|
||||
#bbb-warning,
|
||||
|
@ -194,6 +220,7 @@ pre {
|
|||
padding: 0 6px;
|
||||
position: relative;
|
||||
display: table-cell;
|
||||
border-bottom: 1px solid var(--color-border-dark);
|
||||
|
||||
& > form {
|
||||
margin: -10px;
|
||||
|
@ -298,39 +325,9 @@ pre {
|
|||
}
|
||||
|
||||
.bbb-simple-menu {
|
||||
min-width: auto;
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.bbb-input-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bbb-qrcode-container {
|
||||
display: block;
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
margin: 3px;
|
||||
position: relative;
|
||||
cursor: zoom-in;
|
||||
|
||||
canvas {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
display: none;
|
||||
|
||||
&:checked + canvas {
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
box-shadow: 0 0 10px;
|
||||
box-shadow: 0 0 5px var(--color-box-shadow);
|
||||
cursor: zoom-out;
|
||||
border: 5px solid #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,7 +146,8 @@ const App: React.FC<Props> = () => {
|
|||
}
|
||||
|
||||
const maxRooms = restriction?.maxRooms || 0;
|
||||
const quota = maxRooms < 0 ? t('bbb', 'unlimited') : rooms.filter(room => room.userId === OC.currentUser).length + ' / ' + maxRooms;
|
||||
const ownRoomsLength = rooms.filter(room => room.userId === OC.currentUser).length;
|
||||
const quota = maxRooms < 0 ? t('bbb', 'unlimited') : ownRoomsLength + ' / ' + maxRooms;
|
||||
|
||||
return (
|
||||
<div id="bbb-react-root"
|
||||
|
@ -188,7 +189,7 @@ const App: React.FC<Props> = () => {
|
|||
{!isLoaded && <span className="icon icon-loading-small icon-visible"></span>}
|
||||
</td>
|
||||
<td>
|
||||
{(maxRooms > rows.length || maxRooms < 0) ?
|
||||
{(maxRooms > ownRoomsLength || maxRooms < 0) ?
|
||||
<NewRoomForm addRoom={addRoom} /> :
|
||||
<p className="text-muted">{maxRooms === 0 ?
|
||||
t('bbb', 'You are not permitted to create a room.') :
|
||||
|
|
|
@ -23,10 +23,10 @@ const RestrictionRoom: React.FC<Props> = (props) => {
|
|||
|
||||
function deleteRow(ev: MouseEvent) {
|
||||
ev.preventDefault();
|
||||
|
||||
const groupName = restriction.groupName || restriction.groupId;
|
||||
OC.dialogs.confirm(
|
||||
t('bbb', 'Are you sure you want to delete the restrictions for group "{name}"? This operation cannot be undone.', { name: restriction.groupId }),
|
||||
t('bbb', 'Delete restrictions for "{name}"?', { name: restriction.groupId }),
|
||||
t('bbb', 'Are you sure you want to delete the restrictions for group "{name}"? This operation cannot be undone.', { name: groupName }),
|
||||
t('bbb', 'Delete restrictions for "{name}"?', { name: groupName}),
|
||||
confirmed => {
|
||||
if (confirmed) {
|
||||
props.deleteRestriction(restriction.id);
|
||||
|
@ -42,7 +42,7 @@ const RestrictionRoom: React.FC<Props> = (props) => {
|
|||
|
||||
return (
|
||||
<tr>
|
||||
<td className="name">{restriction.groupId || t('bbb', 'All users')}</td>
|
||||
<td className="name">{restriction.groupName || restriction.groupId || t('bbb', 'All users')}</td>
|
||||
<td className="max-rooms bbb-shrink">
|
||||
{edit('maxRooms', 'number')}
|
||||
</td>
|
||||
|
|
Loading…
Reference in New Issue