mirror of
https://github.com/nextcloud/passman.git
synced 2024-12-24 08:32:18 +08:00
Add settings page, non functional
Implement disable context menu Implemement disable http warning Implement vault key strength setting Implement share settings Implement version check setting
This commit is contained in:
parent
3d31b28093
commit
858195834d
21 changed files with 506 additions and 77 deletions
|
@ -17,7 +17,7 @@ For an demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
|
|||
]]></description>
|
||||
|
||||
<licence>AGPL</licence>
|
||||
<version>2.0.0-RC2</version>
|
||||
<version>2.0.0-RC3</version>
|
||||
<author homepage="https://github.com/brantje">Sander Brand</author>
|
||||
<author homepage="https://github.com/animalillo">Marcos Zuriaga</author>
|
||||
<namespace>Passman</namespace>
|
||||
|
@ -40,7 +40,9 @@ For an demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
|
|||
<database>sqlite</database>
|
||||
<database min-version="5.5">mysql</database>
|
||||
</dependencies>
|
||||
|
||||
<settings>
|
||||
<admin>OCA\Passman\Settings\Admin</admin>
|
||||
</settings>
|
||||
|
||||
<background-jobs>
|
||||
<job>OCA\Passman\BackgroundJob\ExpireCredentials</job>
|
||||
|
|
|
@ -76,6 +76,8 @@ return [
|
|||
['name' => 'internal#read', 'url' => '/api/internal/notifications/read/{credential_id}', 'verb' => 'DELETE'],
|
||||
['name' => 'internal#getAppVersion', 'url' => '/api/internal/version', 'verb' => 'GET'],
|
||||
['name' => 'internal#generatePerson', 'url' => '/api/internal/generate_person', 'verb' => 'GET'],
|
||||
['name' => 'internal#save_settings', 'url' => '/api/internal/settings/{key}/{value}', 'verb' => 'POST'],
|
||||
['name' => 'internal#get_settings', 'url' => '/api/internal/settings', 'verb' => 'GET'],
|
||||
|
||||
]
|
||||
];
|
|
@ -17,6 +17,7 @@ use OCA\Passman\Utility\NotFoundJSONResponse;
|
|||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\ApiController;
|
||||
|
@ -33,6 +34,7 @@ class CredentialController extends ApiController {
|
|||
private $activityService;
|
||||
private $credentialRevisionService;
|
||||
private $sharingService;
|
||||
private $config;
|
||||
|
||||
public function __construct($AppName,
|
||||
IRequest $request,
|
||||
|
@ -40,7 +42,8 @@ class CredentialController extends ApiController {
|
|||
CredentialService $credentialService,
|
||||
ActivityService $activityService,
|
||||
CredentialRevisionService $credentialRevisionService,
|
||||
ShareService $sharingService
|
||||
ShareService $sharingService,
|
||||
IConfig $config
|
||||
) {
|
||||
parent::__construct($AppName, $request);
|
||||
$this->userId = $userId;
|
||||
|
@ -48,8 +51,10 @@ class CredentialController extends ApiController {
|
|||
$this->activityService = $activityService;
|
||||
$this->credentialRevisionService = $credentialRevisionService;
|
||||
$this->sharingService = $sharingService;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
|
@ -85,7 +90,7 @@ class CredentialController extends ApiController {
|
|||
);
|
||||
$credential = $this->credentialService->createCredential($credential);
|
||||
$link = ''; // @TODO create direct link to credential
|
||||
if(!$credential->getHidden()) {
|
||||
if (!$credential->getHidden()) {
|
||||
$this->activityService->add(
|
||||
Activity::SUBJECT_ITEM_CREATED_SELF, array($label, $this->userId),
|
||||
'', array(),
|
||||
|
@ -146,7 +151,11 @@ class CredentialController extends ApiController {
|
|||
} else {
|
||||
return new DataResponse(['msg' => 'Not authorized'], Http::STATUS_UNAUTHORIZED);
|
||||
}
|
||||
if ($this->config->getAppValue('passman', 'user_sharing_enabled', 1) === 0 || $this->config->getAppValue('passman', 'user_sharing_enabled', 1) === '0') {
|
||||
return new DataResponse(['msg' => 'Not authorized'], Http::STATUS_UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
$link = ''; // @TODO create direct link to credential
|
||||
if ($revision_created) {
|
||||
$activity = 'item_apply_revision';
|
||||
|
@ -154,13 +163,13 @@ class CredentialController extends ApiController {
|
|||
$activity . '_self', array($label, $this->userId, $revision_created),
|
||||
'', array(),
|
||||
$link, $this->userId, Activity::TYPE_ITEM_ACTION);
|
||||
} else if (($storedCredential->getDeleteTime() === 0) && (int) $delete_time > 0) {
|
||||
} else if (($storedCredential->getDeleteTime() === 0) && (int)$delete_time > 0) {
|
||||
$activity = 'item_deleted';
|
||||
$this->activityService->add(
|
||||
$activity . '_self', array($label, $this->userId),
|
||||
'', array(),
|
||||
$link, $this->userId, Activity::TYPE_ITEM_ACTION);
|
||||
} else if (($storedCredential->getDeleteTime() > 0) && (int) $delete_time === 0) {
|
||||
} else if (($storedCredential->getDeleteTime() > 0) && (int)$delete_time === 0) {
|
||||
$activity = 'item_recovered';
|
||||
$this->activityService->add(
|
||||
$activity . '_self', array($label, $this->userId),
|
||||
|
@ -204,7 +213,7 @@ class CredentialController extends ApiController {
|
|||
|
||||
foreach ($acl_list as $sharingACL) {
|
||||
$target_user = $sharingACL->getUserId();
|
||||
if($target_user === $this->userId){
|
||||
if ($target_user === $this->userId) {
|
||||
continue;
|
||||
}
|
||||
$this->activityService->add(
|
||||
|
@ -219,15 +228,15 @@ class CredentialController extends ApiController {
|
|||
$link, $storedCredential->getUserId(), Activity::TYPE_ITEM_ACTION);
|
||||
}
|
||||
}
|
||||
if($set_share_key === true){
|
||||
if ($set_share_key === true) {
|
||||
$storedCredential->setSharedKey($shared_key);
|
||||
$credential['shared_key'] = $shared_key;
|
||||
}
|
||||
if($unshare_action === true){
|
||||
if ($unshare_action === true) {
|
||||
$storedCredential->setSharedKey('');
|
||||
$credential['shared_key'] = '';
|
||||
}
|
||||
if(!$skip_revision) {
|
||||
if (!$skip_revision) {
|
||||
$this->credentialRevisionService->createRevision($storedCredential, $storedCredential->getUserId(), $credential_id, $this->userId);
|
||||
}
|
||||
$credential = $this->credentialService->updateCredential($credential);
|
||||
|
@ -259,26 +268,23 @@ class CredentialController extends ApiController {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
public function getRevision($credential_guid) {
|
||||
try {
|
||||
$credential = $this->credentialService->getCredentialByGUID($credential_guid);
|
||||
}
|
||||
catch (DoesNotExistException $ex){
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
try {
|
||||
$credential = $this->credentialService->getCredentialByGUID($credential_guid);
|
||||
} catch (DoesNotExistException $ex) {
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
|
||||
// If the request was made by the owner of the credential
|
||||
if ($this->userId === $credential->getUserId()) {
|
||||
$result = $this->credentialRevisionService->getRevisions($credential->getId(), $this->userId);
|
||||
}
|
||||
else {
|
||||
$acl = $this->sharingService->getACL($this->userId, $credential_guid);
|
||||
if ($acl->hasPermission(SharingACL::HISTORY)){
|
||||
$result = $this->credentialRevisionService->getRevisions($credential->getId());
|
||||
}
|
||||
else {
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
}
|
||||
// If the request was made by the owner of the credential
|
||||
if ($this->userId === $credential->getUserId()) {
|
||||
$result = $this->credentialRevisionService->getRevisions($credential->getId(), $this->userId);
|
||||
} else {
|
||||
$acl = $this->sharingService->getACL($this->userId, $credential_guid);
|
||||
if ($acl->hasPermission(SharingACL::HISTORY)) {
|
||||
$result = $this->credentialRevisionService->getRevisions($credential->getId());
|
||||
} else {
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
}
|
||||
|
||||
return new JSONResponse($result);
|
||||
}
|
||||
|
@ -296,7 +302,7 @@ class CredentialController extends ApiController {
|
|||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function updateRevision($credential_guid, $revision_id, $credential_data){
|
||||
public function updateRevision($credential_guid, $revision_id, $credential_data) {
|
||||
$revision = null;
|
||||
try {
|
||||
$this->credentialService->getCredentialByGUID($credential_guid, $this->userId);
|
||||
|
@ -304,9 +310,9 @@ class CredentialController extends ApiController {
|
|||
return new NotFoundJSONResponse();
|
||||
}
|
||||
|
||||
try{
|
||||
try {
|
||||
$revision = $this->credentialRevisionService->getRevision($revision_id);
|
||||
} catch(DoesNotExistException $exception){
|
||||
} catch (DoesNotExistException $exception) {
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace OCA\Passman\Controller;
|
||||
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\ApiController;
|
||||
|
@ -20,14 +21,18 @@ use \OCP\App;
|
|||
class InternalController extends ApiController {
|
||||
private $userId;
|
||||
private $credentialService;
|
||||
private $config;
|
||||
|
||||
public function __construct($AppName,
|
||||
IRequest $request,
|
||||
$UserId,
|
||||
CredentialService $credentialService) {
|
||||
CredentialService $credentialService,
|
||||
IConfig $config
|
||||
) {
|
||||
parent::__construct($AppName, $request);
|
||||
$this->userId = $UserId;
|
||||
$this->credentialService = $credentialService;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,4 +85,30 @@ class InternalController extends ApiController {
|
|||
return new JSONResponse($random_person);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function getSettings() {
|
||||
$settings = array(
|
||||
'link_sharing_enabled' => $this->config->getAppValue('passman', 'link_sharing_enabled', 1),
|
||||
'user_sharing_enabled' => $this->config->getAppValue('passman', 'user_sharing_enabled', 1),
|
||||
'vault_key_strength' => $this->config->getAppValue('passman', 'vault_key_strength', 3),
|
||||
'check_version' => $this->config->getAppValue('passman', 'check_version', 1),
|
||||
'https_check' => $this->config->getAppValue('passman', 'https_check', 1),
|
||||
'disable_contextmenu' => $this->config->getAppValue('passman', 'disable_contextmenu', 1),
|
||||
);
|
||||
return new JSONResponse($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function saveSettings($key, $value) {
|
||||
if (is_numeric($value)) {
|
||||
$value = intval($value);
|
||||
}
|
||||
$this->config->setAppValue('passman', $key, $value);
|
||||
}
|
||||
|
||||
}
|
|
@ -11,8 +11,6 @@
|
|||
|
||||
namespace OCA\Passman\Controller;
|
||||
|
||||
use OCA\Files_External\NotFoundException;
|
||||
use OCA\Passman\Db\ShareRequest;
|
||||
use OCA\Passman\Db\SharingACL;
|
||||
use OCA\Passman\Db\Vault;
|
||||
use OCA\Passman\Service\CredentialService;
|
||||
|
@ -23,16 +21,13 @@ use OCA\Passman\Utility\NotFoundJSONResponse;
|
|||
use OCA\Passman\Utility\Utils;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http\NotFoundResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\ApiController;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUser;
|
||||
|
||||
use OCA\Passman\Service\VaultService;
|
||||
use OCA\Passman\Service\ActivityService;
|
||||
|
@ -49,6 +44,7 @@ class ShareController extends ApiController {
|
|||
private $credentialService;
|
||||
private $notificationService;
|
||||
private $fileService;
|
||||
private $config;
|
||||
|
||||
private $limit = 50;
|
||||
private $offset = 0;
|
||||
|
@ -63,7 +59,8 @@ class ShareController extends ApiController {
|
|||
ShareService $shareService,
|
||||
CredentialService $credentialService,
|
||||
NotificationService $notificationService,
|
||||
FileService $fileService
|
||||
FileService $fileService,
|
||||
IConfig $config
|
||||
) {
|
||||
parent::__construct($AppName, $request);
|
||||
|
||||
|
@ -76,6 +73,13 @@ class ShareController extends ApiController {
|
|||
$this->credentialService = $credentialService;
|
||||
$this->notificationService = $notificationService;
|
||||
$this->fileService = $fileService;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
private function isSharingEnabled() {
|
||||
if ($this->config->getAppValue('passman', 'link_sharing_enabled', 1) === 0 || $this->config->getAppValue('passman', 'link_sharing_enabled', 1) === '0') {
|
||||
return new JSONResponse(array());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,10 +91,12 @@ class ShareController extends ApiController {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
public function createPublicShare($item_id, $item_guid, $permissions, $expire_timestamp, $expire_views) {
|
||||
$this->isSharingEnabled();
|
||||
|
||||
try{
|
||||
|
||||
try {
|
||||
$credential = $this->credentialService->getCredentialByGUID($item_guid);
|
||||
} catch (DoesNotExistException $exception){
|
||||
} catch (DoesNotExistException $exception) {
|
||||
return new NotFoundResponse();
|
||||
}
|
||||
|
||||
|
@ -124,6 +130,7 @@ class ShareController extends ApiController {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
public function applyIntermediateShare($item_id, $item_guid, $vaults, $permissions) {
|
||||
$this->isSharingEnabled();
|
||||
/**
|
||||
* Assemble notification
|
||||
*/
|
||||
|
@ -139,14 +146,14 @@ class ShareController extends ApiController {
|
|||
return new JSONResponse(array('error' => 'User got already pending requests'));
|
||||
}
|
||||
} catch (DoesNotExistException $exception) {
|
||||
|
||||
// no need to catch this
|
||||
}
|
||||
|
||||
$acl = null;
|
||||
try {
|
||||
$acl = $this->shareService->getCredentialAclForUser($first_vault['user_id'], $item_guid);
|
||||
} catch (DoesNotExistException $exception) {
|
||||
|
||||
// no need to catch this
|
||||
}
|
||||
|
||||
if ($acl) {
|
||||
|
@ -216,6 +223,7 @@ class ShareController extends ApiController {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
public function unshareCredential($item_guid) {
|
||||
$this->isSharingEnabled();
|
||||
$acl_list = $this->shareService->getCredentialAclList($item_guid);
|
||||
$request_list = $this->shareService->getShareRequestsByGuid($item_guid);
|
||||
foreach ($acl_list as $ACL) {
|
||||
|
@ -234,21 +242,21 @@ class ShareController extends ApiController {
|
|||
}
|
||||
|
||||
|
||||
public function unshareCredentialFromUser($item_guid, $user_id){
|
||||
public function unshareCredentialFromUser($item_guid, $user_id) {
|
||||
$acl = null;
|
||||
$sr = null;
|
||||
try {
|
||||
$acl = $this->shareService->getCredentialAclForUser($user_id, $item_guid);
|
||||
} catch (DoesNotExistException $e){
|
||||
} catch (DoesNotExistException $e) {
|
||||
|
||||
}
|
||||
try{
|
||||
$sr = array_pop($this->shareService->getPendingShareRequestsForCredential($item_guid, $user_id));
|
||||
} catch (DoesNotExistException $e){
|
||||
|
||||
try {
|
||||
$sr = array_pop($this->shareService->getPendingShareRequestsForCredential($item_guid, $user_id));
|
||||
} catch (DoesNotExistException $e) {
|
||||
// no need to catch this
|
||||
}
|
||||
|
||||
if($sr){
|
||||
if ($sr) {
|
||||
$this->shareService->cleanItemRequestsForUser($sr);
|
||||
$manager = \OC::$server->getNotificationManager();
|
||||
$notification = $manager->createNotification();
|
||||
|
@ -257,7 +265,7 @@ class ShareController extends ApiController {
|
|||
->setUser($user_id);
|
||||
$manager->markProcessed($notification);
|
||||
}
|
||||
if($acl){
|
||||
if ($acl) {
|
||||
$this->shareService->deleteShareACL($acl);
|
||||
}
|
||||
return new JSONResponse(array('result' => true));
|
||||
|
@ -355,7 +363,7 @@ class ShareController extends ApiController {
|
|||
try {
|
||||
return new JSONResponse($this->shareService->getItemHistory($this->userId, $item_guid));
|
||||
} catch (DoesNotExistException $ex) {
|
||||
return new NotFoundResponse();
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,6 +374,8 @@ class ShareController extends ApiController {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
public function getVaultItems($vault_guid) {
|
||||
$this->isSharingEnabled();
|
||||
|
||||
try {
|
||||
return new JSONResponse($this->shareService->getSharedItems($this->userId->getUID(), $vault_guid));
|
||||
} catch (DoesNotExistException $ex) {
|
||||
|
@ -404,7 +414,7 @@ class ShareController extends ApiController {
|
|||
$this->shareService->cleanItemRequestsForUser($sr);
|
||||
return new JSONResponse(array('result' => true));
|
||||
} catch (DoesNotExistException $ex) {
|
||||
return new NotFoundResponse();
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,15 +426,15 @@ class ShareController extends ApiController {
|
|||
* @PublicPage
|
||||
*/
|
||||
public function getPublicCredentialData($credential_guid) {
|
||||
|
||||
$this->isSharingEnabled();
|
||||
//@TODO Check expire date
|
||||
$acl = $this->shareService->getACL(null, $credential_guid);
|
||||
|
||||
if ($acl->getExpire() > 0 && Utils::getTime() > $acl->getExpire()) {
|
||||
if ($acl->getExpire() > 0 && Utils::getTime() > $acl->getExpire()) {
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
|
||||
$views = $acl->getExpireViews();
|
||||
$views = $acl->getExpireViews();
|
||||
if ($views === 0) {
|
||||
return new NotFoundJSONResponse();
|
||||
} else if ($views !== -1) {
|
||||
|
@ -475,15 +485,15 @@ class ShareController extends ApiController {
|
|||
* @return JSONResponse
|
||||
* @return NotFoundResponse
|
||||
*/
|
||||
public function getFile($item_guid, $file_guid){
|
||||
public function getFile($item_guid, $file_guid) {
|
||||
try {
|
||||
$credential = $this->credentialService->getCredentialByGUID($item_guid);
|
||||
} catch (DoesNotExistException $e){
|
||||
} catch (DoesNotExistException $e) {
|
||||
return new NotFoundJSONResponse();
|
||||
}
|
||||
$userId = ($this->userId) ? $this->userId->getUID() : null;
|
||||
$acl = $this->shareService->getACL($userId, $credential->getGuid());
|
||||
if (!$acl->hasPermission(SharingACL::FILES)){
|
||||
if (!$acl->hasPermission(SharingACL::FILES)) {
|
||||
return new NotFoundJSONResponse();
|
||||
} else {
|
||||
return $this->fileService->getFileByGuid($file_guid);
|
||||
|
|
|
@ -96,6 +96,11 @@ class TranslationController extends ApiController {
|
|||
'credential.shared' => $this->trans->t('Credential shared'),
|
||||
'saved' => $this->trans->t('Saved!'),
|
||||
|
||||
// js/app/controllers/vault.js
|
||||
'password.poor' => $this->trans->t('Poor'),
|
||||
'password.weak' => $this->trans->t('Weak'),
|
||||
'password.good' => $this->trans->t('Good'),
|
||||
'password.strong' => $this->trans->t('Strong'),
|
||||
// js/app/directives/credentialfield.js
|
||||
'toggle.visibility' => $this->trans->t('Toggle visibility'),
|
||||
'copy.field' => $this->trans->t('Copy to clipboard'),
|
||||
|
|
|
@ -194,6 +194,19 @@
|
|||
};
|
||||
|
||||
|
||||
var settingsLoaded = function () {
|
||||
$scope.settings = SettingsService.getSettings();
|
||||
};
|
||||
|
||||
if(!SettingsService.getSetting('user_sharing_enabled')){
|
||||
$rootScope.$on('settings_loaded', function () {
|
||||
settingsLoaded();
|
||||
});
|
||||
} else {
|
||||
settingsLoaded();
|
||||
}
|
||||
|
||||
|
||||
$scope.addCredential = function () {
|
||||
var new_credential = CredentialService.newCredential();
|
||||
var enc_c = CredentialService.encryptCredential(new_credential);
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('MainCtrl', ['$scope', '$rootScope', '$location', function ($scope, $rootScope, $location) {
|
||||
.controller('MainCtrl', ['$scope', '$rootScope', '$location', 'SettingsService', function ($scope, $rootScope, $location, SettingsService) {
|
||||
$scope.selectedVault = false;
|
||||
|
||||
$scope.http_warning_hidden = true;
|
||||
|
@ -41,6 +41,17 @@
|
|||
|
||||
}
|
||||
|
||||
$rootScope.$on('settings_loaded', function(){
|
||||
if (SettingsService.getSetting('disable_contextmenu') === '1' || SettingsService.getSetting('disable_contextmenu') === 1) {
|
||||
document.addEventListener('contextmenu', function (event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
if (SettingsService.getSetting('https_check') === '0' || SettingsService.getSetting('https_check') === 0) {
|
||||
$scope.http_warning_hidden = true;
|
||||
}
|
||||
});
|
||||
|
||||
$rootScope.setHttpWarning = function (state) {
|
||||
$scope.http_warning_hidden = state;
|
||||
};
|
||||
|
|
|
@ -32,10 +32,13 @@
|
|||
* This file is part of passman, licensed under AGPLv3
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL', 'EncryptService', '$translate',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService, $translate) {
|
||||
.controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL', 'EncryptService', '$translate', '$rootScope',
|
||||
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService, $translate, $rootScope) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
|
||||
|
||||
|
||||
|
||||
$scope.tabs = [{
|
||||
title: $translate.instant('share.u.g'),
|
||||
url: 'views/partials/forms/share_credential/basics.html'
|
||||
|
@ -44,8 +47,31 @@
|
|||
url: 'views/partials/forms/share_credential/link_sharing.html',
|
||||
color: 'green'
|
||||
}];
|
||||
|
||||
$scope.currentTab = $scope.tabs[0];
|
||||
|
||||
|
||||
var settingsLoaded = function () {
|
||||
var settings = SettingsService.getSettings();
|
||||
if(settings.user_sharing_enabled === 0 || settings.user_sharing_enabled ==='0'){
|
||||
$scope.tabs.splice(0,1);
|
||||
}
|
||||
if(settings.link_sharing_enabled === 0 || settings.link_sharing_enabled ==='0'){
|
||||
$scope.tabs.splice(1,1);
|
||||
}
|
||||
if($scope.tabs.length > 0){
|
||||
$scope.currentTab = $scope.tabs[0];
|
||||
}
|
||||
};
|
||||
|
||||
if(!SettingsService.getSetting('user_sharing_enabled')){
|
||||
$rootScope.$on('settings_loaded', function () {
|
||||
settingsLoaded();
|
||||
});
|
||||
} else {
|
||||
settingsLoaded();
|
||||
}
|
||||
|
||||
$scope.onClickTab = function (tab) {
|
||||
$scope.currentTab = tab;
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('VaultCtrl', ['$scope', 'VaultService', 'SettingsService', 'CredentialService', '$location', 'ShareService', 'EncryptService', '$translate', function ($scope, VaultService, SettingsService, CredentialService, $location, ShareService, EncryptService, $translate) {
|
||||
.controller('VaultCtrl', ['$scope', 'VaultService', 'SettingsService', 'CredentialService', '$location', 'ShareService', 'EncryptService', '$translate', '$rootScope', function ($scope, VaultService, SettingsService, CredentialService, $location, ShareService, EncryptService, $translate, $rootScope) {
|
||||
VaultService.getVaults().then(function (vaults) {
|
||||
$scope.vaults = vaults;
|
||||
if (SettingsService.getSetting('defaultVault') != null) {
|
||||
|
@ -57,9 +57,26 @@
|
|||
});
|
||||
|
||||
|
||||
var key_strengths = [
|
||||
'password.poor',
|
||||
'password.poor',
|
||||
'password.weak',
|
||||
'password.good',
|
||||
'password.strong'
|
||||
];
|
||||
|
||||
$scope.default_vault = false;
|
||||
$scope.remember_vault_password = false;
|
||||
$scope.list_selected_vault = false;
|
||||
$scope.minimal_value_key_strength = 3;
|
||||
|
||||
$rootScope.$on('settings_loaded', function () {
|
||||
$scope.minimal_value_key_strength = SettingsService.getSetting('vault_key_strength');
|
||||
$translate(key_strengths[SettingsService.getSetting('vault_key_strength')]).then(function(translation){
|
||||
$scope.required_score = {'strength': translation};
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$scope.toggleDefaultVault = function () {
|
||||
$scope.default_vault = !$scope.default_vault;
|
||||
|
@ -96,7 +113,7 @@
|
|||
var key_size = 1024;
|
||||
ShareService.generateRSAKeys(key_size).progress(function (progress) {
|
||||
var p = progress > 0 ? 2 : 1;
|
||||
var msg = $translate.instant('generating.sharing.keys');
|
||||
var msg = $translate.instant('generating.sharing.keys');
|
||||
msg = msg.replace('%step', p);
|
||||
$scope.creating_keys = msg;
|
||||
$scope.$digest();
|
||||
|
|
|
@ -32,12 +32,18 @@
|
|||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('SettingsService', ['localStorageService', function (localStorageService) {
|
||||
.service('SettingsService', ['localStorageService', '$http', '$rootScope', function (localStorageService, $http, $rootScope) {
|
||||
var settings = {
|
||||
defaultVault: null,
|
||||
defaultVaultPass: null
|
||||
};
|
||||
|
||||
$http.get(OC.generateUrl('apps/passman/api/internal/settings')).then(function (response) {
|
||||
if (response.data) {
|
||||
settings = angular.merge(settings, response.data);
|
||||
$rootScope.$broadcast('settings_loaded');
|
||||
}
|
||||
});
|
||||
|
||||
var cookie = localStorageService.get('settings');
|
||||
settings = angular.merge(settings, cookie);
|
||||
|
|
121
js/settings-admin.js
Normal file
121
js/settings-admin.js
Normal file
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
* @copyright Copyright (c) 2016, Sander Brand (brantje@gmail.com)
|
||||
* @copyright Copyright (c) 2016, Marcos Zuriaga Miguel (wolfi@wolfi.es)
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
var Settings = function (baseUrl) {
|
||||
this._baseUrl = baseUrl;
|
||||
this._settings = [];
|
||||
};
|
||||
|
||||
Settings.prototype = {
|
||||
load: function () {
|
||||
var deferred = $.Deferred();
|
||||
var self = this;
|
||||
$.ajax({
|
||||
url: this._baseUrl,
|
||||
method: 'GET',
|
||||
async: false
|
||||
}).done(function (settings) {
|
||||
self._settings = settings;
|
||||
}).fail(function () {
|
||||
deferred.reject();
|
||||
});
|
||||
return deferred.promise();
|
||||
},
|
||||
|
||||
setUserKey: function (key, value) {
|
||||
var request = $.ajax({
|
||||
url: this._baseUrl + '/' + key + '/' + value,
|
||||
method: 'POST'
|
||||
});
|
||||
request.done(function () {
|
||||
$('.msg-passwords').removeClass("msg_error");
|
||||
$('.msg-passwords').text('');
|
||||
});
|
||||
request.fail(function () {
|
||||
$('.msg-passwords').addClass("msg_error");
|
||||
$('.msg-passwords').text(t('passwords', 'Error while saving field') + ' ' + key + '!');
|
||||
});
|
||||
},
|
||||
|
||||
setAdminKey: function (key, value) {
|
||||
var request = $.ajax({
|
||||
url: this._baseUrl + '/' + key + '/' + value,
|
||||
method: 'POST'
|
||||
});
|
||||
request.done(function () {
|
||||
$('.msg-passwords').removeClass("msg_error");
|
||||
$('.msg-passwords').text('');
|
||||
});
|
||||
request.fail(function () {
|
||||
$('.msg-passwords').addClass("msg_error");
|
||||
$('.msg-passwords').text(t('passwords', 'Error while saving field') + ' ' + key + '!');
|
||||
});
|
||||
},
|
||||
getKey: function (key) {
|
||||
if(this._settings.hasOwnProperty(key)){
|
||||
return this._settings[key];
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getAll: function () {
|
||||
return this._settings;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var settings = new Settings(OC.generateUrl('apps/passman/api/internal/settings'));
|
||||
settings.load();
|
||||
|
||||
// ADMIN SETTINGS
|
||||
|
||||
// fill the boxes
|
||||
$('#passman_link_sharing_enabled').prop('checked', (settings.getKey('link_sharing_enabled').toString().toLowerCase() == '1'));
|
||||
$('#passman_sharing_enabled').prop('checked', (settings.getKey('user_sharing_enabled').toString().toLowerCase() == '1'));
|
||||
$('#passman_check_version').prop('checked', (settings.getKey('check_version').toString().toLowerCase() == '1'));
|
||||
$('#passman_https_check').prop('checked', (settings.getKey('https_check').toString().toLowerCase() == '1'));
|
||||
$('#passman_disable_contextmenu').prop('checked', (settings.getKey('disable_contextmenu').toString().toLowerCase() == '1'));
|
||||
$('#vault_key_strength').val(settings.getKey('vault_key_strength'));
|
||||
|
||||
|
||||
$('#passman_check_version').change(function () {
|
||||
settings.setAdminKey('check_version', ($(this).is(":checked")) ? 1 : 0);
|
||||
});
|
||||
|
||||
$('#passman_https_check').change(function () {
|
||||
settings.setAdminKey('https_check', ($(this).is(":checked")) ? 1 : 0);
|
||||
});
|
||||
|
||||
$('#passman_disable_contextmenu').change(function () {
|
||||
settings.setAdminKey('disable_contextmenu', ($(this).is(":checked")) ? 1 : 0);
|
||||
});
|
||||
|
||||
$('#passman_sharing_enabled').change(function () {
|
||||
settings.setAdminKey('user_sharing_enabled', ($(this).is(":checked")) ? 1 : 0);
|
||||
});
|
||||
|
||||
$('#passman_link_sharing_enabled').change(function () {
|
||||
settings.setAdminKey('link_sharing_enabled', ($(this).is(":checked")) ? 1 : 0);
|
||||
});
|
||||
|
||||
});
|
File diff suppressed because one or more lines are too long
|
@ -26,7 +26,7 @@
|
|||
scope.matchBreakdown = false;
|
||||
scope.toggleScore = function () {
|
||||
scope.scoreShown = !scope.scoreShown;
|
||||
}
|
||||
};
|
||||
jQuery('.match-sequence').hide();
|
||||
scope.toggleMatchBreakdown = function () {
|
||||
scope.matchBreakdown = true;
|
||||
|
|
|
@ -36,6 +36,7 @@ use OCA\Passman\Service\FileService;
|
|||
use OCA\Passman\Service\VaultService;
|
||||
use OCA\Passman\Utility\Utils;
|
||||
use OCA\Passman\Service\NotificationService;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
use OCP\AppFramework\App;
|
||||
|
@ -70,7 +71,8 @@ class Application extends App {
|
|||
$c->query('ShareService'),
|
||||
$c->query('CredentialService'),
|
||||
$c->query('NotificationService'),
|
||||
$c->query('FileService')
|
||||
$c->query('FileService'),
|
||||
$c->query('IConfig')
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -109,6 +111,7 @@ class Application extends App {
|
|||
$container->registerAlias('ShareService', ShareService::class);
|
||||
$container->registerAlias('Utils', Utils::class);
|
||||
$container->registerAlias('IDBConnection', IDBConnection::class);
|
||||
$container->registerAlias('IConfig', IConfig::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
70
lib/Settings/Admin.php
Normal file
70
lib/Settings/Admin.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
* @copyright Copyright (c) 2016, Sander Brand (brantje@gmail.com)
|
||||
* @copyright Copyright (c) 2016, Marcos Zuriaga Miguel (wolfi@wolfi.es)
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Passman\Settings;
|
||||
|
||||
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\IL10N;
|
||||
use OCP\Settings\ISettings;
|
||||
|
||||
class Admin implements ISettings {
|
||||
|
||||
private $config;
|
||||
private $l;
|
||||
|
||||
public function __construct(
|
||||
IConfig $config,
|
||||
IL10N $l) {
|
||||
$this->config = $config;
|
||||
$this->l = $l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function getForm() {
|
||||
|
||||
return new TemplateResponse('passman', 'settings-admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the section ID, e.g. 'sharing'
|
||||
*/
|
||||
public function getSection() {
|
||||
return 'additional';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int whether the form should be rather on the top or bottom of
|
||||
* the admin section. The forms are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
*
|
||||
* E.g.: 70
|
||||
*/
|
||||
public function getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
103
templates/settings-admin.php
Normal file
103
templates/settings-admin.php
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
/** @var \OCP\IL10N $l */
|
||||
/** @var array $_ */
|
||||
use \OCP\App;
|
||||
|
||||
script('passman', 'settings-admin');
|
||||
|
||||
$checkVersion = OC::$server->getConfig()->getAppValue('passman', 'check_version', '1') === '1';
|
||||
$AppInstance = new App();
|
||||
$localVersion = $AppInstance->getAppInfo("passman")["version"];
|
||||
if ($checkVersion) {
|
||||
// get latest master version
|
||||
$doc = new DOMDocument();
|
||||
$doc->load('https://raw.githubusercontent.com/nextcloud/passman/master/appinfo/info.xml');
|
||||
$root = $doc->getElementsByTagName("info");
|
||||
$version = false;
|
||||
$githubVersion = $l->t('Unable to get version info');
|
||||
foreach ($root as $element) {
|
||||
$versions = $element->getElementsByTagName("version");
|
||||
$version = $versions->item(0)->nodeValue;
|
||||
}
|
||||
if ($version) {
|
||||
$githubVersion = $version;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div id="passwordSharingSettings" class="followupsection">
|
||||
<form name="passman_settings">
|
||||
<h2><?php p($l->t('Passman Settings')); ?></h2>
|
||||
<?php
|
||||
if ($checkVersion) {
|
||||
p($l->t('Github version:'). ' '. $githubVersion);
|
||||
print '<br />';
|
||||
} ?>
|
||||
Local version: <?php p($localVersion); ?><br/>
|
||||
<?php
|
||||
if (version_compare($githubVersion, $localVersion) === 1) {
|
||||
p($l->t('A newer version of passman is available'));
|
||||
}
|
||||
?>
|
||||
<h3><?php p($l->t('Sharing')); ?></h3>
|
||||
<p>
|
||||
<input type="checkbox" name="passman_link_sharing_enabled"
|
||||
id="passman_link_sharing_enabled" class="checkbox"
|
||||
value="1"/>
|
||||
<label for="passman_link_sharing_enabled">
|
||||
<?php p($l->t('Allow users on this server to share passwords with a link')); ?>
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input type="checkbox" name="passman_sharing_enabled"
|
||||
id="passman_sharing_enabled" class="checkbox"
|
||||
value="1" <?php if ($_['user_sharing_enabled']) print_unescaped('checked="checked"'); ?> />
|
||||
<label for="passman_sharing_enabled">
|
||||
<?php p($l->t('Allow users on this server to share passwords with other users')); ?>
|
||||
</label>
|
||||
</p>
|
||||
<h3><?php p($l->t('General')); ?></h3>
|
||||
<p>
|
||||
<input type="checkbox" name="check_version"
|
||||
id="passman_check_version" class="checkbox"
|
||||
value="0"/>
|
||||
<label for="passman_check_version">
|
||||
<?php p($l->t('Check for new versions')); ?>
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<input type="checkbox" name="https_check"
|
||||
id="passman_https_check" class="checkbox"
|
||||
value="0"/>
|
||||
<label for="passman_https_check">
|
||||
<?php p($l->t('Enable HTTPS check')); ?>
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<input type="checkbox" name="disable_contextmenu"
|
||||
id="passman_disable_contextmenu" class="checkbox"
|
||||
value="0"/>
|
||||
<label for="passman_disable_contextmenu">
|
||||
<?php p($l->t('Disable context menu')); ?>
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label for="vault_key_strength">Minimum vault key strength:</label>
|
||||
<select name="vault_key_strength" id="vault_key_strength">
|
||||
<option value="1" <?php if ($_['vault_key_strength'] === 1) print_unescaped('selected="selected"'); ?>>
|
||||
Poor
|
||||
</option>
|
||||
<option value="2" <?php if ($_['vault_key_strength'] === 2) print_unescaped('selected="selected"'); ?>>
|
||||
Weak
|
||||
</option>
|
||||
<option value="3" <?php if ($_['vault_key_strength'] === 3) print_unescaped('selected="selected"'); ?>>
|
||||
Good
|
||||
</option>
|
||||
<option value="4" <?php if ($_['vault_key_strength'] === 4) print_unescaped('selected="selected"'); ?>>
|
||||
Strong
|
||||
</option>
|
||||
</select>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
</ul>
|
||||
|
||||
<div class="tab_container share_credential">
|
||||
<div class="tab_container share_credential" ng-show="currentTab">
|
||||
<div ng-include="currentTab.url"></div>
|
||||
|
||||
<button ng-click="applyShare()">{{ 'share' | translate}}</button>
|
||||
|
|
|
@ -195,7 +195,8 @@
|
|||
</button>
|
||||
<button class="button"
|
||||
ng-click="shareCredential(selectedCredential)"
|
||||
ng-if="selectedCredential.delete_time == 0 && selectedCredential.acl === undefined">
|
||||
ng-if="selectedCredential.delete_time == 0 && selectedCredential.acl === undefined &&
|
||||
(settings.user_sharing_enabled === 1 || settings.user_sharing_enabled === '1' || settings.link_sharing_enabled === 1 || settings.link_sharing_enabled === '1')">
|
||||
<span class="fa fa-share"></span> {{ 'share' | translate}}
|
||||
</button>
|
||||
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
{{ 'new.vault.passr' | translate}}
|
||||
<input type="password" ng-model="vault_key2" required>
|
||||
</div>
|
||||
<div ng-show="error || vault_key_score.score < 2" class="error">
|
||||
<div ng-show="error || vault_key_score.score < minimal_value_key_strength" class="error">
|
||||
<ul>
|
||||
<li ng-show="error">{{error}}</li>
|
||||
<li ng-show="vault_key_score.score < 2">{{'min.vault.key.strength' | translate:'{strength:"weak"}'}}</li>
|
||||
<li ng-show="vault_key_score.score < minimal_value_key_strength">{{'min.vault.key.strength' | translate:required_score}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -55,7 +55,7 @@
|
|||
</div>
|
||||
<div class="button_wrapper">
|
||||
<button class="button button-geen" ng-if="!creating_keys"
|
||||
ng-click="createVault(vault_name, vault_key, vault_key2)" ng-disabled="vault_key_score.score < 2 || vault_key !== vault_key2 || vault_key === ''">
|
||||
ng-click="createVault(vault_name, vault_key, vault_key2)" ng-disabled="vault_key_score.score < minimal_value_key_strength || vault_key !== vault_key2 || vault_key === ''">
|
||||
{{ 'new.vault.create' | translate }}
|
||||
</button>
|
||||
<div class="button" ng-if="creating_keys">
|
||||
|
|
|
@ -41,11 +41,12 @@ class InternalControllerTest extends PHPUnit_Framework_TestCase {
|
|||
|
||||
public function setUp() {
|
||||
$request = $this->getMockBuilder('OCP\IRequest')->getMock();
|
||||
$config = $this->getMockBuilder('OCP\IConfig')->getMock();
|
||||
$this->credentialService = $this->getMockBuilder('OCA\Passman\Service\CredentialService')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->controller = new InternalController(
|
||||
'passman', $request, $this->userId, $this->credentialService
|
||||
'passman', $request, $this->userId, $this->credentialService, $config
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue