Completed
Push — master ( 3d31b2...c9ad65 )
by Sander
8s
created

angular.controller(ꞌShareCtrlꞌ)   F

Complexity

Conditions 9
Paths 1152

Size

Total Lines 379

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
dl 0
loc 379
rs 3.1304
c 3
b 0
f 0
cc 9
nc 1152
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('user_sharing_enabled')){
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 ($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
					ShareService.unshareCredential(credential);
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
248
					_credential = CredentialService.encryptCredential(_credential, old_key);
249
					CredentialService.updateCredential(_credential, true).then(function () {
250
						NotificationService.showNotification($translate.instant('credential.unshared'), 4000);
251
						CredentialService.reencryptCredential(_credential.guid, old_key, new_key).then(function () {
252
							getAcl();
253
						});
254
					});
255
				};
256
257
				/**
258
				 * Apply a share to a new user
259
				 * @param user A user object to who we should share the data
260
				 * @param enc_key The shared key we are going to ecnrypt with his public rsa key
261
				 */
262
				$scope.applyShareToUser = function (user, enc_key) {
263
					ShareService.getVaultsByUser(user.userId).then(function (data) {
264
						$scope.share_settings.cypher_progress.total += data.length;
265
266
						user.vaults = data;
267
						var start = new Date().getTime() / 1000;
268
						ShareService.cypherRSAStringWithPublicKeyBulkAsync(user.vaults, enc_key)
269
							.progress(function () {
270
								$scope.share_settings.cypher_progress.done++;
271
								$scope.share_settings.cypher_progress.percent = $scope.share_settings.cypher_progress.done / $scope.share_settings.cypher_progress.total * 100;
272
								$scope.$digest();
273
							})
274
							.then(function (result) {
275
																$scope.share_settings.cypher_progress.times.push({
276
									time: ((new Date().getTime() / 1000) - start),
277
									user: data[0].user_id
278
								});
279
								user.vaults = result;
280
								if (!user.hasOwnProperty('acl_id')) {
281
									$scope.uploadChanges(user);
282
								}
283
								$scope.$digest();
284
							});
285
					});
286
				};
287
288
289
290
				$scope.$on("$locationChangeStart", function(event) {
291
					if(!$scope.sharing_complete){
292
						if(!confirm($translate.instant('share.navigate.away.warning'))){
293
							event.preventDefault();
294
						}
295
					}
296
				});
297
298
				var getShareLink = function(hash){
299
					var port;
300
					var defaultPort = ($location.$$protocol === 'http') ? 80 : 443;
301
					port = (defaultPort !== $location.$$port) ? ':'+ $location.$$port : '';
302
					return $location.$$protocol + '://' + $location.$$host + port + OC.generateUrl('apps/passman/share/public#') + hash;
303
				};
304
305
				$scope.sharing_complete = true;
306
				$scope.applyShare = function () {
307
					$scope.sharing_complete = false;
308
					$scope.share_settings.cypher_progress.percent = 0;
309
					$scope.share_settings.cypher_progress.done = 0;
310
					$scope.share_settings.cypher_progress.total = 0;
311
					$scope.share_settings.cypher_progress.times = [];
312
					$scope.share_settings.cypher_progress.times_total = [];
313
					$scope.share_settings.upload_progress.done = 0;
314
					$scope.share_settings.upload_progress.total = 0;
315
					//Credential is already shared
316
					if ($scope.storedCredential.shared_key && $scope.storedCredential.shared_key !== '' && $scope.storedCredential.shared_key !== null) {
317
												var enc_key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
318
						if ($scope.share_settings.linkSharing.enabled) {
319
							var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
320
							var shareObj = {
321
								item_id: $scope.storedCredential.credential_id,
322
								item_guid: $scope.storedCredential.guid,
323
								permissions: $scope.share_settings.linkSharing.settings.acl.getAccessLevel(),
324
								expire_timestamp: expire_time,
325
								expire_views: $scope.share_settings.linkSharing.settings.expire_views
326
							};
327
							ShareService.createPublicSharedCredential(shareObj).then(function () {
328
								var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key);
329
								$scope.share_link = getShareLink(hash);
330
							});
331
						}
332
333
						var list = $scope.share_settings.credentialSharedWithUserAndGroup;
334
335
						for (var i = 0; i < list.length; i++) {
336
							var iterator = i;
337
							var target_user = list[i];
338
							if (target_user.hasOwnProperty('created')) {
339
								var acl = {
340
									user_id: target_user.userId,
341
									permission: target_user.acl.getAccessLevel()
342
								};
343
								ShareService.updateCredentialAcl($scope.storedCredential, acl);
344
							} else {
345
								$scope.applyShareToUser(list[iterator], enc_key);
346
							}
347
						}
348
						NotificationService.showNotification($translate.instant('saved'), 4000);
349
						$scope.sharing_complete = true;
350
					} else {
351
352
						ShareService.generateSharedKey(20).then(function (key) {
353
354
							var encryptedSharedCredential = angular.copy($scope.storedCredential);
355
							var old_key = VaultService.getActiveVault().vaultKey;
356
357
							CredentialService.reencryptCredential(encryptedSharedCredential.guid, old_key, key).progress(function () {
358
															}).then(function (data) {
359
								var _credential = data.cryptogram;
360
								_credential.set_share_key = true;
361
								_credential.skip_revision = true;
362
								_credential.shared_key = EncryptService.encryptString(key);
363
								CredentialService.updateCredential(_credential, true).then(function () {
364
									NotificationService.showNotification($translate.instant('credential.shared'), 4000);
365
									$scope.sharing_complete = true;
366
								});
367
							});
368
369
							var list = $scope.share_settings.credentialSharedWithUserAndGroup;
370
							for (var i = 0; i < list.length; i++) {
371
								if (list[i].type === "user") {
372
									$scope.applyShareToUser(list[i], key);
373
								}
374
							}
375
376
							if ($scope.share_settings.linkSharing.enabled) {
377
								var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
378
								var shareObj = {
379
									item_id: $scope.storedCredential.credential_id,
380
									item_guid: $scope.storedCredential.guid,
381
									permissions: $scope.share_settings.linkSharing.settings.acl.getAccessLevel(),
382
									expire_timestamp: expire_time,
383
									expire_views: $scope.share_settings.linkSharing.settings.expire_views
384
								};
385
								ShareService.createPublicSharedCredential(shareObj).then(function () {
386
									var hash = window.btoa($scope.storedCredential.guid + '<::>' + key);
387
									$scope.share_link = getShareLink(hash);
388
								});
389
							}
390
391
						});
392
					}
393
				};
394
395
				$scope.uploadChanges = function (user) {
396
					$scope.share_settings.upload_progress.total++;
397
398
					user.accessLevel = angular.copy(user.acl.getAccessLevel());
399
					ShareService.shareWithUser(storedCredential, user)
400
						.then(function () {
401
							$scope.share_settings.upload_progress.done++;
402
							$scope.share_settings.upload_progress.percent = $scope.share_settings.upload_progress.done / $scope.share_settings.upload_progress.total * 100;
403
						});
404
				};
405
406
				$scope.calculate_total_time = function () {
407
					$scope.share_settings.cypher_progress.times = $scope.share_settings.cypher_progress.times || [];
408
					var total = 0;
409
					for (var i = 0; i < $scope.share_settings.cypher_progress.times.length; i++) {
410
						total += $scope.share_settings.cypher_progress.times[i].time;
411
					}
412
					return total;
413
				};
414
			}]);
415
}());
416