1<?php 2 3declare(strict_types=1); 4/** 5 * @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com> 6 * 7 * @author Joas Schilling <coding@schilljs.com> 8 * 9 * @license GNU AGPL version 3 or any later version 10 * 11 * This program is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Affero General Public License as 13 * published by the Free Software Foundation, either version 3 of the 14 * License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Affero General Public License for more details. 20 * 21 * You should have received a copy of the GNU Affero General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 * 24 */ 25 26namespace OCA\Talk; 27 28use OCA\Talk\Model\Attendee; 29use OCA\Talk\Model\Session; 30use OCP\IConfig; 31 32class Participant { 33 public const OWNER = 1; 34 public const MODERATOR = 2; 35 public const USER = 3; 36 public const GUEST = 4; 37 public const USER_SELF_JOINED = 5; 38 public const GUEST_MODERATOR = 6; 39 40 public const FLAG_DISCONNECTED = 0; 41 public const FLAG_IN_CALL = 1; 42 public const FLAG_WITH_AUDIO = 2; 43 public const FLAG_WITH_VIDEO = 4; 44 public const FLAG_WITH_PHONE = 8; 45 46 public const NOTIFY_DEFAULT = 0; 47 public const NOTIFY_ALWAYS = 1; 48 public const NOTIFY_MENTION = 2; 49 public const NOTIFY_NEVER = 3; 50 51 public const NOTIFY_CALLS_OFF = 0; 52 public const NOTIFY_CALLS_ON = 1; 53 54 public const PRIVACY_PUBLIC = 0; 55 public const PRIVACY_PRIVATE = 1; 56 57 /** @var Room */ 58 protected $room; 59 /** @var Attendee */ 60 protected $attendee; 61 /** @var Session|null */ 62 protected $session; 63 64 public function __construct(Room $room, 65 Attendee $attendee, 66 ?Session $session) { 67 $this->room = $room; 68 $this->attendee = $attendee; 69 $this->session = $session; 70 } 71 72 public function getAttendee(): Attendee { 73 return $this->attendee; 74 } 75 76 public function getSession(): ?Session { 77 return $this->session; 78 } 79 80 public function setSession(Session $session): void { 81 $this->session = $session; 82 } 83 84 public function isGuest(): bool { 85 $participantType = $this->attendee->getParticipantType(); 86 return \in_array($participantType, [self::GUEST, self::GUEST_MODERATOR], true); 87 } 88 89 public function hasModeratorPermissions(bool $guestModeratorAllowed = true): bool { 90 $participantType = $this->attendee->getParticipantType(); 91 if (!$guestModeratorAllowed) { 92 return \in_array($participantType, [self::OWNER, self::MODERATOR], true); 93 } 94 95 return \in_array($participantType, [self::OWNER, self::MODERATOR, self::GUEST_MODERATOR], true); 96 } 97 98 public function canStartCall(IConfig $config): bool { 99 $defaultStartCall = (int) $config->getAppValue('spreed', 'start_calls', Room::START_CALL_EVERYONE); 100 101 if (!($this->getPermissions() & Attendee::PERMISSIONS_CALL_START)) { 102 return false; 103 } 104 105 if ($defaultStartCall === Room::START_CALL_EVERYONE) { 106 return true; 107 } 108 109 if ($defaultStartCall === Room::START_CALL_USERS && (!$this->isGuest() || $this->hasModeratorPermissions())) { 110 return true; 111 } 112 113 if ($defaultStartCall === Room::START_CALL_MODERATORS && $this->hasModeratorPermissions()) { 114 return true; 115 } 116 117 return false; 118 } 119 120 public function getPermissions(): int { 121 $permissions = $this->getPermissionsFromFallbackChain(); 122 123 if ($this->hasModeratorPermissions()) { 124 // Moderators can always do everything 125 $permissions = Attendee::PERMISSIONS_MAX_DEFAULT; 126 } 127 128 return $permissions; 129 } 130 131 protected function getPermissionsFromFallbackChain(): int { 132 if ($this->getAttendee()->getPermissions() !== Attendee::PERMISSIONS_DEFAULT) { 133 return $this->getAttendee()->getPermissions(); 134 } 135 136 if ($this->room->getCallPermissions() !== Attendee::PERMISSIONS_DEFAULT) { 137 // The currently ongoing call is in a special mode 138 return $this->room->getCallPermissions(); 139 } 140 141 if ($this->room->getDefaultPermissions() !== Attendee::PERMISSIONS_DEFAULT) { 142 // The conversation has some permissions set 143 return $this->room->getDefaultPermissions(); 144 } 145 146 // Falling back to an unrestricted set of permissions, only ignoring the lobby is off 147 return Attendee::PERMISSIONS_MAX_DEFAULT & ~Attendee::PERMISSIONS_LOBBY_IGNORE; 148 } 149} 150