Completed
Push — master ( 641a91...fc9f6a )
by
unknown
10:16
created

angular.controller(ꞌShareCtrlꞌ)   D

Complexity

Conditions 9
Paths 2304

Size

Total Lines 386

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
dl 0
loc 386
rs 4.6666
c 0
b 0
f 0
nc 2304
nop 12

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
/**
2
 * Nextcloud - passman
3
 *
4
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
5
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
(function () {
24
	'use strict';
25
26
	/**
27
	 * @ngdoc function
28
	 * @name passmanApp.controller:MainCtrl
29
	 * @description
30
	 * # MainCtrl
31
	 * Controller of the passmanApp
32
	 * This file is part of passman, licensed under AGPLv3
33
	 */
34
	angular.module('passmanApp')
35
		.controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL', 'EncryptService', '$translate', '$rootScope',
36
			function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService, $translate, $rootScope) {
37
				$scope.active_vault = VaultService.getActiveVault();
38
39
40
41
42
				$scope.tabs = [{
43
					title: $translate.instant('share.u.g'),
44
					url: 'views/partials/forms/share_credential/basics.html'
45
				}, {
46
					title: $translate.instant('share.link'),
47
					url: 'views/partials/forms/share_credential/link_sharing.html',
48
					color: 'green'
49
				}];
50
51
				$scope.currentTab = $scope.tabs[0];
52
53
54
				var settingsLoaded = function () {
55
					var settings = SettingsService.getSettings();
56
					if(settings.user_sharing_enabled === 0 || settings.user_sharing_enabled ==='0'){
57
						$scope.tabs.splice(0,1);
58
					}
59
					if(settings.link_sharing_enabled === 0 || settings.link_sharing_enabled ==='0'){
60
						$scope.tabs.splice(1,1);
61
					}
62
					if($scope.tabs.length > 0){
63
						$scope.currentTab = $scope.tabs[0];
64
					}
65
				};
66
67
				if(!SettingsService.getSetting('settings_loaded')){
68
					$rootScope.$on('settings_loaded', function () {
69
						settingsLoaded();
70
					});
71
				} else {
72
					settingsLoaded();
73
				}
74
75
				$scope.onClickTab = function (tab) {
76
					$scope.currentTab = tab;
77
				};
78
79
				$scope.isActiveTab = function (tab) {
80
					return tab.url === $scope.currentTab.url;
81
				};
82
83
				if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
84
					if (!$scope.active_vault) {
85
						$location.path('/');
86
					}
87
				} else {
88
					if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
89
						var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
90
						_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
91
						VaultService.setActiveVault(_vault);
92
						$scope.active_vault = _vault;
93
94
					}
95
				}
96
				var storedCredential = SettingsService.getSetting('share_credential');
97
98
				if (!storedCredential) {
99
					$location.path('/vault/' + $routeParams.vault_id);
100
				} else {
101
					$scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential));
102
				}
103
104
				if ($scope.active_vault) {
105
					$scope.$parent.selectedVault = true;
106
				}
107
				$scope.cancel = function () {
108
					SettingsService.setSetting('share_credential', null);
109
					$location.path('/vault/' + $routeParams.vault_id);
110
				};
111
112
113
				$scope.default_permissions = new SharingACL(0);
114
				$scope.default_permissions.addPermission(
115
					$scope.default_permissions.permissions.READ |
116
					$scope.default_permissions.permissions.WRITE |
117
					$scope.default_permissions.permissions.FILES
118
				);
119
120
				var link_acl = angular.copy($scope.default_permissions);
121
				link_acl.removePermission($scope.default_permissions.permissions.WRITE);
122
				var oneMonthLater = new Date();
123
				oneMonthLater.setMonth(oneMonthLater.getMonth() + 1);
