js: getDefaultKey and verify fix
authorMaximilian Krambach <maximilian.krambach@intevation.de>
Wed, 13 Jun 2018 13:22:03 +0000 (15:22 +0200)
committerMaximilian Krambach <maximilian.krambach@intevation.de>
Wed, 13 Jun 2018 13:22:03 +0000 (15:22 +0200)
--

* DemoExtension/maindemo.js - added a Demo for retrieving the default
  signing key

* src/Errors.js - add a new Error if no default key can be determined

* src/Key.js added documentation and a TODO marker for hasSecret.

* src/Keyring.js implemented getDefaultKey

* src/permittedOperations.js: Added missing entry for verify,
    added config_opt

lang/js/CHECKLIST
lang/js/DemoExtension/maindemo.js
lang/js/DemoExtension/mainui.html
lang/js/src/Errors.js
lang/js/src/Key.js
lang/js/src/Keyring.js
lang/js/src/permittedOperations.js

index fe26018..2e70dff 100644 (file)
@@ -13,10 +13,11 @@ receiving an answer
     [*] Key handling (import/export, modifying, status queries)
         [x] Import (not importing secret)
         [x] Export (not exporting secret)
-        [x] status queries
+        [*] status queries
+            [ ] getHasSecret
         [ ] key generation
         [ ] modification
-    [*] Configuration handling
+    [x] Configuration handling
     [ ] check for completeness
 
 Communication with other implementations
index 5cde1ce..67b811f 100644 (file)
@@ -36,7 +36,7 @@ document.addEventListener('DOMContentLoaded', function() {
                                 'answer').value = answer.data;
                         }
                     }, function(errormsg){
-                        alert( errormsg.code + ' ' + errormsg.msg);
+                        alert( errormsg.message);
                     });
             });
 
@@ -50,8 +50,18 @@ document.addEventListener('DOMContentLoaded', function() {
                                 'answer').value = answer.data;
                         }
                     }, function(errormsg){
-                        alert( errormsg.code + ' ' + errormsg.msg);
+                        alert(errormsg.message);
                     });
             });
+
+        document.getElementById('getdefaultkey').addEventListener('click',
+            function(){
+                gpgmejs.Keyring.getDefaultKey().then(function(answer){
+                    document.getElementById('defaultkey').innerHtml =
+                        answer.fingerprint;
+                }, function(errormsg){
+                    alert(errormsg.message);
+                });
+            });
     });
 });
index 76b8a22..91be7bb 100644 (file)
     <hr>
     <h3>Result data:</h3>
     <textarea id="answer" rows="5" cols="65" wrap="hard"></textarea>
+
+    <hr>
+    <ul>
+        <li>
+            <span class="label">Default Key:</span>
+            <button id="getdefaultkey">Get</button><br>
+            <span id="defaultkey"></span>
+        </li>
+
+
+    </ul>
     </body>
 </html>
index dabf6a5..73e7438 100644 (file)
@@ -78,6 +78,11 @@ const err_list = {
         msg:'This property has not been retrieved yet from GPG',
         type: 'error'
     },
+    'KEY_NO_DEFAULT': {
+        msg:'A default key could not be established. Please check yout gpg ' +
+            'configuration',
+        type: 'error'
+    },
     // generic
     'PARAM_WRONG':{
         msg: 'Invalid parameter was found',
index 5986254..3e4f1c7 100644 (file)
@@ -192,6 +192,7 @@ export class GPGME_Key {
      * Query the armored block of the non- secret parts of the Key directly
      * from gpg.
      * @returns {Promise<String>}
+     * @async
      */
     getArmor(){
         let me = this;
@@ -211,6 +212,13 @@ export class GPGME_Key {
         });
     }
 
+    /**
+     * Find out if the Key includes a secret part
+     * @returns {Promise<Boolean>}
+     *
+     * @async
+     */
+    // TODO: Does not work yet, result is always false
     getHasSecret(){
         let me = this;
         return new Promise(function(resolve, reject) {
index 0d4e3c5..e07a593 100644 (file)
@@ -99,7 +99,61 @@ export class GPGME_Keyring {
         });
     }
 
-    // getDefaultKey() Big TODO
+    /**
+     * Returns the Key to be used by default for signing operations,
+     * looking up the gpg configuration, or returning the first key that
+     * contains a secret key.
+     * @returns {Promise<GPGME_Key>}
+     *
+     * @async
+     * TODO: getHasSecret always returns false at this moment, so this fucntion
+     * still does not fully work as intended.
+     *
+     */
+    getDefaultKey() {
+        let me = this;
+        return new Promise(function(resolve, reject){
+            let msg = createMessage('config_opt');
+            msg.setParameter('component', 'gpg');
+            msg.setParameter('option', 'default-key');
+            msg.post().then(function(response){
+                if (response.value !== undefined
+                    && response.value.hasOwnProperty('string')
+                    && typeof(response.value.string) === 'string'
+                ){
+                    me.getKeys(response.value.string,true).then(function(keys){
+                        if(keys.length === 1){
+                            resolve(keys[0]);
+                        } else {
+                            reject(gpgme_error('KEY_NO_DEFAULT'));
+                        }
+                    }, function(error){
+                        reject(error);
+                    });
+                } else {
+                    // TODO: this is overly 'expensive' in communication
+                    // and probably performance, too
+                    me.getKeys(null,true).then(function(keys){
+                        for (let i=0; i < keys.length; i++){
+                            console.log(keys[i]);
+                            console.log(keys[i].get('hasSecret'));
+                            if (keys[i].get('hasSecret') === true){
+                                resolve(keys[i]);
+                                break;
+                            }
+                            if (i === keys.length -1){
+                                reject(gpgme_error('KEY_NO_DEFAULT'));
+                            }
+                        }
+                    }, function(error){
+                        reject(error);
+                    });
+                }
+            }, function(error){
+                reject(error);
+            });
+        });
+    }
 
     /**
      *
index 91612ad..044ae4a 100644 (file)
@@ -314,7 +314,7 @@ export const permittedOperations = {
     },
 
     createkey: {
-       pinentry: true,
+        pinentry: true,
         required: {
             userid: {
                 allowed: ['string']
@@ -332,7 +332,59 @@ export const permittedOperations = {
             type: [''],
             data: {'fingerprint': 'string'}
         }
+    },
+
+    verify: {
+        required: {
+            data: {
+                allowed: ['string']
+            }
+        },
+        optional: {
+            'protocol': {
+                allowed: ['string'],
+                allowed_data: ['cms', 'openpgp']
+            },
+            'signature': {
+                allowed: ['string']
+            },
+            'base64':{
+                allowed: ['boolean']
+            }
+        },
+        answer: {
+            type: ['plaintext'],
+            data:{
+                data: 'string',
+                base64:'boolean',
+                info: 'object'
+                // file_name: Optional string of the plaintext file name.
+                //  is_mime: Boolean if the messages claims it is MIME.
+                // signatures: Array of signatures
+            }
+        }
+    },
+
+    config_opt: {
+        required: {
+            'component':{
+                allowed: ['string'],
+                // allowed_data: ['gpg'] // TODO check all available
+            },
+            'option': {
+                allowed: ['string'],
+                // allowed_data: ['default-key'] // TODO check all available
+            }
+        },
+        optional: {},
+        answer: {
+            type: [],
+            data: {
+                option: 'object'
+            }
+        }
     }
+
     /**
      * TBD handling of secrets
      * TBD key modification?