1<?php 2/** 3 * Nextcloud - passman 4 * 5 * @copyright Copyright (c) 2016, Sander Brand (brantje@gmail.com) 6 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel (wolfi@wolfi.es) 7 * @license GNU AGPL version 3 or any later version 8 * 9 * This program is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU Affero General Public License as 11 * published by the Free Software Foundation, either version 3 of the 12 * License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Affero General Public License for more details. 18 * 19 * You should have received a copy of the GNU Affero General Public License 20 * along with this program. If not, see <http://www.gnu.org/licenses/>. 21 * 22 */ 23 24namespace OCA\Passman\Service; 25 26use OCA\Passman\Activity; 27use OCA\Passman\Db\Credential; 28use OCA\Passman\Db\CredentialMapper; 29use OCA\Passman\Db\SharingACL; 30use OCA\Passman\Db\SharingACLMapper; 31use OCP\AppFramework\Db\DoesNotExistException; 32use OCP\AppFramework\Db\Entity; 33use OCP\AppFramework\Db\MultipleObjectsReturnedException; 34use OCP\IConfig; 35 36 37class CredentialService { 38 39 private CredentialMapper $credentialMapper; 40 private SharingACLMapper $sharingACL; 41 private ActivityService $activityService; 42 private ShareService $shareService; 43 private EncryptService $encryptService; 44 private CredentialRevisionService $credentialRevisionService; 45 private $server_key; 46 47 public function __construct(CredentialMapper $credentialMapper, 48 SharingACLMapper $sharingACL, 49 ActivityService $activityService, 50 ShareService $shareService, 51 EncryptService $encryptService, 52 CredentialRevisionService $credentialRevisionService, 53 IConfig $config) { 54 $this->credentialMapper = $credentialMapper; 55 $this->sharingACL = $sharingACL; 56 $this->activityService = $activityService; 57 $this->shareService = $shareService; 58 $this->encryptService = $encryptService; 59 $this->credentialRevisionService = $credentialRevisionService; 60 $this->server_key = $config->getSystemValue('passwordsalt', ''); 61 } 62 63 /** 64 * Create a new credential 65 * 66 * @param array $credential 67 * @return Credential 68 * @throws \Exception 69 */ 70 public function createCredential(array $credential) { 71 $credential = $this->encryptService->encryptCredential($credential); 72 return $this->credentialMapper->create($credential); 73 } 74 75 /** 76 * Update credential 77 * 78 * @param array $credential 79 * @param false $useRawUser 80 * @return Credential|Entity 81 * @throws DoesNotExistException 82 * @throws MultipleObjectsReturnedException 83 */ 84 public function updateCredential(array $credential, $useRawUser = false) { 85 $credential = $this->encryptService->encryptCredential($credential); 86 return $this->credentialMapper->updateCredential($credential, $useRawUser); 87 } 88 89 /** 90 * Update credential 91 * 92 * @param Credential $credential 93 * @return Credential|Entity 94 * @throws DoesNotExistException 95 * @throws MultipleObjectsReturnedException 96 */ 97 public function upd(Credential $credential) { 98 $credential = $this->encryptService->encryptCredential($credential); 99 return $this->credentialMapper->updateCredential($credential->jsonSerialize(), false); 100 } 101 102 /** 103 * Delete credential 104 * 105 * @param Credential $credential 106 * @return Entity 107 */ 108 public function deleteCredential(Credential $credential) { 109 $this->shareService->unshareCredential($credential->getGuid()); 110 return $this->credentialMapper->deleteCredential($credential); 111 } 112 113 /** 114 * Delete leftovers from a credential 115 * @param Credential $credential 116 * @throws \Exception 117 */ 118 public function deleteCredentialParts(Credential $credential, $userId) { 119 $this->activityService->add( 120 'item_destroyed_self', array($credential->getLabel()), 121 '', array(), 122 '', $userId, Activity::TYPE_ITEM_ACTION); 123 $this->shareService->unshareCredential($credential->getGuid()); 124 foreach ($this->credentialRevisionService->getRevisions($credential->getId()) as $revision) { 125 $id = $revision['revision_id']; 126 if (isset($id)) { 127 $this->credentialRevisionService->deleteRevision($id, $userId); 128 } 129 } 130 } 131 132 /** 133 * Get credentials by vault id 134 * 135 * @param int $vault_id 136 * @param string $user_id 137 * @return Entity[] 138 * @throws \Exception 139 */ 140 public function getCredentialsByVaultId(int $vault_id, string $user_id) { 141 $credentials = $this->credentialMapper->getCredentialsByVaultId($vault_id, $user_id); 142 foreach ($credentials as $index => $credential) { 143 $credentials[$index] = $this->encryptService->decryptCredential($credential); 144 } 145 return $credentials; 146 } 147 148 /** 149 * Get a random credential from given vault 150 * 151 * @param int $vault_id 152 * @param string $user_id 153 * @return mixed 154 */ 155 public function getRandomCredentialByVaultId(int $vault_id, string $user_id) { 156 $credentials = $this->credentialMapper->getRandomCredentialByVaultId($vault_id, $user_id); 157 foreach ($credentials as $index => $credential) { 158 $credentials[$index] = $this->encryptService->decryptCredential($credential); 159 } 160 return array_pop($credentials); 161 } 162 163 /** 164 * Get expired credentials. 165 * 166 * @param int $timestamp 167 * @return Entity[] 168 * @throws \Exception 169 */ 170 public function getExpiredCredentials(int $timestamp) { 171 $credentials = $this->credentialMapper->getExpiredCredentials($timestamp); 172 foreach ($credentials as $index => $credential) { 173 $credentials[$index] = $this->encryptService->decryptCredential($credential); 174 } 175 return $credentials; 176 } 177 178 /** 179 * Get a single credential. 180 * 181 * @param int $credential_id 182 * @param string $user_id 183 * @return array|Credential 184 * @throws DoesNotExistException 185 * @throws MultipleObjectsReturnedException 186 */ 187 public function getCredentialById(int $credential_id, ?string $user_id) { 188 $credential = $this->credentialMapper->getCredentialById($credential_id); 189 if ($credential->getUserId() === $user_id) { 190 return $this->encryptService->decryptCredential($credential); 191 } else { 192 $acl = $this->sharingACL->getItemACL($user_id, $credential->getGuid()); 193 if ($acl->hasPermission(SharingACL::READ)) { 194 return $this->encryptService->decryptCredential($credential); 195 } else { 196 throw new DoesNotExistException("Did expect one result but found none when executing"); 197 } 198 } 199 } 200 201 /** 202 * Get credential label by credential id. 203 * 204 * @param int $credential_id 205 * @return array|Credential 206 * @throws DoesNotExistException 207 * @throws MultipleObjectsReturnedException 208 */ 209 public function getCredentialLabelById(int $credential_id) { 210 $credential = $this->credentialMapper->getCredentialLabelById($credential_id); 211 return $this->encryptService->decryptCredential($credential); 212 } 213 214 /** 215 * Get credential by guid 216 * 217 * @param string $credential_guid 218 * @param string|null $user_id 219 * @return array|Credential 220 * @throws DoesNotExistException 221 * @throws MultipleObjectsReturnedException 222 */ 223 public function getCredentialByGUID(string $credential_guid, string $user_id = null) { 224 $credential = $this->credentialMapper->getCredentialByGUID($credential_guid, $user_id); 225 return $this->encryptService->decryptCredential($credential); 226 } 227} 228