124
				$scope.share_settings = {
125
					linkSharing: {
126
						enabled: false,
127
						settings: {
128
							expire_time: oneMonthLater,
129
							expire_views: 5,
130
							acl: link_acl
131
						}
132
					},
133
					credentialSharedWithUserAndGroup: [],
134
					cypher_progress: {
135
						done: 0,
136
						total: 0
137
					},
138
					upload_progress: {
139
						done: 0,
140
						total: 0
141
					}
142
				};
143
144
				var getAcl = function () {
145
					ShareService.getSharedCredentialACL($scope.storedCredential).then(function (aclList) {
146
						var _list = [];
147
						var enc_key = ($scope.storedCredential.shared_key) ? EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key)) : false;
148
						for (var i = 0; i < aclList.length; i++) {
149
							var acl = aclList[i];
150
							if (acl.user_id === null) {
151
								$scope.share_settings.linkSharing = {
152
									enabled: true,
153
									settings: {
154
										expire_time: new Date(acl.expire * 1000),
155
										expire_views: acl.expire_views,
156
										acl: new SharingACL(acl.permissions)
157
									}
158
								};
159
								if (enc_key) {
160
									var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key);
161
									$scope.share_link = getShareLink(hash);
162
								}
163
							} else {
164
								var obj = {
165
									userId: acl.user_id,
166
									displayName: acl.user_id,
167
									type: 'user',
168
									acl: new SharingACL(acl.permissions),
169
									acl_id: acl.acl_id,
170
									pending: acl.pending,
171
									credential_guid: acl.item_guid,
172
									created: acl.created
173
								};
174
175
								_list.push(obj);
176
							}
177
178
						}
179
						$scope.share_settings.credentialSharedWithUserAndGroup = _list;
180
					});
181
				};
182
				getAcl();
183
				var acl = new SharingACL(0);
184
185
186
				$scope.$watch('share_settings.upload_progress.done', function () {
187
										if ($scope.share_settings.upload_progress.done === $scope.share_settings.upload_progress.total && $scope.share_settings.upload_progress.total > 0) {
188
						getAcl();
189
					}
190
				});
191
192
				$scope.inputSharedWith = [];
193
194
				$scope.searchUsers = function ($query) {
195
					return ShareService.search($query);
196
				};
197
198
				$scope.hasPermission = function (acl, permission) {
199
					return acl.hasPermission(permission);
200
				};
201
202
				$scope.setPermission = function (acl, permission) {
203
					acl.togglePermission(permission);
204
				};
205
				$scope.shareWith = function (shareWith) {
206
					$scope.inputSharedWith = [];
207
					if (shareWith.length > 0) {
208
						for (var i = 0; i < shareWith.length; i++) {
209
							var obj = {
210
								userId: shareWith[i].uid,
211
								displayName: shareWith[i].text,
212
								type: shareWith[i].type,
213
								acl: angular.copy($scope.default_permissions),
214
								pending: true,
215
								credential_guid: $scope.storedCredential.guid
216
							};
217
							var found = false;
218
							for (var z = 0; z < $scope.share_settings.credentialSharedWithUserAndGroup.length; z++) {
219
								if (shareWith[z] && $scope.share_settings.credentialSharedWithUserAndGroup[z].userId === shareWith[z].uid) {
220
									found = true;
221
								}
222
							}
223
							if (found === false) {
224
								$scope.share_settings.credentialSharedWithUserAndGroup.push(obj);
225
							}
226
						}
227
					}
228
				};
229
230
				$scope.unshareUser = function (user) {
231
					ShareService.unshareCredentialFromUser($scope.storedCredential, user.userId).then(function (result) {
232
						if (result.result === true) {
233
							var idx = $scope.share_settings.credentialSharedWithUserAndGroup.indexOf(user);
234
							$scope.share_settings.credentialSharedWithUserAndGroup.splice(idx, 1);
235
						}
236
					});
237
				};
