js: Configuration and Error handling
[gpgme.git] / lang / js / src / Keyring.js
1 /* gpgme.js - Javascript integration for gpgme
2  * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
3  *
4  * This file is part of GPGME.
5  *
6  * GPGME is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * GPGME is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  * SPDX-License-Identifier: LGPL-2.1+
19  */
20
21 import {GPGME_Message} from './Message'
22 import {GPGME_Key} from './Key'
23 import { isFingerprint, isLongId } from './Helpers';
24 import { gpgme_error } from './Errors';
25
26 export class GPGME_Keyring {
27     constructor(connection){
28         this.connection = connection;
29     }
30
31     set connection(connection){
32         if (!this._connection && connection instanceof Connection){
33             this._connection = connection;
34         }
35     }
36     get connection(){
37         if (this._connection instanceof Connection){
38             if (this._connection.isConnected){
39                 return this._connection;
40             }
41             return gpgme_error('CONN_DISCONNECTED');
42         }
43         return gpgme_error('CONN_NO_CONNECT');
44     }
45
46     /**
47      * @param {String} (optional) pattern A pattern to search for, in userIds or KeyIds
48      * @param {Boolean} (optional) Include listing of secret keys
49      * @returns {Promise.<Array<GPGME_Key>>}
50      *
51      */
52     getKeys(pattern, include_secret){
53         let msg = new GPGME_Message('listkeys');
54         if (pattern && typeof(pattern) === 'string'){
55             msg.setParameter('pattern', pattern);
56         }
57         if (include_secret){
58             msg.setParameter('with-secret', true);
59         }
60
61         this.connection.post(msg).then(function(result){
62             let fpr_list = [];
63             let resultset = [];
64             if (!Array.isArray(result.keys)){
65             //TODO check assumption keys = Array<String fingerprints>
66                 fpr_list = [result.keys];
67             } else {
68                 fpr_list = result.keys;
69             }
70             for (let i=0; i < fpr_list.length; i++){
71                 let newKey = new GPGME_Key(fpr_list[i]);
72                 if (newKey instanceof GPGME_Key){
73                     resultset.push(newKey);
74                 }
75             }
76             return Promise.resolve(resultset);
77         });
78     }
79
80     /**
81      * @param {Object} flags subset filter expecting at least one of the
82      * filters described below. True will filter on the condition, False will
83      * reverse the filter, if not present or undefined, the filter will not be
84      * considered. Please note that some combination may not make sense
85      * @param {Boolean} flags.secret Only Keys containing a secret part.
86      * @param {Boolean} flags.revoked revoked Keys only
87      * @param {Boolean} flags.expired Expired Keys only
88      * @param {String} (optional) pattern A pattern to search for, in userIds or KeyIds
89      * @returns {Promise Array<GPGME_Key>}
90      *
91      */
92     getSubset(flags, pattern){
93         if (flags === undefined) {
94             throw('ERR_WRONG_PARAM');
95         };
96         let secretflag = false;
97         if (flags.hasOwnProperty(secret) && flags.secret){
98             secretflag = true;
99         }
100         this.getKeys(pattern, secretflag).then(function(queryset){
101             let resultset = [];
102             for (let i=0; i < queryset.length; i++ ){
103                 let conditions = [];
104                 let anticonditions = [];
105                 if (secretflag === true){
106                     conditions.push('hasSecret');
107                 } else if (secretflag === false){
108                     anticonditions.push('hasSecret');
109                 }
110                 /**
111                 if (flags.defaultKey === true){
112                     conditions.push('isDefault');
113                 } else if (flags.defaultKey === false){
114                     anticonditions.push('isDefault');
115                 }
116                 */
117                 /**
118                  * if (flags.valid === true){
119                     anticonditions.push('isInvalid');
120                 } else if (flags.valid === false){
121                     conditions.push('isInvalid');
122                 }
123                 */
124                 if (flags.revoked === true){
125                     conditions.push('isRevoked');
126                 } else if (flags.revoked === false){
127                     anticonditions.push('isRevoked');
128                 }
129                 if (flags.expired === true){
130                     conditions.push('isExpired');
131                 } else if (flags.expired === false){
132                     anticonditions.push('isExpired');
133                 }
134                 let decision = undefined;
135                 for (let con = 0; con < conditions.length; con ++){
136                     if (queryset[i][conditions[con]] !== true){
137                         decision = false;
138                     }
139                 }
140                 for (let acon = 0; acon < anticonditions.length; acon ++){
141                     if (queryset[i][anticonditions[acon]] === true){
142                         decision = false;
143                     }
144                 }
145                 if (decision !== false){
146                     resultset.push(queryset[i]);
147                 }
148             }
149             return Promise.resolve(resultset);
150         });
151     }
152
153 };