/*
* This file is part of PKM (Persistent Knowledge Monitor).
* Copyright (c) 2020 Capgemini Group, Commissariat à l'énergie atomique et aux énergies alternatives,
* OW2, Sysgo AG, Technikon, Tree Technology, Universitat Politècnica de València.
*
* PKM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation.
*
* PKM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with PKM. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Create/Update user
*
* @memberof PKM
* @instance
* @param {User} user - user
* @param {boolean} update - flag to enable/disable updating user's info
*
* @return {Promise} a promise
*/
function create_update_user(user, update)
{
return new Promise(function(resolve, reject)
{
const debug = this.debug;
const db = this.client.db(this.config.pkm_db);
if(update)
{
this.get_user(user.name).then((known_user) =>
{
known_user = this.grant_pkm_management_roles(known_user);
// check that current user can update user:
// - it is not another user or,
// - it is an administrator
((this.user_name == user.name) ? Promise.resolve(true) : new Promise((resolve, reject) =>
{
// current user is not the user being updated
// determine whether current user is an administrator, which thus can update another user
this.get_user(this.user_name).then((current_user) =>
{
resolve(current_user.is_admin());
}).catch((err) =>
{
reject(this.Error(err));
});
})).then((can_update_user) => new Promise((resolve, reject) =>
{
if(can_update_user)
{
let cmd =
{
updateUser : user.name,
};
if((user.first_name !== undefined) ||
(user.last_name !== undefined) ||
(user.email !== undefined) ||
(user.phone !== undefined) ||
(user.git_user_credentials !== undefined))
{
const GitUserCredential = require('./git_user_credential');
cmd.customData =
{
first_name : (user.first_name !== undefined) ? user.first_name : known_user.first_name,
last_name : (user.last_name !== undefined) ? user.last_name : known_user.last_name,
email : (user.email !== undefined) ? user.email : known_user.email,
phone : (user.phone !== undefined) ? user.phone : known_user.phone
};
if((user.name == this.user_name) && (user.git_user_credentials !== undefined))
{
cmd.customData.git_user_credentials = user.git_user_credentials.map((git_user_credential) => git_user_credential.encrypt(this.crypt));
}
else if(known_user.git_user_credentials !== undefined)
{
cmd.customData.git_user_credentials = known_user.git_user_credentials;
}
}
if(!(user.password === undefined))
{
cmd.pwd = user.password;
}
if((cmd.customData !== undefined) || (cmd.pwd !== undefined) || (cmd.roles !== undefined))
{
if(debug)
{
console.log('Running command ', cmd);
}
db.command(cmd).then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
}
else
{
if(debug)
{
console.log('no custom data or password update');
}
resolve();
}
}
else
{
if(debug)
{
console.log('current user can\'t update other user custom data or password');
}
resolve();
}
})).then(() =>
{
if(!(user.roles === undefined))
{
user = this.grant_pkm_management_roles(user);
var grant_user_role_promises = [];
user.roles.forEach((user_role) =>
{
if(!known_user.has_role(user_role.db, user_role.role))
{
if(debug)
{
console.log('known user (\'' + known_user.name + '\') has no role \'' + user_role.role + '\' in \'' + user_role.db + '\': requesting grant');
}
grant_user_role_promises.push(this.update_user_role(user_role.db, user_role.role, 'grant', user.name));
}
});
Promise.all(grant_user_role_promises).then(() =>
{
let revoke_user_role_promises = [];
known_user.roles.forEach((known_user_role) =>
{
if(!user.has_role(known_user_role.db, known_user_role.role))
{
if(debug)
{
console.log('user (\'' + known_user.name + '\') has no longer role \'' + known_user_role.role+ '\' in \'' + known_user_role.db + '\': requesting revocation');
}
revoke_user_role_promises.push(this.update_user_role(known_user_role.db, known_user_role.role, 'revoke', user.name));
}
});
Promise.all(revoke_user_role_promises).then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
}).catch((err) =>
{
reject(this.Error(err));
});
}
else
{
resolve();
}
}).catch((err) =>
{
reject(this.Error(err));
});
}).catch((err) =>
{
reject(this.Error(err));
});
}
else
{
user = this.grant_pkm_management_roles(user);
var options =
{
roles : user.roles,
customData :
{
first_name : user.first_name,
last_name : user.last_name,
email : user.email,
phone : user.phone
}
};
if(user.git_user_credentials !== undefined) options.customData.git_user_credentials = user.git_user_credentials.map((git_user_credential) => git_user_credential.encrypt(this.crypt));
if(debug)
{
console.log('Adding ' + user.name + '@' + this.config.pkm_db + ' with password \'' + user.password + '\', roles ', options.roles, ', custom data ', options.customData);
}
db.addUser(user.name, user.password, options).then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
}
}.bind(this));
}
exports.create_update_user = create_update_user;