238
239
				$scope.unshareCredential = function (credential) {
240
241
					var _credential = angular.copy(credential);
242
					var old_key = EncryptService.decryptString(angular.copy(_credential.shared_key));
243
					var new_key = VaultService.getActiveVault().vaultKey;
244
					_credential.shared_key = null;
245
					_credential.unshare_action = true;
246
					_credential.skip_revision = true;
247
					CredentialService.reencryptCredential(_credential.guid, old_key, new_key, true).then(function (data) {
248
						getAcl();
249
						var c = data.cryptogram;
250
						c.shared_key = null;
251
						c.unshare_action = true;
252
						c.skip_revision = true;
253
						ShareService.unshareCredential(c);
254
						CredentialService.updateCredential(c, true).then(function () {
255
							NotificationService.showNotification($translate.instant('credential.unshared'), 4000);
256
							$scope.sharing_complete = true;
257
							$scope.storedCredential.shared_key = null;
258
							$scope.share_settings.credentialSharedWithUserAndGroup = [];
259
						});
260
					});
261
				};
262
263
				/**
264
				 * Apply a share to a new user
265
				 * @param user A user object to who we should share the data
266
				 * @param enc_key The shared key we are going to ecnrypt with his public rsa key
267
				 */
268
				$scope.applyShareToUser = function (user, enc_key) {
269
					ShareService.getVaultsByUser(user.userId).then(function (data) {
270
						$scope.share_settings.cypher_progress.total += data.length;
271
272
						user.vaults = data;
273
						var start = new Date().getTime() / 1000;
274
						ShareService.cypherRSAStringWithPublicKeyBulkAsync(user.vaults, enc_key)
275
							.progress(function () {
276
								$scope.share_settings.cypher_progress.done++;
277
								$scope.share_settings.cypher_progress.percent = $scope.share_settings.cypher_progress.done / $scope.share_settings.cypher_progress.total * 100;
278
								$scope.$digest();
279
							})
280
							.then(function (result) {
281
																$scope.share_settings.cypher_progress.times.push({
282
									time: ((new Date().getTime() / 1000) - start),
283
									user: data[0].user_id
284
								});
285
								user.vaults = result;
286
								if (!user.hasOwnProperty('acl_id')) {
287
									$scope.uploadChanges(user);
288
								}
289
								$scope.$digest();
290
							});
291
					});
292
				};
293
294
295
296
				$scope.$on("$locationChangeStart", function(event) {
297
					if(!$scope.sharing_complete){
298
						if(!confirm($translate.instant('share.navigate.away.warning'))){
299
							event.preventDefault();
300
						}
301
					}
302
				});
303
304
				var getShareLink = function(hash){
305
					var port;
306
					var defaultPort = ($location.$$protocol === 'http') ? 80 : 443;
307
					port = (defaultPort !== $location.$$port) ? ':'+ $location.$$port : '';
308
					return $location.$$protocol + '://' + $location.$$host + port + OC.generateUrl('apps/passman/share/public#') + hash;
309
				};
310
311
				$scope.sharing_complete = true;
