mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
add username and description to api (+ doc)
This commit is contained in:
parent
b7ba462a5d
commit
9e47ae36a4
@ -50,6 +50,7 @@ In case of success returns:
|
||||
"state":"success",
|
||||
"user": {
|
||||
"created": 1614782270,
|
||||
"description": "",
|
||||
"disabled": false,
|
||||
"email": "max.musterman@gmail.de",
|
||||
"email_checked": true,
|
||||
@ -69,6 +70,7 @@ In case of success returns:
|
||||
|
||||
- `user`: contain user object
|
||||
- `created`: timestamp on which account was created
|
||||
- `description`: description of user for other user
|
||||
- `disabled`: true if account was disabled, if disabled no login or coin transfer is possible
|
||||
- `email`: email of user
|
||||
- `email_checked`: true if user has successfully clicked on activation link in email
|
||||
@ -97,6 +99,8 @@ with:
|
||||
"email":"max.musterman@gmail.de",
|
||||
"first_name":"Max",
|
||||
"last_name":"Musterman",
|
||||
"username": "Maxilein",
|
||||
"description": "Tischler",
|
||||
"emailType": 2,
|
||||
"group_id": 1,
|
||||
"password":"123abcDE&",
|
||||
@ -104,6 +108,8 @@ with:
|
||||
}
|
||||
```
|
||||
|
||||
- `username`: (optional), mindestens 4 Zeichen, return error if already used
|
||||
- `description`: (optional), mindestens 4 Zeichen
|
||||
- `emailType`: control email-text sended with email verification code
|
||||
- 2: default, if user has registered directly
|
||||
- 5: if user was registered by an admin
|
||||
@ -167,6 +173,8 @@ with:
|
||||
"update": {
|
||||
"User.first_name": "Max",
|
||||
"User.last_name" : "Musterman",
|
||||
"User.username" : "Maxilein",
|
||||
"User.description" : "Tischler",
|
||||
"User.disabled": 0,
|
||||
"User.language": "de",
|
||||
"User.password": "1234"
|
||||
@ -237,6 +245,8 @@ with:
|
||||
"user.pubkeyhex",
|
||||
"user.first_name",
|
||||
"user.last_name",
|
||||
"user.username",
|
||||
"user.description",
|
||||
"user.disabled",
|
||||
"user.email_checked",
|
||||
"user.language"
|
||||
@ -271,6 +281,8 @@ Return only the fields which are defined in request
|
||||
- `user.pubkeyhex`: public key of user in hex-format
|
||||
- `user.first_name`: first name of user
|
||||
- `user.last_name`: last name of user
|
||||
- `user.username`: username of user (min 4 Character, unique per group)
|
||||
- `user.description`: profil text for user
|
||||
- `user.disabled`: User will be disabled if he wants a account delete but has transactions. Until transactions are saved in real blockchain, we need this data because the public key
|
||||
is in db only saved in state_users so if we delete this entry, validating all transactions is no longer possible. Disabled User cannot login and cannot receive transactions.
|
||||
- `email_checked`: If user has clicked on link in verification email (register), can only transfer gradidos if email_checked is 1
|
||||
@ -298,6 +310,7 @@ In case of success returns:
|
||||
"info":[],
|
||||
"user": {
|
||||
"created": 1614782270,
|
||||
"description": "Tischler"
|
||||
"disabled": false,
|
||||
"email": "max.musterman@gmail.de",
|
||||
"email_checked": true,
|
||||
|
||||
@ -4,6 +4,7 @@ CREATE TABLE `users` (
|
||||
`first_name` varchar(150) NOT NULL,
|
||||
`last_name` varchar(255) DEFAULT '',
|
||||
`username` varchar(255) DEFAULT '',
|
||||
`description` text DEFAULT '',
|
||||
`password` bigint unsigned DEFAULT '0',
|
||||
`pubkey` binary(32) DEFAULT NULL,
|
||||
`privkey` binary(80) DEFAULT NULL,
|
||||
|
||||
@ -15,6 +15,8 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params)
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
std::string password;
|
||||
std::string username;
|
||||
std::string description;
|
||||
bool login_after_register = false;
|
||||
int emailType;
|
||||
int group_id = 1;
|
||||
@ -36,18 +38,27 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params)
|
||||
paramJsonObject->get("first_name").convert(first_name);
|
||||
paramJsonObject->get("last_name").convert(last_name);
|
||||
paramJsonObject->get("emailType").convert(emailType);
|
||||
|
||||
auto group_id_obj = paramJsonObject->get("group_id");
|
||||
auto username_obj = paramJsonObject->get("username");
|
||||
auto description_obj = paramJsonObject->get("description");
|
||||
|
||||
if(!group_id_obj.isEmpty()) {
|
||||
group_id_obj.convert(group_id);
|
||||
}
|
||||
|
||||
if (!username_obj.isEmpty()) {
|
||||
username_obj.convert(username);
|
||||
}
|
||||
if (!description_obj.isEmpty()) {
|
||||
description_obj.convert(description);
|
||||
}
|
||||
if ((ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS)) {
|
||||
paramJsonObject->get("password").convert(password);
|
||||
}
|
||||
if (!paramJsonObject->isNull("login_after_register")) {
|
||||
paramJsonObject->get("login_after_register").convert(login_after_register);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
return stateError("json exception", ex.displayText());
|
||||
@ -85,6 +96,15 @@ Poco::JSON::Object* JsonCreateUser::handle(Poco::Dynamic::Var params)
|
||||
group_was_not_set = true;
|
||||
}
|
||||
user = controller::User::create(email, first_name, last_name, group_id);
|
||||
if (username.size() > 3) {
|
||||
if (user->isUsernameAlreadyUsed(username)) {
|
||||
return stateError("username already in use");
|
||||
}
|
||||
user->getModel()->setUsername(username);
|
||||
}
|
||||
if (description.size() > 3) {
|
||||
user->getModel()->setDescription(description);
|
||||
}
|
||||
auto userModel = user->getModel();
|
||||
Session* session = nullptr;
|
||||
|
||||
|
||||
@ -121,6 +121,12 @@ Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params)
|
||||
else if (parameterString == "user.last_name") {
|
||||
jsonUser.set("last_name", user_model->getLastName());
|
||||
}
|
||||
else if (parameterString == "user.username") {
|
||||
jsonUser.set("username", user_model->getUsername());
|
||||
}
|
||||
else if (parameterString == "user.description") {
|
||||
jsonUser.set("description", user_model->getDescription());
|
||||
}
|
||||
else if (parameterString == "user.disabled") {
|
||||
jsonUser.set("disabled", user_model->isDisabled());
|
||||
}
|
||||
|
||||
@ -86,6 +86,32 @@ Poco::JSON::Object* JsonUpdateUserInfos::handle(Poco::Dynamic::Var params)
|
||||
extractet_values++;
|
||||
}
|
||||
}
|
||||
else if ("User.username" == name && value.size() > 3) {
|
||||
if (!value.isString()) {
|
||||
jsonErrorsArray.add("User.username isn't a string");
|
||||
}
|
||||
else {
|
||||
auto new_username = value.toString();
|
||||
if (user_model->getUsername() != new_username) {
|
||||
if (user->isUsernameAlreadyUsed(new_username)) {
|
||||
jsonErrorsArray.add("username already used");
|
||||
}
|
||||
else {
|
||||
user_model->setUsername(new_username);
|
||||
extractet_values++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("User.description" == name && value.size() > 3) {
|
||||
if (!value.isString()) {
|
||||
jsonErrorsArray.add("description isn't a string");
|
||||
}
|
||||
else {
|
||||
user_model->setDescription(value.toString());
|
||||
extractet_values++;
|
||||
}
|
||||
}
|
||||
else if ("User.disabled" == name) {
|
||||
if (value.isBoolean()) {
|
||||
bool disabled;
|
||||
|
||||
@ -105,6 +105,12 @@ namespace controller {
|
||||
|
||||
}
|
||||
|
||||
bool User::isUsernameAlreadyUsed(const std::string& username)
|
||||
{
|
||||
auto db = getModel();
|
||||
return db->loadFromDB({ "username", "group_id" }, username, db->getGroupId(), model::table::MYSQL_CONDITION_AND) > 0;
|
||||
}
|
||||
|
||||
int User::load(const unsigned char* pubkey_array)
|
||||
{
|
||||
Poco::Data::BLOB pubkey(pubkey_array, 32);
|
||||
|
||||
@ -47,6 +47,8 @@ namespace controller {
|
||||
|
||||
static std::vector<User*> search(const std::string& searchString, const std::string& accountState = "all");
|
||||
|
||||
bool isUsernameAlreadyUsed(const std::string& username);
|
||||
|
||||
//! \brief go through whole db and search users with email_checked = false and schedule resend 7 days after email_opt_in created date
|
||||
//!
|
||||
//! Should be only called by server start, later it aren't necessary, because register function schedule resend tasks by himself.
|
||||
|
||||
@ -29,7 +29,8 @@ namespace model {
|
||||
User::User(UserTuple tuple)
|
||||
: ModelBase(tuple.get<0>()),
|
||||
mFirstName(tuple.get<1>()), mLastName(tuple.get<2>()), mEmail(tuple.get<3>()), mUsername(tuple.get<4>()),
|
||||
mPublicKey(tuple.get<5>()), mCreated(tuple.get<6>()), mEmailChecked(tuple.get<7>()), mDisabled(tuple.get<8>()), mGroupId(tuple.get<9>()),
|
||||
mDescription(tuple.get<5>()),
|
||||
mPublicKey(tuple.get<6>()), mCreated(tuple.get<7>()), mEmailChecked(tuple.get<8>()), mDisabled(tuple.get<9>()), mGroupId(tuple.get<10>()),
|
||||
mPasswordHashed(0), mLanguageKey("de"), mRole(ROLE_NOT_LOADED)
|
||||
{
|
||||
|
||||
@ -82,12 +83,12 @@ namespace model {
|
||||
|
||||
|
||||
if (mPasswordHashed) {
|
||||
insert << "INSERT INTO users (email, first_name, last_name, username, password, email_hash, language, group_id) VALUES(?,?,?,?,?,?,?,?);",
|
||||
use(mEmail), use(mFirstName), use(mLastName), use(mUsername), bind(mPasswordHashed), use(mEmailHash), use(mLanguageKey), use(mGroupId);
|
||||
insert << "INSERT INTO users (email, first_name, last_name, username, description, password, email_hash, language, group_id) VALUES(?,?,?,?,?,?,?,?);",
|
||||
use(mEmail), use(mFirstName), use(mLastName), use(mUsername), use(mDescription), bind(mPasswordHashed), use(mEmailHash), use(mLanguageKey), use(mGroupId);
|
||||
}
|
||||
else {
|
||||
insert << "INSERT INTO users (email, first_name, last_name, username, email_hash, language, group_id) VALUES(?,?,?,?,?,?,?);",
|
||||
use(mEmail), use(mFirstName), use(mLastName), use(mUsername), use(mEmailHash), use(mLanguageKey), use(mGroupId);
|
||||
insert << "INSERT INTO users (email, first_name, last_name, username, description, email_hash, language, group_id) VALUES(?,?,?,?,?,?,?);",
|
||||
use(mEmail), use(mFirstName), use(mLastName), use(mUsername), use(mDescription), use(mEmailHash), use(mLanguageKey), use(mGroupId);
|
||||
}
|
||||
|
||||
return insert;
|
||||
@ -100,11 +101,11 @@ namespace model {
|
||||
_fieldName = getTableName() + std::string(".id");
|
||||
}
|
||||
Poco::Data::Statement select(session);
|
||||
select << "SELECT " << getTableName() << ".id, email, first_name, last_name, username, password, pubkey, privkey, email_hash, created, email_checked, language, disabled, group_id, user_roles.role_id "
|
||||
select << "SELECT " << getTableName() << ".id, email, first_name, last_name, username, description, password, pubkey, privkey, email_hash, created, email_checked, language, disabled, group_id, user_roles.role_id "
|
||||
<< " FROM " << getTableName()
|
||||
<< " LEFT JOIN user_roles ON " << getTableName() << ".id = user_roles.user_id "
|
||||
<< " WHERE " << _fieldName << " = ?" ,
|
||||
into(mID), into(mEmail), into(mFirstName), into(mLastName), into(mUsername), into(mPasswordHashed),
|
||||
into(mID), into(mEmail), into(mFirstName), into(mLastName), into(mUsername), into(mDescription), into(mPasswordHashed),
|
||||
into(mPublicKey), into(mPrivateKey), into(mEmailHash), into(mCreated), into(mEmailChecked),
|
||||
into(mLanguageKey), into(mDisabled), into(mGroupId), into(mRole);
|
||||
|
||||
@ -116,7 +117,7 @@ namespace model {
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
// typedef Poco::Tuple<std::string, std::string, std::string, Poco::Nullable<Poco::Data::BLOB>, int> UserTuple;
|
||||
select << "SELECT id, first_name, last_name, email, username, pubkey, created, email_checked, disabled, group_id FROM " << getTableName()
|
||||
select << "SELECT id, first_name, last_name, email, username, description, pubkey, created, email_checked, disabled, group_id FROM " << getTableName()
|
||||
<< " where " << fieldName << " LIKE ?";
|
||||
|
||||
|
||||
@ -132,7 +133,7 @@ namespace model {
|
||||
}
|
||||
|
||||
// typedef Poco::Tuple<std::string, std::string, std::string, Poco::Nullable<Poco::Data::BLOB>, int> UserTuple;
|
||||
select << "SELECT id, first_name, last_name, email, username, pubkey, created, email_checked, disabled, group_id FROM " << getTableName()
|
||||
select << "SELECT id, first_name, last_name, email, username, description, pubkey, created, email_checked, disabled, group_id FROM " << getTableName()
|
||||
<< " where " << fieldNames[0] << " LIKE ?";
|
||||
if (conditionType == MYSQL_CONDITION_AND) {
|
||||
for (int i = 1; i < fieldNames.size(); i++) {
|
||||
@ -244,8 +245,8 @@ namespace model {
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
|
||||
Poco::Data::Statement update(session);
|
||||
update << "UPDATE users SET first_name = ?, last_name = ?, username = ?, disabled = ?, language = ? where id = ?;",
|
||||
use(mFirstName), use(mLastName), use(mUsername), use(mDisabled), use(mLanguageKey), use(mID);
|
||||
update << "UPDATE users SET first_name = ?, last_name = ?, username = ?, description = ?, disabled = ?, language = ? where id = ?;",
|
||||
use(mFirstName), use(mLastName), use(mUsername), use(mDescription), use(mDisabled), use(mLanguageKey), use(mID);
|
||||
|
||||
|
||||
try {
|
||||
@ -305,6 +306,8 @@ namespace model {
|
||||
|
||||
ss << mUsername << std::endl;
|
||||
ss << mFirstName << " " << mLastName << " <" << mEmail << ">" << std::endl;
|
||||
ss << "username: " << mUsername << std::endl;
|
||||
ss << "details: " << mDescription << std::endl;
|
||||
ss << "password hash: " << mPasswordHashed << std::endl;
|
||||
ss << "public key: " << (char*)*pubkeyHex << std::endl;
|
||||
ss << "private key: " << (char*)*privkeyHex << std::endl;
|
||||
@ -343,6 +346,8 @@ namespace model {
|
||||
|
||||
ss << "<b>" << mUsername << "</b><br>";
|
||||
ss << "<b>" << mFirstName << " " << mLastName << " <" << mEmail << "></b>" << "<br>";
|
||||
ss << "username: " << mUsername << "<br>";
|
||||
ss << "details: " << mDescription << "<br>";
|
||||
ss << "public key: " << (char*)*pubkeyHex << "<br>";
|
||||
ss << "email hash: " << (char*)*email_hash << "<br>";
|
||||
ss << "created: " << Poco::DateTimeFormatter::format(mCreated, "%f.%m.%Y %H:%M:%S") << "<br>";
|
||||
@ -415,6 +420,7 @@ namespace model {
|
||||
userObj.set("last_name", mLastName);
|
||||
userObj.set("email", mEmail);
|
||||
userObj.set("username", mUsername);
|
||||
userObj.set("description", mDescription);
|
||||
|
||||
//userObj.set("state", userStateToString(mState));
|
||||
auto createTimeStamp = mCreated.timestamp();
|
||||
|
||||
@ -20,6 +20,8 @@ namespace model {
|
||||
USER_FIELD_EMAIL,
|
||||
USER_FIELDS_FIRST_NAME,
|
||||
USER_FIELDS_LAST_NAME,
|
||||
USER_FIELDS_USERNAME,
|
||||
USER_FIELDS_DESCRIPTION,
|
||||
USER_FIELDS_PASSWORD,
|
||||
USER_FIELDS_PUBLIC_KEY,
|
||||
USER_FIELDS_PRIVATE_KEY,
|
||||
@ -28,7 +30,7 @@ namespace model {
|
||||
USER_FIELDS_LANGUAGE
|
||||
};
|
||||
|
||||
typedef Poco::Tuple<int, std::string, std::string, std::string, std::string, Poco::Nullable<Poco::Data::BLOB>, Poco::DateTime, int, int, int> UserTuple;
|
||||
typedef Poco::Tuple<int, std::string, std::string, std::string, std::string, std::string, Poco::Nullable<Poco::Data::BLOB>, Poco::DateTime, int, int, int> UserTuple;
|
||||
|
||||
class User : public ModelBase
|
||||
{
|
||||
@ -57,6 +59,7 @@ namespace model {
|
||||
inline const std::string getFirstName() const { SHARED_LOCK; return mFirstName; }
|
||||
inline const std::string getLastName() const { SHARED_LOCK; return mLastName; }
|
||||
inline const std::string getUsername() const { SHARED_LOCK; return mUsername; }
|
||||
inline const std::string getDescription() const { SHARED_LOCK; return mDescription; }
|
||||
inline std::string getNameWithEmailHtml() const { SHARED_LOCK; return mFirstName + " " + mLastName + " <" + mEmail + ">"; }
|
||||
inline const Poco::UInt64 getPasswordHashed() const { SHARED_LOCK; return mPasswordHashed; }
|
||||
inline int getGroupId() const { SHARED_LOCK; return mGroupId; }
|
||||
@ -80,6 +83,7 @@ namespace model {
|
||||
inline void setFirstName(const std::string& first_name) { UNIQUE_LOCK; mFirstName = first_name; }
|
||||
inline void setLastName(const std::string& last_name) { UNIQUE_LOCK; mLastName = last_name; }
|
||||
inline void setUsername(const std::string& username) { UNIQUE_LOCK; mUsername = username; }
|
||||
inline void setDescription(const std::string& description) { UNIQUE_LOCK; mDescription = description; }
|
||||
inline void setPasswordHashed(const Poco::UInt64& passwordHashed) { UNIQUE_LOCK; mPasswordHashed = passwordHashed; }
|
||||
void setPublicKey(const unsigned char* publicKey);
|
||||
//! \brief set encrypted private key
|
||||
@ -105,7 +109,7 @@ namespace model {
|
||||
std::string mFirstName;
|
||||
std::string mLastName;
|
||||
std::string mUsername;
|
||||
|
||||
std::string mDescription;
|
||||
Poco::UInt64 mPasswordHashed;
|
||||
|
||||
Poco::Nullable<Poco::Data::BLOB> mPublicKey;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user