mirror of
https://gitea.msk.dinamika-avia.ru/Constanta-Design/RRJServer.git
synced 2026-03-28 19:55:48 +03:00
GUI.Тип ошибки авторизации
This commit is contained in:
@@ -37,16 +37,32 @@ bool InterfaceDataBaseLMS::DBisConnected()
|
||||
|
||||
//Инструкторы
|
||||
|
||||
bool InterfaceDataBaseLMS::authorizationInstructor(QString login, QString password)
|
||||
bool InterfaceDataBaseLMS::authorizationInstructor(QString login, QString password, ErrorAuth& error)
|
||||
{
|
||||
error = ErrorAuth::errNo;
|
||||
|
||||
if(int id = selectUserID(DataBaseLMS::TypeUserDBInstructor, login, password))
|
||||
{
|
||||
if(selectUserArchived(DataBaseLMS::TypeUserDBInstructor, id) || selectUserLoggedIn(DataBaseLMS::TypeUserDBInstructor, id))
|
||||
if(selectUserArchived(DataBaseLMS::TypeUserDBInstructor, id))
|
||||
{
|
||||
error = ErrorAuth::errArchived;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(selectUserLoggedIn(DataBaseLMS::TypeUserDBInstructor, id))
|
||||
{
|
||||
error = ErrorAuth::errAlreadyLogIn;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(updateUserLoggedIn(DataBaseLMS::TypeUserDBInstructor, id, true))
|
||||
return true;
|
||||
else
|
||||
error = ErrorAuth::errDB;
|
||||
}
|
||||
else
|
||||
error = ErrorAuth::errLoginOrPassword;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -118,16 +134,32 @@ bool InterfaceDataBaseLMS::isLoggedInInstructor(int id)
|
||||
|
||||
//Инструкторы
|
||||
|
||||
bool InterfaceDataBaseLMS::authorizationTrainee(QString login, QString password, QString classroom_name, QString computer_name)
|
||||
bool InterfaceDataBaseLMS::authorizationTrainee(QString login, QString password, ErrorAuth& error, QString classroom_name, QString computer_name)
|
||||
{
|
||||
error = ErrorAuth::errNo;
|
||||
|
||||
if(int id = selectUserID(DataBaseLMS::TypeUserDBTrainee, login, password))
|
||||
{
|
||||
if(selectUserArchived(DataBaseLMS::TypeUserDBTrainee, id) || selectUserLoggedIn(DataBaseLMS::TypeUserDBTrainee, id))
|
||||
if(selectUserArchived(DataBaseLMS::TypeUserDBTrainee, id))
|
||||
{
|
||||
error = ErrorAuth::errArchived;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(selectUserLoggedIn(DataBaseLMS::TypeUserDBTrainee, id))
|
||||
{
|
||||
error = ErrorAuth::errAlreadyLogIn;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(updateUserLoggedIn(DataBaseLMS::TypeUserDBTrainee, id, true))
|
||||
return true;
|
||||
else
|
||||
error = ErrorAuth::errDB;
|
||||
}
|
||||
else
|
||||
error = ErrorAuth::errLoginOrPassword;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,15 @@
|
||||
|
||||
class DATABASELMS_EXPORT InterfaceDataBaseLMS : public DataBaseLMS
|
||||
{
|
||||
public:
|
||||
enum ErrorAuth
|
||||
{
|
||||
errNo = 0,
|
||||
errDB,
|
||||
errLoginOrPassword,
|
||||
errArchived,
|
||||
errAlreadyLogIn
|
||||
};
|
||||
public:
|
||||
InterfaceDataBaseLMS(QWidget *ownerWidget, QObject *parent = nullptr);
|
||||
|
||||
@@ -22,7 +31,7 @@ public:
|
||||
|
||||
//Инструкторы
|
||||
|
||||
bool authorizationInstructor(QString login, QString password);
|
||||
bool authorizationInstructor(QString login, QString password, ErrorAuth& error);
|
||||
bool deAuthorizationInstructor(QString login);
|
||||
bool deAuthorizationAllInstructors();
|
||||
|
||||
@@ -43,7 +52,7 @@ public:
|
||||
|
||||
//Обучаемые
|
||||
|
||||
bool authorizationTrainee(QString login, QString password, QString classroom_name, QString computer_name);
|
||||
bool authorizationTrainee(QString login, QString password, ErrorAuth& error, QString classroom_name, QString computer_name);
|
||||
bool deAuthorizationTrainee(QString login);
|
||||
bool deAuthorizationAllTrainees();
|
||||
|
||||
|
||||
@@ -456,16 +456,33 @@ void RecognizeSystem::xmlParser(QByteArray array)
|
||||
|
||||
if(name == "Code")
|
||||
{
|
||||
if (value == "END")
|
||||
if (value == NOTIFY_SERVER_END)
|
||||
{
|
||||
emit sigSocketDisabled();
|
||||
}
|
||||
|
||||
if(value == "BLOCKED")
|
||||
if(value == NOTIFY_SERVER_BLOCKED)
|
||||
{
|
||||
emit sigServerBlocked();
|
||||
}
|
||||
|
||||
if(value == NOTIFY_ERROR_AUTH_DB)
|
||||
{
|
||||
emit sigErrorAuth(value);
|
||||
}
|
||||
if(value == NOTIFY_ERROR_AUTH_LOGINORPASSWORD)
|
||||
{
|
||||
emit sigErrorAuth(value);
|
||||
}
|
||||
if(value == NOTIFY_ERROR_AUTH_ARCHIVED)
|
||||
{
|
||||
emit sigErrorAuth(value);
|
||||
}
|
||||
if(value == NOTIFY_ERROR_AUTH_ALREADYLOGIN)
|
||||
{
|
||||
emit sigErrorAuth(value);
|
||||
}
|
||||
|
||||
if(value == "HASHSENDCOMPLETE")
|
||||
{
|
||||
emit sigStartCompare();
|
||||
|
||||
@@ -34,6 +34,7 @@ signals:
|
||||
void sigSendDebugLog(QString message);
|
||||
void sigSocketDisabled();
|
||||
void sigServerBlocked();
|
||||
void sigErrorAuth(QString error);
|
||||
void sigAuth(ServerAuthorization *serverAuth);
|
||||
void sigDeAuth(ServerDeAuthorization *serverDeAuth);
|
||||
void sigAnswerQueryToDB(QList<Instructor>* listInstructors,
|
||||
|
||||
@@ -71,6 +71,14 @@ enum PacketType{
|
||||
FREE = 155
|
||||
};
|
||||
|
||||
#define NOTIFY_ERROR_AUTH_DB "ERROR_AUTH_DB"
|
||||
#define NOTIFY_ERROR_AUTH_LOGINORPASSWORD "ERROR_AUTH_LOGINORPASSWORD"
|
||||
#define NOTIFY_ERROR_AUTH_ARCHIVED "ERROR_AUTH_ARCHIVED"
|
||||
#define NOTIFY_ERROR_AUTH_ALREADYLOGIN "ERROR_AUTH_ALREADYLOGIN"
|
||||
#define NOTIFY_SERVER_END "END"
|
||||
#define NOTIFY_SERVER_BLOCKED "BLOCKED"
|
||||
#define SERVER_HELLO "NewConnection. I am server LMS!"
|
||||
|
||||
//Q_DECLARE_METATYPE(PacketType)
|
||||
|
||||
class Tools {
|
||||
|
||||
@@ -90,6 +90,11 @@ void ConnectorToServer::slot_ServerBlocked()
|
||||
emit sigServerBlocked();
|
||||
}
|
||||
|
||||
void ConnectorToServer::slot_ErrorAuth(QString error)
|
||||
{
|
||||
emit sigErrorAuth(error);
|
||||
}
|
||||
|
||||
void ConnectorToServer::slot_SendDeleteVersion(StreamingVersionData *streaming)
|
||||
{
|
||||
emit signal_SendDeleteVersion(streaming);
|
||||
@@ -133,6 +138,7 @@ void ConnectorToServer::bindConnection()
|
||||
connect(recognizeSystem,&RecognizeSystem::sigDeAuth,this,&ConnectorToServer::sigDeLoginResult);
|
||||
|
||||
connect(recognizeSystem,&RecognizeSystem::sigServerBlocked,this,&ConnectorToServer::slot_ServerBlocked);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigErrorAuth,this,&ConnectorToServer::slot_ErrorAuth);
|
||||
|
||||
connect(recognizeSystem,&RecognizeSystem::signal_ReceiveMessage,this,&ConnectorToServer::signal_receiveMessage,Qt::AutoConnection);
|
||||
connect(recognizeSystem,&RecognizeSystem::sigShowServerDataList,this,&ConnectorToServer::slot_showServerList);
|
||||
|
||||
@@ -108,6 +108,7 @@ public slots:
|
||||
void slot_HashReady();
|
||||
void slot_Auth(ServerAuthorization * serverAuth);
|
||||
void slot_ServerBlocked();
|
||||
void slot_ErrorAuth(QString error);
|
||||
|
||||
void slot_SendDeleteVersion(StreamingVersionData *streaming);
|
||||
void slot_SendSwitchVersion(StreamingVersionData *selectVersion);
|
||||
@@ -125,6 +126,7 @@ signals:
|
||||
void sigLoginResult(ServerAuthorization * serverAuth);
|
||||
void sigDeLoginResult(ServerDeAuthorization * serverDeAuth);
|
||||
void sigServerBlocked();
|
||||
void sigErrorAuth(QString error);
|
||||
|
||||
void signal_UpdateDB(bool treeInstructor, bool treeTrainee);
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ InstructorsAndTraineesWidget::InstructorsAndTraineesWidget(QWidget *parent) :
|
||||
connect(connectorToServer, &ConnectorToServer::sigLoginResult, this, &InstructorsAndTraineesWidget::slot_checkLoginResult);
|
||||
connect(connectorToServer, &ConnectorToServer::sigDeLoginResult, this, &InstructorsAndTraineesWidget::slot_checkDeLoginResult);
|
||||
connect(connectorToServer, &ConnectorToServer::sigServerBlocked, this, &InstructorsAndTraineesWidget::slot_ServerBlocked);
|
||||
connect(connectorToServer, &ConnectorToServer::sigErrorAuth, this, &InstructorsAndTraineesWidget::slot_ErrorAuth);
|
||||
connect(connectorToServer,&ConnectorToServer::signal_AnswerDocsChanged,this, &InstructorsAndTraineesWidget::slot_AnswerDocsChanged);
|
||||
|
||||
messangerController = new MessangerController(connectorToServer, this);
|
||||
@@ -239,16 +240,14 @@ void InstructorsAndTraineesWidget::slot_checkLoginResult(ServerAuthorization *se
|
||||
viewerInstructors->activate();
|
||||
|
||||
waitAnimationWidget->hideWithStop();
|
||||
|
||||
flTryLogin = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
waitAnimationWidget->hideWithStop();
|
||||
|
||||
ui->btnAuthorizationInstructor->setChecked(false);
|
||||
SpecialMessageBox(this, SpecialMessageBox::TypeSpecMsgBox::critical, tr("Instructor authorization.") + "\n" + tr("Invalid login or password!")).exec();
|
||||
//waitAnimationWidget->hideWithStop();
|
||||
//ui->btnAuthorizationInstructor->setChecked(false);
|
||||
}
|
||||
|
||||
flTryLogin = false;
|
||||
}
|
||||
|
||||
void InstructorsAndTraineesWidget::slot_checkDeLoginResult(ServerDeAuthorization *serverDeAuth)
|
||||
@@ -285,7 +284,39 @@ void InstructorsAndTraineesWidget::slot_ServerBlocked()
|
||||
waitAnimationWidget->hideWithStop();
|
||||
|
||||
ui->btnAuthorizationInstructor->setChecked(false);
|
||||
SpecialMessageBox(this, SpecialMessageBox::TypeSpecMsgBox::warningClose, tr("Server blocked!")).exec();
|
||||
SpecialMessageBox(this, SpecialMessageBox::TypeSpecMsgBox::warningClose, tr("Instructor authorization.") + "\n" + tr("Server blocked!")).exec();
|
||||
}
|
||||
}
|
||||
|
||||
void InstructorsAndTraineesWidget::slot_ErrorAuth(QString error)
|
||||
{
|
||||
if(flTryLogin)
|
||||
{
|
||||
flTryLogin = false;
|
||||
waitAnimationWidget->hideWithStop();
|
||||
|
||||
ui->btnAuthorizationInstructor->setChecked(false);
|
||||
|
||||
QString errorTextMsg = "";
|
||||
|
||||
if(error == NOTIFY_ERROR_AUTH_DB)
|
||||
{
|
||||
errorTextMsg = tr("Database error!");
|
||||
}
|
||||
else if(error == NOTIFY_ERROR_AUTH_ARCHIVED)
|
||||
{
|
||||
errorTextMsg = tr("The user is archived!");
|
||||
}
|
||||
else if(error == NOTIFY_ERROR_AUTH_ALREADYLOGIN)
|
||||
{
|
||||
errorTextMsg = tr("The user is already logged in!");
|
||||
}
|
||||
else if(error == NOTIFY_ERROR_AUTH_LOGINORPASSWORD)
|
||||
{
|
||||
errorTextMsg = tr("Login or password error!");
|
||||
}
|
||||
|
||||
SpecialMessageBox(this, SpecialMessageBox::TypeSpecMsgBox::warningClose, tr("Instructor authorization.") + "\n" + errorTextMsg).exec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ public Q_SLOTS:
|
||||
void slot_checkDeLoginResult(ServerDeAuthorization * serverDeAuth);
|
||||
|
||||
void slot_ServerBlocked();
|
||||
void slot_ErrorAuth(QString error);
|
||||
|
||||
//Слот обработки результата подключения к серверу
|
||||
void slot_ConnectedToServer(bool state);
|
||||
|
||||
@@ -5,9 +5,13 @@
|
||||
#include <QString>
|
||||
#include "typeQueryToDB.h"
|
||||
|
||||
#define NOTIFY_SERVER_END "END"
|
||||
#define NOTIFY_SERVER_BLOCKED "BLOCKED"
|
||||
#define SERVER_HELLO "NewConnection. I am server LMS!"
|
||||
#define NOTIFY_ERROR_AUTH_DB "ERROR_AUTH_DB"
|
||||
#define NOTIFY_ERROR_AUTH_LOGINORPASSWORD "ERROR_AUTH_LOGINORPASSWORD"
|
||||
#define NOTIFY_ERROR_AUTH_ARCHIVED "ERROR_AUTH_ARCHIVED"
|
||||
#define NOTIFY_ERROR_AUTH_ALREADYLOGIN "ERROR_AUTH_ALREADYLOGIN"
|
||||
#define NOTIFY_SERVER_END "END"
|
||||
#define NOTIFY_SERVER_BLOCKED "BLOCKED"
|
||||
#define SERVER_HELLO "NewConnection. I am server LMS!"
|
||||
|
||||
enum EStateServer{started, stoped};
|
||||
enum EStateBlockAutorization{blocked, unblocked};
|
||||
|
||||
@@ -39,8 +39,6 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien
|
||||
{
|
||||
QByteArray arrayAnswer = dataParser->ClientAnswer()->notify(NOTIFY_SERVER_BLOCKED);
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
|
||||
QString str = QString(arrayAnswer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,8 +48,10 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien
|
||||
QByteArray arrayAnswer;
|
||||
int clientID = 0;
|
||||
|
||||
InterfaceDataBaseLMS::ErrorAuth errorAuth = InterfaceDataBaseLMS::ErrorAuth::errNo;
|
||||
|
||||
if(providerDBLMS->authorizationInstructor(clientAutorization.Login, clientAutorization.Password))
|
||||
|
||||
if(providerDBLMS->authorizationInstructor(clientAutorization.Login, clientAutorization.Password, errorAuth))
|
||||
{//Авторизуется инструктор
|
||||
|
||||
client->getClient()->setLogin(clientAutorization.Login);
|
||||
@@ -67,7 +67,7 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien
|
||||
}
|
||||
else if(clientAutorization.TypeClient != TypeClientAutorization::TYPE_GUI)
|
||||
{
|
||||
if(providerDBLMS->authorizationTrainee(clientAutorization.Login, clientAutorization.Password, "", ""))
|
||||
if(providerDBLMS->authorizationTrainee(clientAutorization.Login, clientAutorization.Password, errorAuth, "", ""))
|
||||
{//Авторизуется обучаемый
|
||||
|
||||
client->getClient()->setLogin(clientAutorization.Login);
|
||||
@@ -91,15 +91,42 @@ void ProcessingSystem::processingClientAutorization(ClientHandler *client, Clien
|
||||
arrayAnswer = dataParser->ClientAnswer()->authorization(false, "", "", "", "", 0);
|
||||
}
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
client->sendVersion();
|
||||
|
||||
//client->sendPacketType(PacketType::BUSY);
|
||||
//client->sendPacketType(PacketType::FREE);
|
||||
if(errorAuth == InterfaceDataBaseLMS::ErrorAuth::errNo)
|
||||
{
|
||||
client->sendVersion();
|
||||
|
||||
QString str = QString(arrayAnswer);
|
||||
//logger->addTextToLogger("To Client: " + str);
|
||||
//Извещаем об изменениях в авторизации
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
//client->sendPacketType(PacketType::BUSY);
|
||||
//client->sendPacketType(PacketType::FREE);
|
||||
|
||||
//Извещаем об изменениях в авторизации
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString notifyText = "";
|
||||
|
||||
switch (errorAuth)
|
||||
{
|
||||
case InterfaceDataBaseLMS::ErrorAuth::errDB:
|
||||
notifyText = NOTIFY_ERROR_AUTH_DB;
|
||||
break;
|
||||
case InterfaceDataBaseLMS::ErrorAuth::errArchived:
|
||||
notifyText = NOTIFY_ERROR_AUTH_ARCHIVED;
|
||||
break;
|
||||
case InterfaceDataBaseLMS::ErrorAuth::errAlreadyLogIn:
|
||||
notifyText = NOTIFY_ERROR_AUTH_ALREADYLOGIN;
|
||||
break;
|
||||
case InterfaceDataBaseLMS::ErrorAuth::errLoginOrPassword:
|
||||
notifyText = NOTIFY_ERROR_AUTH_LOGINORPASSWORD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QByteArray arrayAnswer = dataParser->ClientAnswer()->notify(notifyText);
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessingSystem::processingClientDeAutorization(ClientHandler *client, ClientDeAutorization clientDeAutorization)
|
||||
@@ -129,6 +156,10 @@ void ProcessingSystem::processingClientDeAutorization(ClientHandler *client, Cli
|
||||
emit sigUpdateListClients();
|
||||
|
||||
arrayAnswer = dataParser->ClientAnswer()->deAuthorization(true, clientDeAutorization.Login);
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
|
||||
//Извещаем об изменениях в авторизации
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
}
|
||||
else if(providerDBLMS->deAuthorizationInstructor(clientDeAutorization.Login))
|
||||
{//ДеАвторизуется инструктор
|
||||
@@ -139,18 +170,16 @@ void ProcessingSystem::processingClientDeAutorization(ClientHandler *client, Cli
|
||||
emit sigUpdateListClients();
|
||||
|
||||
arrayAnswer = dataParser->ClientAnswer()->deAuthorization(true, clientDeAutorization.Login);
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
|
||||
//Извещаем об изменениях в авторизации
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
}
|
||||
else
|
||||
{//Никто не ДеАвторизовался
|
||||
arrayAnswer = dataParser->ClientAnswer()->deAuthorization(false, "");
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
}
|
||||
client->sendXmlAnswer(arrayAnswer);
|
||||
|
||||
QString str = QString(arrayAnswer);
|
||||
//logger->addTextToLogger("To Client: " + str);
|
||||
|
||||
//Извещаем об изменениях в авторизации
|
||||
emit sigListsInstructorsTraineesChanged();
|
||||
}
|
||||
|
||||
void ProcessingSystem::processingClientBlockAuth(ClientHandler *client, bool block)
|
||||
|
||||
@@ -108,7 +108,7 @@ QString ProviderDBLMS::getMainInstructorName()
|
||||
return QStringLiteral("");
|
||||
}
|
||||
|
||||
bool ProviderDBLMS::authorizationTrainee(QString login, QString password, QString classroom_name, QString computer_name)
|
||||
bool ProviderDBLMS::authorizationTrainee(QString login, QString password, InterfaceDataBaseLMS::ErrorAuth& error, QString classroom_name, QString computer_name)
|
||||
{
|
||||
mtxAccess.lock();
|
||||
|
||||
@@ -120,7 +120,7 @@ bool ProviderDBLMS::authorizationTrainee(QString login, QString password, QStrin
|
||||
|
||||
//Q_EMIT signal_BlockAutorization(true);
|
||||
|
||||
bool res = dbLMS->authorizationTrainee(login, password, classroom_name, computer_name);
|
||||
bool res = dbLMS->authorizationTrainee(login, password, error, classroom_name, computer_name);
|
||||
|
||||
//Q_EMIT signal_BlockAutorization(false);
|
||||
|
||||
@@ -164,7 +164,7 @@ QString ProviderDBLMS::getNameTraineeByLogin(QString login)
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ProviderDBLMS::authorizationInstructor(QString login, QString password)
|
||||
bool ProviderDBLMS::authorizationInstructor(QString login, QString password, InterfaceDataBaseLMS::ErrorAuth& error)
|
||||
{
|
||||
mtxAccess.lock();
|
||||
|
||||
@@ -176,7 +176,7 @@ bool ProviderDBLMS::authorizationInstructor(QString login, QString password)
|
||||
|
||||
//Q_EMIT signal_BlockAutorization(true);
|
||||
|
||||
bool res = dbLMS->authorizationInstructor(login, password);
|
||||
bool res = dbLMS->authorizationInstructor(login, password, error);
|
||||
|
||||
//Q_EMIT signal_BlockAutorization(false);
|
||||
|
||||
|
||||
@@ -16,12 +16,12 @@ public:
|
||||
QString getMainInstructorName();
|
||||
|
||||
//Авторизация обучаемого на клиенте
|
||||
bool authorizationTrainee(QString login, QString password, QString classroom_name = QStringLiteral(""), QString computer_name = QStringLiteral(""));
|
||||
bool authorizationTrainee(QString login, QString password, InterfaceDataBaseLMS::ErrorAuth& error, QString classroom_name = QStringLiteral(""), QString computer_name = QStringLiteral(""));
|
||||
bool deAuthorizationTrainee(QString login);
|
||||
QString getNameTraineeByLogin(QString login);
|
||||
|
||||
//Авторизация инструктора на клиенте
|
||||
bool authorizationInstructor(QString login, QString password);
|
||||
bool authorizationInstructor(QString login, QString password, InterfaceDataBaseLMS::ErrorAuth& error);
|
||||
bool deAuthorizationInstructor(QString login);
|
||||
QString getNameInstructorByLogin(QString login);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user