312
				$scope.applyShare = function () {
313
					$scope.sharing_complete = false;
314
					$scope.share_settings.cypher_progress.percent = 0;
315
					$scope.share_settings.cypher_progress.done = 0;
316
					$scope.share_settings.cypher_progress.total = 0;
317
					$scope.share_settings.cypher_progress.times = [];
318
					$scope.share_settings.cypher_progress.times_total = [];
319
					$scope.share_settings.upload_progress.done = 0;
320
					$scope.share_settings.upload_progress.total = 0;
321
					//Credential is already shared
322
					if ($scope.storedCredential.shared_key && $scope.storedCredential.shared_key !== '' && $scope.storedCredential.shared_key !== null) {
323
												var enc_key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
324
						if ($scope.share_settings.linkSharing.enabled) {
325
							var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
326
							var shareObj = {
327
								item_id: $scope.storedCredential.credential_id,
328
								item_guid: $scope.storedCredential.guid,
329
								permissions: $scope.share_settings.linkSharing.settings.acl.getAccessLevel(),
330
								expire_timestamp: expire_time,
331
								expire_views: $scope.share_settings.linkSharing.settings.expire_views
332
							};
333
							ShareService.createPublicSharedCredential(shareObj).then(function () {
334
								var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key);
335
								$scope.share_link = getShareLink(hash);
336
							});
337
						}
338
339
						var list = $scope.share_settings.credentialSharedWithUserAndGroup;
340
341
						for (var i = 0; i < list.length; i++) {
342
							var iterator = i;
343
							var target_user = list[i];
344
							if (target_user.hasOwnProperty('created')) {
345
								var acl = {
346
									user_id: target_user.userId,
347
									permission: target_user.acl.getAccessLevel()
348
								};
349
								ShareService.updateCredentialAcl($scope.storedCredential, acl);
350
							} else {
351
								$scope.applyShareToUser(list[iterator], enc_key);
352
							}
353
						}
354
						NotificationService.showNotification($translate.instant('saved'), 4000);
355
						$scope.sharing_complete = true;
356
					} else {
357
358
						ShareService.generateSharedKey(20).then(function (key) {
359
360
							var encryptedSharedCredential = angular.copy($scope.storedCredential);
361
							var old_key = VaultService.getActiveVault().vaultKey;
362
363
							CredentialService.reencryptCredential(encryptedSharedCredential.guid, old_key, key).progress(function () {
364
															}).then(function (data) {
365
								var _credential = data.cryptogram;
366
								_credential.set_share_key = true;
367
								_credential.skip_revision = true;
368
								_credential.shared_key = EncryptService.encryptString(key);
369
								CredentialService.updateCredential(_credential, true).then(function () {
370
									$scope.storedCredential.shared_key = _credential.shared_key;
371
									NotificationService.showNotification($translate.instant('credential.shared'), 4000);
372
									$scope.sharing_complete = true;
373
								});
374
							});
375
376
							var list = $scope.share_settings.credentialSharedWithUserAndGroup;
377
							for (var i = 0; i < list.length; i++) {
378
								if (list[i].type === "user") {
379
									$scope.applyShareToUser(list[i], key);
380
								}
381
							}
382
383
							if ($scope.share_settings.linkSharing.enabled) {
384
								var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
385
								var shareObj = {
386
									item_id: $scope.storedCredential.credential_id,
387
									item_guid: $scope.storedCredential.guid,
388
									permissions: $scope.share_settings.linkSharing.settings.acl.getAccessLevel(),
389
									expire_timestamp: expire_time,
390
									expire_views: $scope.share_settings.linkSharing.settings.expire_views
391
								};
392
								ShareService.createPublicSharedCredential(shareObj).then(function () {
393
									var hash = window.btoa($scope.storedCredential.guid + '<::>' + key);
394
									$scope.share_link = getShareLink(hash);
395
								});
396
							}
397
398
						});
399
					}
400
				};
401
402
				$scope.uploadChanges = function (user) {
403
					$scope.share_settings.upload_progress.total++;
404
405
					user.accessLevel = angular.copy(user.acl.getAccessLevel());
406
					ShareService.shareWithUser(storedCredential, user)
407
						.then(function () {
408
							$scope.share_settings.upload_progress.done++;
409
							$scope.share_settings.upload_progress.percent = $scope.share_settings.upload_progress.done / $scope.share_settings.upload_progress.total * 100;
410
						});
411
				};
412
413
				$scope.calculate_total_time = function () {
414
					$scope.share_settings.cypher_progress.times = $scope.share_settings.cypher_progress.times || [];
415
					var total = 0;
416
					for (var i = 0; i < $scope.share_settings.cypher_progress.times.length; i++) {
417
						total += $scope.share_settings.cypher_progress.times[i].time;
418
					}
419
					return total;
420
				};
421
			}]);
422
}());
423