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

js/app/controllers/share.js   B

Complexity

Conditions 1
Paths 9216

Size

Total Lines 400

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 400
rs 7
c 0
b 0
f 0
nc 9216
nop 0

1 Function

Rating   Name   Duplication   Size   Complexity  
D angular.controller(ꞌShareCtrlꞌ) 0 386 9

How to fix   Long Method   

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:

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