From 9f5f00c91c7a85345870d0c26b8a0dc2ef143a75 Mon Sep 17 00:00:00 2001 From: brantje Date: Sun, 25 Sep 2016 00:01:23 +0200 Subject: [PATCH] Add reading keepass csv --- js/app/controllers/import.js | 39 +++++++++- js/app/controllers/settings.js | 20 ++--- js/importers/import-main.js | 77 +++++++++++++++++++ js/importers/importer-keepasscsv.js | 39 ++++++++++ js/templates.js | 4 +- templates/main.php | 3 +- .../forms/settings/general_settings.html | 4 +- .../views/partials/forms/settings/import.html | 13 +++- 8 files changed, 184 insertions(+), 15 deletions(-) create mode 100644 js/importers/import-main.js create mode 100644 js/importers/importer-keepasscsv.js diff --git a/js/app/controllers/import.js b/js/app/controllers/import.js index 2ac52a24..d30d829b 100644 --- a/js/app/controllers/import.js +++ b/js/app/controllers/import.js @@ -8,7 +8,44 @@ * Controller of the passmanApp */ angular.module('passmanApp') - .controller('ImportCtrl', ['$scope', function ($scope) { + .controller('ImportCtrl', ['$scope', '$window', function ($scope, $window) { + //@TODo read the available importers from $window.PassmanImporter + $scope.available_importers = [ + { + name: 'KeePass CSV', + value: 'keepassCsv' + }, + { + name: 'LastPass CSV', + value: 'lastpassCsv' + }, + { + name: 'Passman CSV', + value: 'passmanCsv' + }, + { + name: 'Passman JSON', + value: 'passmanJson' + } + ]; + var file_data; + $scope.fileLoaded = function (file) { + file_data = file.data.split(','); + file_data = decodeURIComponent(escape(window.atob( file_data[1] ))); //window.atob(); + }; + $scope.fileLoadError = function (file) { + console.error('Error loading file'); + }; + $scope.fileSelectProgress = function (progress) { + + }; + + $scope.startImport = function(importerType){ + if(file_data){ + var parsed_data = $window.PassmanImporter[importerType].readFile(file_data); + console.log('Data parsed!', parsed_data); + } + } }]); diff --git a/js/app/controllers/settings.js b/js/app/controllers/settings.js index 6d8cc8d7..be4de5e7 100644 --- a/js/app/controllers/settings.js +++ b/js/app/controllers/settings.js @@ -11,14 +11,16 @@ angular.module('passmanApp') .controller('SettingsCtrl', ['$scope', '$rootScope', 'SettingsService', 'VaultService', 'CredentialService', '$location', '$routeParams', '$http', function ($scope, $rootScope, SettingsService, VaultService, CredentialService, $location, $routeParams, $http) { - $scope.tabs = [{ - title: 'General settings', - url: 'views/partials/forms/settings/general_settings.html' - }, { - title: 'Password Tool', - url: 'views/partials/forms/settings/tool.html' + $scope.tabs = [ + { + title: 'General settings', + url: 'views/partials/forms/settings/general_settings.html' + }, + { + title: 'Password Tool', + url: 'views/partials/forms/settings/tool.html' - }, + }, { title: 'Import credentials', url: 'views/partials/forms/settings/import.html' @@ -30,7 +32,7 @@ angular.module('passmanApp') }]; - $scope.currentTab = $scope.tabs[0]; + $scope.currentTab = $scope.tabs[2]; $scope.onClickTab = function (tab) { $scope.currentTab = tab; @@ -42,7 +44,7 @@ angular.module('passmanApp') var getPassmanVersion = function () { var url = OC.generateUrl('apps/passman/api/internal/version'); - $http.get(url).then(function(result){ + $http.get(url).then(function (result) { $scope.passman_version = result.data.version; }) }; diff --git a/js/importers/import-main.js b/js/importers/import-main.js new file mode 100644 index 00000000..42dcafa6 --- /dev/null +++ b/js/importers/import-main.js @@ -0,0 +1,77 @@ +// Importers should always start with this +if(!window['PassmanImporter']){ + var PassmanImporter = {} +} + +PassmanImporter.parseRow_ = function(row, isHeading) { + // Strip leading quote. + row = row.trim(); + if (row.charAt(0) == '"') { + row = row.substring(1); + } + if (row.charAt(row.length - 2) == '"') { + row = row.substring(0, row.length - 2); + } + // Strip trailing quote. There seems to be a character between the last quote + // and the line ending, hence 2 instead of 1. + + row = row.split('","'); + return row; +}; + +PassmanImporter.toObject_ = function(headings, row) { + var result = {}; + for (var i = 0, ii = row.length; i < ii; i++) { + headings[i] = headings[i].replace(',','_') + .toLowerCase().replace(' ','_') + .replace('(','').replace(')','') + .replace('"',''); + result[headings[i]] = row[i]; + } + return result; +}; + +PassmanImporter.join_ = function(arr, sep) { + var parts = []; + for (var i = 0, ii = arr.length; i < ii; i++) { + arr[i] && parts.push(arr[i]); + } + return parts.join(sep); +}; + +PassmanImporter.newCredential = function () { + var credential = { + 'credential_id': null, + 'guid': null, + 'vault_id': null, + 'label': null, + 'description': null, + 'created': null, + 'changed': null, + 'tags': [], + 'email': null, + 'username': null, + 'password': null, + 'url': null, + 'favicon': null, + 'renew_interval': null, + 'expire_time': 0, + 'delete_time': 0, + 'files': [], + 'custom_fields': [], + 'otp': {}, + 'hidden': false + }; + return credential; +}; + +PassmanImporter.readCsv = function( csv ){ + var lines = []; + var rows = csv.split('\n'); + var headings = this.parseRow_(rows[0]); + for (var i = 1, row; row = rows[i]; i++) { + row = this.toObject_(headings, this.parseRow_(row)); + lines.push(row); + } + return lines; +}; \ No newline at end of file diff --git a/js/importers/importer-keepasscsv.js b/js/importers/importer-keepasscsv.js new file mode 100644 index 00000000..46220c3c --- /dev/null +++ b/js/importers/importer-keepasscsv.js @@ -0,0 +1,39 @@ +// Importers should always start with this +if (!window['PassmanImporter']) { + var PassmanImporter = {} +} +// Define the importer +PassmanImporter.keepassCsv = { + info: { + name: 'KeePass csv', + id: 'keepassCsv', + description: 'Create an csv export with the following options enabled: http://i.imgur.com/CaeTA4d.png' + } +}; + +PassmanImporter.keepassCsv.readFile = function (file_data) { + var parsed_csv = PassmanImporter.readCsv(file_data); + var credential_list = []; + for (var i = 0; i < parsed_csv.length; i++) { + var row = parsed_csv[i]; + var _credential = PassmanImporter.newCredential(); + _credential.label = row.account; + _credential.username = row.login_name; + _credential.password = row.password; + _credential.url = row.web_site; + if (row.hasOwnProperty('expires')) { + row.expires = row.expires.replace('"',''); + _credential.expire_time = new Date(row.expires).getTime() / 1000; + } + var tags = [{text: row.group}]; + if (row.hasOwnProperty('group_tree')) { + var exploded_tree = row.group_tree.split('\\\\'); + for (var t = 0; t < exploded_tree.length; t++) { + tags.push({text: exploded_tree[t]}); + } + } + _credential.tags = tags; + credential_list.push(_credential); + } + return credential_list; +}; \ No newline at end of file diff --git a/js/templates.js b/js/templates.js index 5a0fed58..aa8b34f3 100644 --- a/js/templates.js +++ b/js/templates.js @@ -51,13 +51,13 @@ angular.module('views/partials/forms/settings/export.html', []).run(['$templateC angular.module('views/partials/forms/settings/general_settings.html', []).run(['$templateCache', function($templateCache) { 'use strict'; $templateCache.put('views/partials/forms/settings/general_settings.html', - '

Change vault key

About passman

Version: {{passman_version}}
Bla bla about passman, our vision, and donate link.

'); + '

Change vault key

About passman

Version: {{passman_version}}
Bla bla about passman, changelog.
Donate to support development

'); }]); angular.module('views/partials/forms/settings/import.html', []).run(['$templateCache', function($templateCache) { 'use strict'; $templateCache.put('views/partials/forms/settings/import.html', - '
Import credentials
'); + '

'); }]); angular.module('views/partials/forms/settings/tool.html', []).run(['$templateCache', function($templateCache) { diff --git a/templates/main.php b/templates/main.php index 96dc1ef5..7d5eff7c 100644 --- a/templates/main.php +++ b/templates/main.php @@ -58,7 +58,8 @@ script('passman', 'app/directives/tooltip'); script('passman', 'app/directives/use-theme'); script('passman', 'app/directives/credentialfield'); script('passman', 'app/directives/ngenter'); - +script('passman', 'importers/import-main'); +script('passman', 'importers/importer-keepasscsv'); /* * Styles diff --git a/templates/views/partials/forms/settings/general_settings.html b/templates/views/partials/forms/settings/general_settings.html index fdf287c4..0c3556d5 100644 --- a/templates/views/partials/forms/settings/general_settings.html +++ b/templates/views/partials/forms/settings/general_settings.html @@ -15,7 +15,9 @@

About passman

Version: {{passman_version}}
- Bla bla about passman, our vision, and donate link. + Bla bla about passman, changelog. +
+ Donate to support development

\ No newline at end of file diff --git a/templates/views/partials/forms/settings/import.html b/templates/views/partials/forms/settings/import.html index 77aee5e3..0b20e4e6 100644 --- a/templates/views/partials/forms/settings/import.html +++ b/templates/views/partials/forms/settings/import.html @@ -1,3 +1,14 @@
- Import credentials +
+
+ +
+ +
+
\ No newline at end of file