js: changed Key class stub
authorMaximilian Krambach <maximilian.krambach@intevation.de>
Thu, 3 May 2018 12:12:10 +0000 (14:12 +0200)
committerMaximilian Krambach <maximilian.krambach@intevation.de>
Thu, 3 May 2018 12:12:10 +0000 (14:12 +0200)
--

* src/Key.js:
  A Key object cannot offer more than basic functionality outside a
  connection, so it now requires a connection to be present.

lang/js/src/Key.js
lang/js/src/Keyring.js
lang/js/src/gpgmejs_openpgpjs.js
lang/js/src/index.js
lang/js/test/inputvalues.js

index 30449d6..1e0d319 100644 (file)
@@ -30,11 +30,42 @@ import { isFingerprint } from './Helpers'
 import { gpgme_error } from './Errors'
 import { createMessage } from './Message';
 import { permittedOperations } from './permittedOperations';
+import { Connection } from './Connection';
+
+
+export function createKey(fingerprint, parent){
+    if (!isFingerprint(fingerprint)){
+        return gpgme_error('KEY_INVALID');
+    }
+    if ( parent instanceof Connection){
+        return new GPGME_Key(fingerprint, parent);
+    } else if ( parent.hasOwnProperty('connection') &&
+        parent.connection instanceof Connection){
+            return new GPGME_Key(fingerprint, parent.connection);
+    }
+}
 
 export class GPGME_Key {
 
-    constructor(fingerprint){
+    constructor(fingerprint, connection){
         this.fingerprint = fingerprint;
+        this.connection = connection;
+    }
+
+    set connection(conn){
+        if (this._connection instanceof Connection) {
+            gpgme_error('CONN_ALREADY_CONNECTED');
+        } else if (conn instanceof Connection ) {
+            this._connection = conn;
+        }
+    }
+
+    get connection(){
+        if (!this._connection instanceof Connection){
+            return gpgme_error('CONN_NO_CONNECT');
+        } else {
+            return this._connection;
+        }
     }
 
     set fingerprint(fpr){
@@ -51,55 +82,56 @@ export class GPGME_Key {
      * hasSecret returns true if a secret subkey is included in this Key
      */
     get hasSecret(){
-        return checkKey(this._fingerprint, 'secret');
+        return this.checkKey('secret');
     }
 
     get isRevoked(){
-        return checkKey(this._fingerprint, 'revoked');
+        return this.checkKey('revoked');
     }
 
     get isExpired(){
-        return checkKey(this._fingerprint, 'expired');
+        return this.checkKey('expired');
     }
 
     get isDisabled(){
-        return checkKey(this._fingerprint, 'disabled');
+        return this.checkKey('disabled');
     }
 
     get isInvalid(){
-        return checkKey(this._fingerprint, 'invalid');
+        return this.checkKey('invalid');
     }
 
     get canEncrypt(){
-        return checkKey(this._fingerprint, 'can_encrypt');
+        return this.checkKey('can_encrypt');
     }
 
     get canSign(){
-        return checkKey(this._fingerprint, 'can_sign');
+        return this.checkKey('can_sign');
     }
 
     get canCertify(){
-        return checkKey(this._fingerprint, 'can_certify');
+        return this.checkKey('can_certify');
     }
 
     get canAuthenticate(){
-        return checkKey(this._fingerprint, 'can_authenticate');
+        return this.checkKey('can_authenticate');
     }
 
     get isQualified(){
-        return checkKey(this._fingerprint, 'is_qualified');
+        return this.checkKey('is_qualified');
     }
 
     get armored(){
-        let me = this;
-        return new Promise(function(resolve, reject){
-            let conn = new Connection();
-            conn.setFlag('armor', true);
-            conn.post('export',{'fpr': me._fingerprint});
+        let msg = createMessage ('export_key');
+        msg.setParameter('armor', true);
+        if (msg instanceof Error){
+            return gpgme_error('INVALID_KEY');
+        }
+        this.connection.post(msg).then(function(result){
+            return result.data;
         });
         // TODO return value not yet checked. Should result in an armored block
         // in correct encoding
-        // TODO openpgpjs also returns secKey if private = true?
     }
 
     /**
@@ -114,21 +146,21 @@ export class GPGME_Key {
      * @returns {Array<GPGME_Key>}
      */
     get subkeys(){
-        return checkKey(this._fingerprint, 'subkeys').then(function(result){
+        return this.checkKey('subkeys').then(function(result){
             // TBD expecting a list of fingerprints
             if (!Array.isArray(result)){
                 result = [result];
             }
             let resultset = [];
             for (let i=0; i < result.length; i++){
-                let subkey = new GPGME_Key(result[i]);
+                let subkey = new GPGME_Key(result[i], this.connection);
                 if (subkey instanceof GPGME_Key){
                     resultset.push(subkey);
                 }
             }
             return Promise.resolve(resultset);
         }, function(error){
-            //TODO checkKey fails
+            //TODO this.checkKey fails
         });
     }
 
@@ -137,7 +169,7 @@ export class GPGME_Key {
      * @returns {Date|null} TBD
      */
     get timestamp(){
-        return checkKey(this._fingerprint, 'timestamp');
+        return this.checkKey('timestamp');
         //TODO GPGME: -1 if the timestamp is invalid, and 0 if it is not available.
     }
 
@@ -146,7 +178,7 @@ export class GPGME_Key {
      *  @returns {Date|null} TBD
      */
     get expires(){
-        return checkKey(this._fingerprint, 'expires');
+        return this.checkKey('expires');
         // TODO convert to Date; check for 0
     }
 
@@ -155,51 +187,47 @@ export class GPGME_Key {
      * @returns {String|Array<String>} The user ids associated with this key
      */
     get userIds(){
-        return checkKey(this._fingerprint, 'uids');
+        return this.checkKey('uids');
     }
 
     /**
      * @returns {String} The public key algorithm supported by this subkey
      */
     get pubkey_algo(){
-        return checkKey(this._fingerprint, 'pubkey_algo');
+        return this.checkKey('pubkey_algo');
     }
-};
 
-/**
- * generic function to query gnupg information on a key.
- * @param {*} fingerprint The identifier of the Keyring
- * @param {*} property The gpgme-json property to check
- *
- */
-function checkKey(fingerprint, property){
-    return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED'));
-    if (!property || !permittedOperations[keyinfo].hasOwnProperty(property)){
-            return Promise.reject(gpgme_error('PARAM_WRONG'));
-    }
-    return new Promise(function(resolve, reject){
-        if (!isFingerprint(fingerprint)){
-            reject(gpgme_error('KEY_INVALID'));
+    /**
+    * generic function to query gnupg information on a key.
+    * @param {*} property The gpgme-json property to check.
+    * TODO: check if Promise.then(return)
+    */
+    checkKey(property){
+        return gpgme_error('NOT_YET_IMPLEMENTED');
+        // TODO: async is not what is to be ecpected from Key information :(
+        if (!property || typeof(property) !== 'string' ||
+            !permittedOperations['keyinfo'].hasOwnProperty(property)){
+            return gpgme_error('PARAM_WRONG');
         }
         let msg = createMessage ('keyinfo');
         if (msg instanceof Error){
-            reject(gpgme_error('PARAM_WRONG'));
+            return gpgme_error('PARAM_WRONG');
         }
         msg.setParameter('fingerprint', this.fingerprint);
-        return (this.connection.post(msg)).then(function(result, error){
+        this.connection.post(msg).then(function(result, error){
             if (error){
-                reject(gpgme_error('GNUPG_ERROR',error.msg));
+                return gpgme_error('GNUPG_ERROR',error.msg);
             } else if (result.hasOwnProperty(property)){
-                resolve(result[property]);
+                return result[property];
             }
             else if (property == 'secret'){
-                    // TBD property undefined means "not true" in case of secret?
-                    resolve(false);
+                // TBD property undefined means "not true" in case of secret?
+                return false;
             } else {
-                reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
+                return gpgme_error('CONN_UNEXPECTED_ANSWER');
             }
         }, function(error){
-            //TODO error handling
+            return gpgme_error('GENERIC_ERROR');
         });
-    });
+    }
 };
\ No newline at end of file
index d1f4122..2cf87c2 100644 (file)
@@ -61,6 +61,7 @@ export class GPGME_Keyring {
         if (include_secret){
             msg.setParameter('with-secret', true);
         }
+        let me = this;
 
         this.connection.post(msg).then(function(result){
             let fpr_list = [];
@@ -72,7 +73,7 @@ export class GPGME_Keyring {
                 fpr_list = result.keys;
             }
             for (let i=0; i < fpr_list.length; i++){
-                let newKey = new GPGME_Key(fpr_list[i]);
+                let newKey = new GPGME_Key(fpr_list[i], me._connection);
                 if (newKey instanceof GPGME_Key){
                     resultset.push(newKey);
                 }
index c80d5a8..b233f0f 100644 (file)
 
  import { GpgME } from "./gpgmejs";
  import {GPGME_Keyring}  from "./Keyring"
- import { GPGME_Key } from "./Key";
+ import { GPGME_Key, createKey } from "./Key";
  import { isFingerprint } from "./Helpers"
  import { gpgme_error } from "./Errors"
+import { Connection } from "./Connection";
 
 
  export class GpgME_openpgpmode {
@@ -47,7 +48,7 @@
     initGpgME(connection, config = {}){
         if (connection && typeof(config) ==='object'){
             this._config = config;
-            if (!this._GPGME){
+            if (!this._GpgME){
                 this._GpgME = new GpgME(connection, config);
             }
             if (!this._keyring){
@@ -223,7 +224,7 @@ class GPGME_Keyring_openpgpmode {
         if ( !key.fingerprint || ! isFingerprint(key.fingerprint)){
             return Promise.reject(gpgme_error('PARAM_WRONG'));
         }
-        let key_to_delete = new GPGME_Key(key.fingerprint);
+        let key_to_delete = createKey(key.fingerprint, this._gpgme_keyring_GpgME);
         return key_to_delete.deleteKey(key.secret);
     }
 }
@@ -233,15 +234,22 @@ class GPGME_Keyring_openpgpmode {
  * Offers the Key information as the openpgpmode wants
  */
 class GPGME_Key_openpgpmode {
-    constructor(value){
-        this.init = value;
+    constructor(value, connection){
+        this.init(value, connection);
     }
 
-    set init (value){
+    /**
+     * Can be either constructed using an existing GPGME_Key, or a fingerprint
+     * and a connection
+     * @param {String|GPGME_Key} value
+     * @param {Connection} connection
+     */
+    init (value, connection){
         if (!this._GPGME_Key && value instanceof GPGME_Key){
             this._GPGME_Key = value;
-        } else if (!this._GPGME_Key && isFingerprint(value)){
-            this._GPGME_Key = new GPGME_Key(value);
+        } else if (!this._GPGME_Key && isFingerprint(value) &&
+            connection instanceof Connection){
+            this._GPGME_Key = createKey(value, connection);
         }
     }
 
@@ -264,6 +272,8 @@ class GPGME_Key_openpgpmode {
 
 /**
  * creates GPGME_Key_openpgpmode from GPGME_Keys
+ * @param {GPGME_Key|Array<GPGME_Key>} input keys
+ * @returns {Array<GPGME_Key_openpgpmode>}
  */
 function translateKeys(input){
     if (!input){
index 90fe99e..fc406c6 100644 (file)
@@ -36,9 +36,12 @@ function init(config){
     return new Promise(function(resolve, reject){
         let connection = new Connection;
         // TODO: Delayed reaction is ugly. We need to listen to the port's
-        // event listener in isConnected, but this takes some time (<5ms) to
-        // disconnect if there is no successfull connection.
+        // event listener in isConnected, but in some cases this takes some
+        // time (<5ms) to disconnect if there is no successfull connection.
         let delayedreaction = function(){
+            if (connection === undefined) {
+                reject(gpgme_error('CONN_NO_CONNECT'));
+            }
             if (connection.isConnected === true){
                 if (_conf.api_style && _conf.api_style === 'gpgme_openpgpjs'){
                     resolve(new GpgME_openpgpmode(connection, _conf));
index f6cd75a..7752b82 100644 (file)
@@ -1,12 +1,10 @@
-
-import {GPGME_Key} from "../src/Key"
+import { gpgme_error } from "../src/Errors";
 
 export const helper_params = {
     validLongId: '0A0A0A0A0A0A0A0A',
-    validGPGME_Key: new GPGME_Key('ADDBC303B6D31026F5EB4591A27EABDF283121BB'),
-    validKeys: [new GPGME_Key('A1E3BC45BDC8E87B74F4392D53B151A1368E50F3'),
+    validKeys: ['A1E3BC45BDC8E87B74F4392D53B151A1368E50F3',
         'ADDBC303B6D31026F5EB4591A27EABDF283121BB',
-        new GPGME_Key('EE17AEE730F88F1DE7713C54BBE0A4FF7851650A')],
+        'EE17AEE730F88F1DE7713C54BBE0A4FF7851650A'],
     validFingerprint: '9A9A7A7A8A9A9A7A7A8A9A9A7A7A8A9A9A7A7A8A',
     validFingerprints: ['9A9A7A7A8A9A9A7A7A8A9A9A7A7A8A9A9A7A7A8A',
         '9AAE7A338A9A9A7A7A8A9A9A7A7A8A9A9A7A7DDA'],
@@ -14,10 +12,10 @@ export const helper_params = {
     invalidFingerprint: [{hello:'World'}],
     invalidKeyArray: {curiosity:'uncat'},
     invalidKeyArray_OneBad: [
-        new GPGME_Key('12AE9F3E41B33BF77DF52B6BE8EE1992D7909B08'),
+        '12AE9F3E41B33BF77DF52B6BE8EE1992D7909B08',
         'E1D18E6E994FA9FE9360Bx0E687B940FEFEB095A',
         '3AEA7FE4F5F416ED18CEC63DD519450D9C0FAEE5'],
-    invalidErrorCode: 'Please type in all your passwords.'
+    invalidErrorCode: 'Please type in all your passwords.',
 }
 
 export const message_params = {
@@ -28,10 +26,12 @@ export const message_params = {
         valid_op: 'encrypt',
         invalid_param_names: [22,'dance', {}],
         validparam_name_0: 'mime',
-        invalid_values_0: [2134, 'All your passwords', new GPGME_Key('12AE9F3E41B33BF77DF52B6BE8EE1992D7909B08'), null]
+        invalid_values_0: [2134, 'All your passwords', gpgme_error('12AE9F3E41B33BF77DF52B6BE8EE1992D7909B08'), null]
     }
 }
-
+export const whatever_params = {
+    four_invalid_params: ['<(((-<', '>°;==;~~', '^^', '{{{{o}}}}']
+}
 
 export default {
     helper_params: helper_params,