js: disallow bulk set data on key from outside
-- * src/Key.js Key class is not exported anymore, as it should not be used directly anywhere. setKeyData is no more a method of the Key, (optional) data are now validated and set on Key creation and on updates, both from within this module, thus no longer exposing setKeyData to the outside. * createKey now gained an optional parameter which allows to set Key data at this point.
This commit is contained in:
parent
90cb4a6842
commit
754e799d35
@ -22,7 +22,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { gpgme_error } from './Errors';
|
import { gpgme_error } from './Errors';
|
||||||
import { GPGME_Key } from './Key';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to return an array of fingerprints, either from input fingerprints or
|
* Tries to return an array of fingerprints, either from input fingerprints or
|
||||||
@ -50,7 +49,7 @@ export function toKeyIdArray(input){
|
|||||||
}
|
}
|
||||||
} else if (typeof(input[i]) === 'object'){
|
} else if (typeof(input[i]) === 'object'){
|
||||||
let fpr = '';
|
let fpr = '';
|
||||||
if (input[i] instanceof GPGME_Key){
|
if (input[i].hasOwnProperty('fingerprint')){
|
||||||
fpr = input[i].fingerprint;
|
fpr = input[i].fingerprint;
|
||||||
} else if (input[i].hasOwnProperty('primaryKey') &&
|
} else if (input[i].hasOwnProperty('primaryKey') &&
|
||||||
input[i].primaryKey.hasOwnProperty('getFingerprint')){
|
input[i].primaryKey.hasOwnProperty('getFingerprint')){
|
||||||
|
@ -31,13 +31,22 @@ import { createMessage } from './Message';
|
|||||||
* @param {Boolean} async If True, Key properties (except fingerprint) will be
|
* @param {Boolean} async If True, Key properties (except fingerprint) will be
|
||||||
* queried from gnupg on each call, making the operation up-to-date, the
|
* queried from gnupg on each call, making the operation up-to-date, the
|
||||||
* answers will be Promises, and the performance will likely suffer
|
* answers will be Promises, and the performance will likely suffer
|
||||||
* @returns {GPGME_Key|GPGME_Error}
|
* @param {Object} data additional initial properties this Key will have. Needs
|
||||||
|
* a full object as delivered by gpgme-json
|
||||||
|
* @returns {Object|GPGME_Error} The verified and updated data
|
||||||
*/
|
*/
|
||||||
export function createKey(fingerprint, async = false){
|
export function createKey(fingerprint, async = false, data){
|
||||||
if (!isFingerprint(fingerprint) || typeof(async) !== 'boolean'){
|
if (!isFingerprint(fingerprint) || typeof(async) !== 'boolean'){
|
||||||
return gpgme_error('PARAM_WRONG');
|
return gpgme_error('PARAM_WRONG');
|
||||||
}
|
}
|
||||||
else return Object.freeze(new GPGME_Key(fingerprint, async));
|
if (data !== undefined){
|
||||||
|
data = validateKeyData(data);
|
||||||
|
}
|
||||||
|
if (data instanceof Error){
|
||||||
|
return gpgme_error('KEY_INVALID');
|
||||||
|
} else {
|
||||||
|
return Object.freeze(new GPGME_Key(fingerprint, async, data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,9 +58,9 @@ export function createKey(fingerprint, async = false){
|
|||||||
*
|
*
|
||||||
* @class
|
* @class
|
||||||
*/
|
*/
|
||||||
export class GPGME_Key {
|
class GPGME_Key {
|
||||||
|
|
||||||
constructor(fingerprint, async){
|
constructor(fingerprint, async, data){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {Boolean} If true, most answers will be asynchronous
|
* @property {Boolean} If true, most answers will be asynchronous
|
||||||
@ -59,6 +68,11 @@ export class GPGME_Key {
|
|||||||
this.isAsync = async;
|
this.isAsync = async;
|
||||||
|
|
||||||
let _data = {fingerprint: fingerprint.toUpperCase()};
|
let _data = {fingerprint: fingerprint.toUpperCase()};
|
||||||
|
if (data !== undefined
|
||||||
|
&& data.fingerprint.toUpperCase() === _data.fingerprint
|
||||||
|
) {
|
||||||
|
_data = data;
|
||||||
|
}
|
||||||
this.getFingerprint = function(){
|
this.getFingerprint = function(){
|
||||||
if (!_data.fingerprint || !isFingerprint(_data.fingerprint)){
|
if (!_data.fingerprint || !isFingerprint(_data.fingerprint)){
|
||||||
return gpgme_error('KEY_INVALID');
|
return gpgme_error('KEY_INVALID');
|
||||||
@ -77,54 +91,6 @@ export class GPGME_Key {
|
|||||||
return this.get('hasSecret');
|
return this.get('hasSecret');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Object} data Bulk set the data for this key, with an Object
|
|
||||||
* sent by gpgme-json.
|
|
||||||
* @returns {GPGME_Key|GPGME_Error} Itself after values have been set,
|
|
||||||
* an error if something went wrong.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.setKeyData = function (data){
|
|
||||||
if (typeof(data) !== 'object') {
|
|
||||||
return gpgme_error('KEY_INVALID');
|
|
||||||
}
|
|
||||||
if (!data.fingerprint ||
|
|
||||||
data.fingerprint.toUpperCase() !== _data.fingerprint){
|
|
||||||
return gpgme_error('KEY_INVALID');
|
|
||||||
}
|
|
||||||
let keys = Object.keys(data);
|
|
||||||
for (let i=0; i< keys.length; i++){
|
|
||||||
if (!validKeyProperties.hasOwnProperty(keys[i])){
|
|
||||||
return gpgme_error('KEY_INVALID');
|
|
||||||
}
|
|
||||||
//running the defined validation function
|
|
||||||
if (validKeyProperties[keys[i]](data[keys[i]]) !== true ){
|
|
||||||
return gpgme_error('KEY_INVALID');
|
|
||||||
}
|
|
||||||
switch (keys[i]){
|
|
||||||
case 'subkeys':
|
|
||||||
_data.subkeys = [];
|
|
||||||
for (let i=0; i< data.subkeys.length; i++) {
|
|
||||||
_data.subkeys.push(Object.freeze(
|
|
||||||
new GPGME_Subkey(data.subkeys[i])));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'userids':
|
|
||||||
_data.userids = [];
|
|
||||||
for (let i=0; i< data.userids.length; i++) {
|
|
||||||
_data.userids.push(Object.freeze(
|
|
||||||
new GPGME_UserId(data.userids[i])));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'last_update':
|
|
||||||
_data[keys[i]] = new Date( data[keys[i]] * 1000 );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_data[keys[i]] = data[keys[i]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query any property of the Key listed in {@link validKeyProperties}
|
* Query any property of the Key listed in {@link validKeyProperties}
|
||||||
@ -188,7 +154,12 @@ export class GPGME_Key {
|
|||||||
msg.setParameter('keys', _data.fingerprint);
|
msg.setParameter('keys', _data.fingerprint);
|
||||||
msg.post().then(function(result){
|
msg.post().then(function(result){
|
||||||
if (result.keys.length === 1){
|
if (result.keys.length === 1){
|
||||||
me.setKeyData(result.keys[0]);
|
const newdata = validateKeyData(
|
||||||
|
_data.fingerprint, result.keys[0]);
|
||||||
|
if (newdata instanceof Error){
|
||||||
|
reject(gpgme_error('KEY_INVALID'));
|
||||||
|
} else {
|
||||||
|
_data = newdata;
|
||||||
me.getHasSecret().then(function(){
|
me.getHasSecret().then(function(){
|
||||||
me.getArmor().then(function(){
|
me.getArmor().then(function(){
|
||||||
resolve(me);
|
resolve(me);
|
||||||
@ -198,6 +169,7 @@ export class GPGME_Key {
|
|||||||
}, function(error){
|
}, function(error){
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
reject(gpgme_error('KEY_NOKEY'));
|
reject(gpgme_error('KEY_NOKEY'));
|
||||||
}
|
}
|
||||||
@ -602,3 +574,53 @@ const validKeyProperties = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the Key data in bulk. It can only be used from inside a Key, either
|
||||||
|
* during construction or on a refresh callback.
|
||||||
|
* @param {Object} key the original internal key data.
|
||||||
|
* @param {Object} data Bulk set the data for this key, with an Object structure
|
||||||
|
* as sent by gpgme-json.
|
||||||
|
* @returns {Object|GPGME_Error} the changed data after values have been set,
|
||||||
|
* an error if something went wrong.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function validateKeyData(data){
|
||||||
|
const key = {};
|
||||||
|
if ( typeof(data) !== 'object'
|
||||||
|
|| !data.fingerprint){
|
||||||
|
return gpgme_error('KEY_INVALID');
|
||||||
|
}
|
||||||
|
let props = Object.keys(data);
|
||||||
|
for (let i=0; i< props.length; i++){
|
||||||
|
if (!validKeyProperties.hasOwnProperty(props[i])){
|
||||||
|
return gpgme_error('KEY_INVALID');
|
||||||
|
}
|
||||||
|
// running the defined validation function
|
||||||
|
if (validKeyProperties[props[i]](data[props[i]]) !== true ){
|
||||||
|
return gpgme_error('KEY_INVALID');
|
||||||
|
}
|
||||||
|
switch (props[i]){
|
||||||
|
case 'subkeys':
|
||||||
|
key.subkeys = [];
|
||||||
|
for (let i=0; i< data.subkeys.length; i++) {
|
||||||
|
key.subkeys.push(Object.freeze(
|
||||||
|
new GPGME_Subkey(data.subkeys[i])));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'userids':
|
||||||
|
key.userids = [];
|
||||||
|
for (let i=0; i< data.userids.length; i++) {
|
||||||
|
key.userids.push(Object.freeze(
|
||||||
|
new GPGME_UserId(data.userids[i])));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'last_update':
|
||||||
|
key[props[i]] = new Date( data[props[i]] * 1000 );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
key[props[i]] = data[props[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
@ -100,8 +100,8 @@ export class GPGME_Keyring {
|
|||||||
// TODO getArmor() to be used in sync
|
// TODO getArmor() to be used in sync
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let k = createKey(result.keys[i].fingerprint);
|
let k = createKey(result.keys[i].fingerprint,
|
||||||
k.setKeyData(result.keys[i]);
|
!prepare_sync, result.keys[i]);
|
||||||
resultset.push(k);
|
resultset.push(k);
|
||||||
}
|
}
|
||||||
resolve(resultset);
|
resolve(resultset);
|
||||||
@ -170,7 +170,7 @@ export class GPGME_Keyring {
|
|||||||
* @async
|
* @async
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
this.getDefaultKey = function() {
|
this.getDefaultKey = function(prepare_sync = false) {
|
||||||
let me = this;
|
let me = this;
|
||||||
return new Promise(function(resolve, reject){
|
return new Promise(function(resolve, reject){
|
||||||
let msg = createMessage('config_opt');
|
let msg = createMessage('config_opt');
|
||||||
@ -202,8 +202,9 @@ export class GPGME_Keyring {
|
|||||||
for (let i=0; i< result.keys.length; i++ ) {
|
for (let i=0; i< result.keys.length; i++ ) {
|
||||||
if (result.keys[i].invalid === false) {
|
if (result.keys[i].invalid === false) {
|
||||||
let k = createKey(
|
let k = createKey(
|
||||||
result.keys[i].fingerprint);
|
result.keys[i].fingerprint,
|
||||||
k.setKeyData(result.keys[i]);
|
!prepare_sync,
|
||||||
|
result.keys[i]);
|
||||||
resolve(k);
|
resolve(k);
|
||||||
break;
|
break;
|
||||||
} else if (i === result.keys.length - 1){
|
} else if (i === result.keys.length - 1){
|
||||||
|
Loading…
Reference in New Issue
Block a user