mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
commit
0886979d09
@ -197,7 +197,7 @@ class StateBalancesController extends AppController
|
||||
}
|
||||
uasort($transactions, array($this, 'sortTransactions'));
|
||||
$this->set('transactions', $transactions);
|
||||
$this->set('transactionExecutingCount', $session->read('Transaction.executing'));
|
||||
$this->set('transactionExecutingCount', $session->read('Transactions.executing'));
|
||||
$this->set('balance', $session->read('StateUser.balance'));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
$this->set('gdtSum', $gdtSum);
|
||||
@ -370,7 +370,7 @@ class StateBalancesController extends AppController
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transaction.executing'),
|
||||
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||
'count' => count($transactions),
|
||||
'gdtSum' => $gdtSum,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
|
||||
@ -196,7 +196,7 @@ class StateUserTransactionsController extends AppController
|
||||
return $this->returnJson([
|
||||
'state' => 'success',
|
||||
'transactions' => $transactions,
|
||||
'transactionExecutingCount' => $session->read('Transaction.executing'),
|
||||
'transactionExecutingCount' => $session->read('Transactions.executing'),
|
||||
'count' => $all_user_transactions_count,
|
||||
'timeUsed' => microtime(true) - $startTime
|
||||
]);
|
||||
|
||||
@ -323,7 +323,7 @@ class TransactionCreationsController extends AppController
|
||||
$this->set('firstDayLastMonth', $firstDayLastMonth);
|
||||
$this->set('activeUser', $user);
|
||||
$this->set('creationForm', $creationForm);
|
||||
$this->set('transactionExecutingCount', $session->read('Transaction.executing'));
|
||||
$this->set('transactionExecutingCount', $session->read('Transactions.executing'));
|
||||
$this->set('timeUsed', microtime(true) - $startTime);
|
||||
$this->set('countUsers', $countUsers);
|
||||
$this->set('limit', $limit);
|
||||
|
||||
@ -15,8 +15,10 @@ mit:
|
||||
```ini
|
||||
unsercure.allow_cors_all = 1
|
||||
```
|
||||
Wird bei allen JSON-Requests zum Header: Access-Control-Allow-Origin:*
|
||||
hinzugefügt.
|
||||
Wird bei allen JSON-Requests zum Header hinzugefügt:
|
||||
- Access-Control-Allow-Origin:*
|
||||
- Access-Control-Allow-Headers: "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"
|
||||
|
||||
|
||||
In diesen Beispielen gehe ich jetzt davon aus, das du das gesamte Gradido Projekt mit Docker gebaut hast und auf dem lokalen Rechner laufen lässt.
|
||||
|
||||
@ -81,4 +83,130 @@ data: {"session_id": -127182}
|
||||
Wenn alles okay ist erhältst du:
|
||||
```json
|
||||
{"state":"success"}
|
||||
```
|
||||
```
|
||||
|
||||
## Update User Data
|
||||
Update first name, last name, user language and enable/disable user
|
||||
Language currently supported de and en
|
||||
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 we wenn delete this entry, validating all transactions not longer possible.
|
||||
Disabled User cannot login and cannot receive transactions.
|
||||
In update Object only one of the sets needs to be there.
|
||||
|
||||
Update password can only be used if in Login-Server config:
|
||||
```ini
|
||||
unsecure.allow_passwort_via_json_request = 1
|
||||
```
|
||||
|
||||
POST http://localhost/login_api/updateUserInfos
|
||||
```json
|
||||
{"session_id": -127182, "email": "max.musterman@gmail.de", "update": {
|
||||
"User.first_name": "Max",
|
||||
"User.last_name" : "Musterman",
|
||||
"User.disabled": 0,
|
||||
"User.language": "de"
|
||||
"User.password": "1234"
|
||||
}
|
||||
}
|
||||
```
|
||||
also valid
|
||||
```json
|
||||
{"session_id": -127182, "email": "max.musterman@gmail.de", "update": {
|
||||
"User.last_name" : "Musterman"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
It returns if everything is okay
|
||||
```json
|
||||
{"state":"success", "valid_values": 4, "errors":[]}
|
||||
```
|
||||
- valid_values: should contain count of entrys in update if no error occured (User.password will not be counted)
|
||||
- errors: contain on error string for every entry in update, which type isn't like expected
|
||||
- password:
|
||||
- "new password is the same as old password": no change taking place
|
||||
- "password changed, coludn"t load private key for re-encryption": password was successfully changed, is at the moment only a warning as long as user_backups are unencrypted, safe to ignore
|
||||
- "stored pubkey and private key didn't match": error by re-encryption keys, no changes saved
|
||||
- "User.password isn't valid": if password validation failed, followed by reasons why (additional array in array)
|
||||
example:
|
||||
```json
|
||||
{"errors":[
|
||||
"User.password isn't valid",[
|
||||
"Passwort: Dein Passwort ist zu kurz!\n",
|
||||
"Passwort: Bitte gebe ein gültiges Password ein mit mindestens 8 Zeichen, Groß- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen (@$!%*?&+-_) ein!\n"
|
||||
]
|
||||
],
|
||||
"state":"success",
|
||||
"valid_values":0
|
||||
}
|
||||
```
|
||||
## Retrieve User Data
|
||||
Retrieve different user data, in ask only one field is needed, or every possible combination
|
||||
from the available fields
|
||||
|
||||
Normal User can only retrieve data for himself, admins (login-server admin) can retrieve data from every user
|
||||
Email is also the email address of user from which data are asked
|
||||
|
||||
POST http://localhost/login_api/getUserInfos
|
||||
```json
|
||||
{"session_id": -127182, "email": "max.musterman@gmail.de", "ask": [
|
||||
"EmailVerificationCode.Register",
|
||||
"loginServer.path",
|
||||
"user.pubkeyhex",
|
||||
"user.first_name",
|
||||
"user.last_name",
|
||||
"user.disabled",
|
||||
"user.email_checked",
|
||||
]
|
||||
}
|
||||
```
|
||||
returns if no error occured:
|
||||
```json
|
||||
{"state": "success", "userData": {
|
||||
"EmailVerificationCode.Register": "2718271129122",
|
||||
"pubkeyhex": "131c7f68dd94b2be4c913400ff7ff4cdc03ac2bda99c2d29edcacb3b065c67e6",
|
||||
"first_name": "Max",
|
||||
"last_name": "Musterman",
|
||||
"disabled": 0,
|
||||
"email_checked": 1
|
||||
}, "server": {
|
||||
"loginServer.path": "http://localhost/account"
|
||||
},
|
||||
"errors": []
|
||||
}
|
||||
```
|
||||
|
||||
Return only the fields which are defined in ask
|
||||
- EmailVerificationCode.Register: return the email verification code for check email (create one if none exist), work only if logged in user is admin and the email isn't from him
|
||||
- loginServer.path: the redirect path to login-server, for example for login with login-server html frontend
|
||||
- user.pubkeyhex: public key of user in hex-format
|
||||
- user.first_name: first name of user
|
||||
- user.last_name: last name of 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 we wenn delete this entry, validating all transactions not 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
|
||||
|
||||
- errors: array of strings if error occure
|
||||
|
||||
## Login by Email Verification Code
|
||||
Used for replace http://localhost/account/checkEmail
|
||||
Can be used to set check_email to 1 (will be done automaticly if called with valid email verification code of type register or registerDirect)
|
||||
Can be used for password reset (additional step required: call update user info with new password)
|
||||
|
||||
GET http://localhost/login_api/loginViaEmailVerificationCode?emailVerificationCode=382738273892983
|
||||
|
||||
return
|
||||
```json
|
||||
{"state":"success", "email_verification_code_type":"resetPassword","info":[],"session_id":1853761475}
|
||||
```
|
||||
- email_verification_code_type
|
||||
- resetPassword: for password resets, will be deleted immediately, is a only one use code
|
||||
- registerDirect: code generated by register for check email
|
||||
- register: code generated by auto-register via elopage for check email
|
||||
- info can contain additional info strings
|
||||
- user hasn't password: if user hasn't set a password yet (for example if he was registered via elopage)
|
||||
- email already activated: if email was already checked
|
||||
- session_id: session_id for new session
|
||||
@ -71,15 +71,13 @@ Poco::JSON::Object* JsonGetLogin::handle(Poco::Dynamic::Var params)
|
||||
em->addError(new Error("JsonGetLogin::handle", "generic exception calling userModel->getJson: "));
|
||||
em->sendErrorsAsEmail();
|
||||
}
|
||||
// use both variants for compatibility reasons, but final version is Transactions.pending
|
||||
result->set("Transaction.pending", session->getProcessingTransactionCount());
|
||||
|
||||
result->set("Transactions.pending", session->getProcessingTransactionCount());
|
||||
auto executing = observer->getTaskCount(userModel->getEmail(), TASK_OBSERVER_SIGN_TRANSACTION);
|
||||
if (executing < 0) {
|
||||
executing = 0;
|
||||
}
|
||||
// use both variants for compatibility reasons, but final version is Transactions.executing
|
||||
result->set("Transaction.executing", executing);
|
||||
|
||||
result->set("Transactions.executing", executing);
|
||||
//printf("pending: %d\n", session->getProcessingTransactionCount());
|
||||
//std::string user_string = userModel->toString();
|
||||
|
||||
@ -7,6 +7,26 @@
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
Poco::UInt64 JsonGetUserInfos::readOrCreateEmailVerificationCode(int user_id, model::table::EmailOptInType type)
|
||||
{
|
||||
try {
|
||||
auto emailVerificationCode = controller::EmailVerificationCode::load(user_id, type);
|
||||
if (!emailVerificationCode) {
|
||||
emailVerificationCode = controller::EmailVerificationCode::create(user_id, type);
|
||||
UniLib::controller::TaskPtr insert = new model::table::ModelInsertTask(emailVerificationCode->getModel(), false);
|
||||
insert->scheduleTask(insert);
|
||||
}
|
||||
return emailVerificationCode->getModel()->getCode();
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
ErrorList errors;
|
||||
//printf("exception: %s\n", ex.displayText().data());
|
||||
errors.addError(new ParamError("JsonGetUserInfos::readOrCreateEmailVerificationCode", "exception: ", ex.displayText()));
|
||||
errors.sendErrorsAsEmail();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params)
|
||||
{
|
||||
/*
|
||||
@ -54,11 +74,21 @@ Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params)
|
||||
return customStateError("not found", "session not found");
|
||||
}
|
||||
|
||||
auto session_user = session->getNewUser();
|
||||
auto session_user_model = session_user->getModel();
|
||||
bool isAdmin = false;
|
||||
if (model::table::ROLE_ADMIN == session_user_model->getRole()) {
|
||||
isAdmin = true;
|
||||
}
|
||||
if (session_user_model->getEmail() != email && !isAdmin) {
|
||||
return customStateError("not same", "email don't belong to logged in user");
|
||||
}
|
||||
|
||||
auto user = controller::User::create();
|
||||
if (1 != user->load(email)) {
|
||||
return customStateError("not found", "user not found");
|
||||
}
|
||||
auto userModel = user->getModel();
|
||||
auto user_model = user->getModel();
|
||||
|
||||
|
||||
Poco::JSON::Object* result = new Poco::JSON::Object;
|
||||
@ -72,42 +102,32 @@ Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params)
|
||||
std::string parameterString;
|
||||
try {
|
||||
parameter.convert(parameterString);
|
||||
if (parameterString == "EmailVerificationCode.Register") {
|
||||
try {
|
||||
auto emailVerificationCode = controller::EmailVerificationCode::load(
|
||||
userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER
|
||||
);
|
||||
if (!emailVerificationCode) {
|
||||
emailVerificationCode = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER);
|
||||
UniLib::controller::TaskPtr insert = new model::table::ModelInsertTask(emailVerificationCode->getModel(), false);
|
||||
insert->scheduleTask(insert);
|
||||
}
|
||||
jsonUser.set("EmailVerificationCode.Register", std::to_string(emailVerificationCode->getModel()->getCode()));
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
printf("exception: %s\n", ex.displayText().data());
|
||||
if (parameterString == "EmailVerificationCode.Register" && isAdmin && session_user_model->getEmail() != user_model->getEmail()) {
|
||||
auto code = readOrCreateEmailVerificationCode(user_model->getID(), model::table::EMAIL_OPT_IN_REGISTER_DIRECT);
|
||||
if (code) {
|
||||
jsonUser.set("EmailVerificationCode.Register", std::to_string(code));
|
||||
}
|
||||
}
|
||||
else if (parameterString == "loginServer.path") {
|
||||
jsonServer.set("loginServer.path", ServerConfig::g_serverPath);
|
||||
}
|
||||
else if (parameterString == "user.pubkeyhex") {
|
||||
jsonUser.set("pubkeyhex", userModel->getPublicKeyHex());
|
||||
jsonUser.set("pubkeyhex", user_model->getPublicKeyHex());
|
||||
}
|
||||
else if (parameterString == "user.first_name") {
|
||||
jsonUser.set("first_name", userModel->getFirstName());
|
||||
jsonUser.set("first_name", user_model->getFirstName());
|
||||
}
|
||||
else if (parameterString == "user.last_name") {
|
||||
jsonUser.set("last_name", userModel->getLastName());
|
||||
jsonUser.set("last_name", user_model->getLastName());
|
||||
}
|
||||
else if (parameterString == "user.disabled") {
|
||||
jsonUser.set("disabled", userModel->isDisabled());
|
||||
jsonUser.set("disabled", user_model->isDisabled());
|
||||
}
|
||||
else if (parameterString == "user.email_checked") {
|
||||
jsonUser.set("email_checked", userModel->isEmailChecked());
|
||||
jsonUser.set("email_checked", user_model->isEmailChecked());
|
||||
}
|
||||
else if (parameterString == "user.identHash") {
|
||||
auto email = userModel->getEmail();
|
||||
auto email = user_model->getEmail();
|
||||
jsonUser.set("identHash", DRMakeStringHash(email.data(), email.size()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#define __JSON_INTERFACE_JSON_GET_USER_INFOS_
|
||||
|
||||
#include "JsonRequestHandler.h"
|
||||
|
||||
#include "../model/table/EmailOptIn.h"
|
||||
/*!
|
||||
* @author Dario Rekowski
|
||||
* @date 2020-03-21
|
||||
@ -17,7 +17,7 @@ public:
|
||||
Poco::JSON::Object* handle(Poco::Dynamic::Var params);
|
||||
|
||||
protected:
|
||||
|
||||
Poco::UInt64 readOrCreateEmailVerificationCode(int user_id, model::table::EmailOptInType type);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
#include "JsonLoginViaEmailVerificationCode.h"
|
||||
|
||||
#include "JsonUnsecureLogin.h"
|
||||
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
#include "../SingletonManager/SingletonTaskObserver.h"
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
|
||||
#include "../controller/User.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/JSON/Array.h"
|
||||
|
||||
Poco::JSON::Object* JsonLoginViaEmailVerificationCode::handle(Poco::Dynamic::Var params)
|
||||
{
|
||||
|
||||
auto sm = SessionManager::getInstance();
|
||||
|
||||
/*
|
||||
email verification code
|
||||
*/
|
||||
// incoming
|
||||
unsigned long long code = 0;
|
||||
if (params.isVector()) {
|
||||
const Poco::URI::QueryParameters queryParams = params.extract<Poco::URI::QueryParameters>();
|
||||
std::string codeString;
|
||||
for (auto it = queryParams.begin(); it != queryParams.end(); it++) {
|
||||
if (it->first == "emailVerificationCode") {
|
||||
codeString = it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (codeString == "") {
|
||||
return stateError("emailVerificationCode not found");
|
||||
}
|
||||
if (DataTypeConverter::NUMBER_PARSE_OKAY != DataTypeConverter::strToInt(codeString, code)) {
|
||||
return stateError("couldn't parse emailVerificationCode");
|
||||
}
|
||||
|
||||
}
|
||||
auto session = sm->findByEmailVerificationCode(code);
|
||||
if (!session) {
|
||||
session = sm->getNewSession();
|
||||
if (!session->loadFromEmailVerificationCode(code)) {
|
||||
return stateError("couldn't login with emailVerificationCode");
|
||||
}
|
||||
}
|
||||
session->setClientIp(mClientIP);
|
||||
auto result = new Poco::JSON::Object;
|
||||
result->set("state", "success");
|
||||
result->set("session_id", session->getHandle());
|
||||
result->set("email_verification_code_type", model::table::EmailOptIn::typeToString(session->getEmailVerificationType()));
|
||||
Poco::JSON::Array info;
|
||||
|
||||
if (!session->getNewUser()->getModel()->getPasswordHashed()) {
|
||||
info.add("user hasn't password");
|
||||
}
|
||||
auto update_email_verification_result = session->updateEmailVerification(code);
|
||||
if (1 == update_email_verification_result) {
|
||||
info.add("email already activated");
|
||||
}
|
||||
|
||||
result->set("info", info);
|
||||
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
#ifndef __JSON_INTERFACE_JSON_LOGIN_VIA_EMAIL_VERIFICATION_CODE_
|
||||
#define __JSON_INTERFACE_JSON_LOGIN_VIA_EMAIL_VERIFICATION_CODE_
|
||||
|
||||
#include "JsonRequestHandler.h"
|
||||
|
||||
class JsonLoginViaEmailVerificationCode : public JsonRequestHandler
|
||||
{
|
||||
public:
|
||||
JsonLoginViaEmailVerificationCode(Poco::Net::IPAddress ip) : mClientIP(ip) {}
|
||||
Poco::JSON::Object* handle(Poco::Dynamic::Var params);
|
||||
|
||||
protected:
|
||||
Poco::Net::IPAddress mClientIP;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // __JSON_INTERFACE_JSON_LOGIN_VIA_EMAIL_VERIFICATION_CODE_
|
||||
@ -10,6 +10,7 @@
|
||||
#include "JsonTransaction.h"
|
||||
#include "JsonGetRunningUserTasks.h"
|
||||
#include "JsonGetUsers.h"
|
||||
#include "JsonLoginViaEmailVerificationCode.h"
|
||||
#include "JsonAdminEmailVerificationResend.h"
|
||||
#include "JsonGetUserInfos.h"
|
||||
#include "JsonUpdateUserInfos.h"
|
||||
@ -67,6 +68,9 @@ Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(c
|
||||
else if (url_first_part == "/unsecureLogin" && (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS)) {
|
||||
return new JsonUnsecureLogin(client_host);
|
||||
}
|
||||
else if (url_first_part == "/loginViaEmailVerificationCode") {
|
||||
return new JsonLoginViaEmailVerificationCode(client_host);
|
||||
}
|
||||
else if (url_first_part == "/logout") {
|
||||
return new JsonLogout(client_host);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
#include "../SingletonManager/LanguageManager.h"
|
||||
#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h"
|
||||
|
||||
Poco::JSON::Object* JsonUpdateUserInfos::handle(Poco::Dynamic::Var params)
|
||||
{
|
||||
@ -117,6 +118,34 @@ Poco::JSON::Object* JsonUpdateUserInfos::handle(Poco::Dynamic::Var params)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("User.password" == name && (ServerConfig::g_AllowUnsecureFlags & ServerConfig::UNSECURE_PASSWORD_REQUESTS) == ServerConfig::UNSECURE_PASSWORD_REQUESTS) {
|
||||
if (!value.isString()) {
|
||||
jsonErrorsArray.add("User.password isn't string");
|
||||
}
|
||||
else {
|
||||
ErrorList errors;
|
||||
if (!sm->checkPwdValidation(value.toString(), &errors)) {
|
||||
jsonErrorsArray.add("User.password isn't valid");
|
||||
jsonErrorsArray.add(errors.getErrorsArray());
|
||||
}
|
||||
else {
|
||||
auto result_new_password = user->setNewPassword(value.toString());
|
||||
|
||||
switch (result_new_password) {
|
||||
// 0 = new and current passwords are the same
|
||||
case 0: jsonErrorsArray.add("new password is the same as old password"); break;
|
||||
// 1 = password changed, private key re-encrypted and saved into db
|
||||
//case 1: extractet_values++; break;
|
||||
// 2 = password changed, only hash stored in db, couldn't load private key for re-encryption
|
||||
case 2: jsonErrorsArray.add("password changed, couldn't load private key for re-encryption"); break;
|
||||
// -1 = stored pubkey and private key didn't match
|
||||
case -1: jsonErrorsArray.add("stored pubkey and private key didn't match"); break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
jsonErrorsArray.add("update parameter invalid");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user