UsrCod does not exist ini database
static bool API_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** Check if user's code is valid *****/
if (UsrDat->UsrCod <= 0)
return false;
/***** Get some user's data *****/
if (DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT Surname1,Surname2,FirstName,Photo,DATE_FORMAT(Birthday,'%%Y%%m%%d')"
" FROM usr_data WHERE UsrCod=%ld",
UsrDat->UsrCod) != 1)
return false;
/* Read some user's data */
row = mysql_fetch_row (mysql_res);
/* Get user's name */
Str_Copy (UsrDat->Surname1,row[0],
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
Str_Copy (UsrDat->Surname2,row[1],
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
Str_Copy (UsrDat->FirstName,row[2],
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
/* Get user's photo */
Str_Copy (UsrDat->Photo,row[3],
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
/* Get user's brithday */
Dat_GetDateFromYYYYMMDD (&(UsrDat->Birthday),row[4]);
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
/***** Get list of user's IDs *****/
ID_GetListIDsFromUsrCod (UsrDat);
/***** Get user's nickname *****/
Nck_GetNicknameFromUsrCod (UsrDat->UsrCod,UsrDat->Nickname);
/***** Get user's role *****/
/* Query database */
if (CrsCod > 0)
{
/* Get the role in the given course */
if (DB_QuerySELECT (&mysql_res,"can not get user's role",
"SELECT Role FROM crs_usr"
" WHERE CrsCod=%ld AND UsrCod=%ld",
CrsCod,UsrDat->UsrCod)) // User belongs to course
{
row = mysql_fetch_row (mysql_res);
if (row[0])
{
if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) == 1)
UsrDat->Roles.InCurrentCrs.Valid = true;
else
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
}
}
else // Impossible
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
}
}
else // User does not belong to course
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = true;
}
}
else
{
/* Get the maximum role in any course */
if (DB_QuerySELECT (&mysql_res,"can not get user's role",
"SELECT MAX(Role)"
" FROM crs_usr WHERE UsrCod=%ld",
UsrDat->UsrCod) == 1)
{
row = mysql_fetch_row (mysql_res);
if (row[0])
{
if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) == 1)
UsrDat->Roles.InCurrentCrs.Valid = true;
else
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
}
}
else
// MAX(Role) == NULL if user does not belong to any course
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = true;
}
}
else // Impossible
{
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
UsrDat->Roles.InCurrentCrs.Valid = false;
}
}
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
return true;
}
/*****************************************************************************/
/**************************** Get info of my marks ***************************/
/*****************************************************************************/
#define API_CHECK_NEW_ACCOUNT_OK 0
#define API_CHECK_NEW_ACCOUNT_NICKNAME_NOT_VALID -1
#define API_CHECK_NEW_ACCOUNT_NICKNAME_REGISTERED_BY_ANOTHER_USER -2
#define API_CHECK_NEW_ACCOUNT_EMAIL_NOT_VALID -3
#define API_CHECK_NEW_ACCOUNT_EMAIL_REGISTERED_BY_ANOTHER_USER -4
#define API_CHECK_NEW_ACCOUNT_PASSWORD_NOT_VALID -5
int swad__createAccount (struct soap *soap,
char *userNickname,char *userEmail,char *userPassword,char *appKey, // input
struct swad__createAccountOutput *createAccountOut) // output
{
char NewNicknameWithoutArroba[Nck_MAX_BYTES_NICKNAME_FROM_FORM + 1];
char NewEncryptedPassword[Pwd_BYTES_ENCRYPTED_PASSWORD + 1];
int Result;
int ReturnCode;
/***** Initializations *****/
API_Set_gSOAP_RuntimeEnv (soap);
Gbl.WebService.Function = API_createAccount;
/***** Allocate space for strings *****/
createAccountOut->wsKey = (char *) soap_malloc (soap,API_BYTES_WS_KEY + 1);
/***** Default values returned on error *****/
createAccountOut->userCode = 0; // Undefined error
createAccountOut->wsKey[0] = '\0';
/***** Get plugin code *****/
if ((ReturnCode = API_GetPlgCodFromAppKey (soap,(const char *) appKey)) != SOAP_OK)
return ReturnCode;
/***** Check parameters used to create the new account *****/
Result = API_CheckParamsNewAccount (userNickname, // Input
NewNicknameWithoutArroba,// Output
userEmail, // Input-output
userPassword, // Input
NewEncryptedPassword); // Output
if (Result < 0)
{
createAccountOut->userCode = Result;
return SOAP_OK;
}
/***** User's has no ID *****/
Gbl.Usrs.Me.UsrDat.IDs.Num = 0;
Gbl.Usrs.Me.UsrDat.IDs.List = NULL;
/***** Set password to the password typed by the user *****/
Str_Copy (Gbl.Usrs.Me.UsrDat.Password,NewEncryptedPassword,
Pwd_BYTES_ENCRYPTED_PASSWORD);
/***** User does not exist in the platform, so create him/her! *****/
Acc_CreateNewUsr (&Gbl.Usrs.Me.UsrDat,
true); // I am creating my own account
/***** Save nickname *****/
Nck_UpdateNickInDB (Gbl.Usrs.Me.UsrDat.UsrCod,NewNicknameWithoutArroba);
Str_Copy (Gbl.Usrs.Me.UsrDat.Nickname,NewNicknameWithoutArroba,
Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA);
/***** Save email *****/
if (Mai_UpdateEmailInDB (&Gbl.Usrs.Me.UsrDat,userEmail))
{
/* Email updated sucessfully */
Str_Copy (Gbl.Usrs.Me.UsrDat.Email,userEmail,
Cns_MAX_BYTES_EMAIL_ADDRESS);
Gbl.Usrs.Me.UsrDat.EmailConfirmed = false;
}
/***** Copy new user's code *****/
createAccountOut->userCode = Gbl.Usrs.Me.UsrDat.UsrCod;
/***** Generate a key used in subsequents calls to other web services *****/
return API_GenerateNewWSKey (soap,
(long) createAccountOut->userCode,
createAccountOut->wsKey);
}
/*****************************************************************************/
/************* Get parameters for the creation of a new account **************/
/*****************************************************************************/
// Return false on error
//char *userNickname,char *userEmail,char *userID,char *userPassword
static int API_CheckParamsNewAccount (char *NewNicknameWithArroba, // Input
char NewNicknameWithoutArroba[Nck_MAX_BYTES_NICKNAME_FROM_FORM + 1], // Output
char *NewEmail, // Input-output
char *NewPlainPassword, // Input
char *NewEncryptedPassword) // Output
{
/***** Step 1/3: Check new nickname *****/
/* Make a copy without possible starting arrobas */
Str_Copy (NewNicknameWithoutArroba,NewNicknameWithArroba,
Nck_MAX_BYTES_NICKNAME_FROM_FORM);
if (Nck_CheckIfNickWithArrobaIsValid (NewNicknameWithArroba)) // If new nickname is valid
{
/***** Remove arrobas at the beginning *****/
Str_RemoveLeadingArrobas (NewNicknameWithoutArroba);
/***** Check if the new nickname matches any of the nicknames of other users *****/
if (DB_QueryCOUNT ("can not check if nickname already existed",
"SELECT COUNT(*) FROM usr_nicknames"
" WHERE Nickname='%s'",
NewNicknameWithoutArroba)) // A nickname of another user is the same that this nickname
return API_CHECK_NEW_ACCOUNT_NICKNAME_REGISTERED_BY_ANOTHER_USER;
}
else // New nickname is not valid
return API_CHECK_NEW_ACCOUNT_NICKNAME_NOT_VALID;
/***** Step 2/3: Check new email *****/
if (Mai_CheckIfEmailIsValid (NewEmail)) // New email is valid
{
/***** Check if the new email matches any of the confirmed emails of other users *****/
if (DB_QueryCOUNT ("can not check if email already existed",
"SELECT COUNT(*) FROM usr_emails"
" WHERE E_mail='%s' AND Confirmed='Y'",
NewEmail)) // An email of another user is the same that my email
return API_CHECK_NEW_ACCOUNT_EMAIL_REGISTERED_BY_ANOTHER_USER;
}
else // New email is not valid
return API_CHECK_NEW_ACCOUNT_EMAIL_NOT_VALID;
/***** Step 3/3: Check new password *****/
Cry_EncryptSHA512Base64 (NewPlainPassword,NewEncryptedPassword);
if (!Pwd_SlowCheckIfPasswordIsGood (NewPlainPassword,NewEncryptedPassword,-1L)) // New password is good?
return API_CHECK_NEW_ACCOUNT_PASSWORD_NOT_VALID;
return API_CHECK_NEW_ACCOUNT_OK;
}
/*****************************************************************************/
/****************** Login user by user, password and key *********************/
/*****************************************************************************/
int swad__loginByUserPasswordKey (struct soap *soap,
char *userID,char *userPassword,char *appKey, // input
struct swad__loginByUserPasswordKeyOutput *loginByUserPasswordKeyOut) // output
{
char UsrIDNickOrEmail[Cns_MAX_BYTES_EMAIL_ADDRESS + 1];
int ReturnCode;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumRows;
char PhotoURL[Cns_MAX_BYTES_WWW + 1];
bool UsrFound;
/***** Initializations *****/
API_Set_gSOAP_RuntimeEnv (soap);
Gbl.WebService.Function = API_loginByUserPasswordKey;
/***** Allocate space for strings *****/
loginByUserPasswordKeyOut->wsKey = (char *) soap_malloc (soap,API_BYTES_WS_KEY + 1);
loginByUserPasswordKeyOut->userNickname = (char *) soap_malloc (soap,Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA + 1);
loginByUserPasswordKeyOut->userID = (char *) soap_malloc (soap,ID_MAX_BYTES_USR_ID + 1);
loginByUserPasswordKeyOut->userFirstname = (char *) soap_malloc (soap,Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1);
loginByUserPasswordKeyOut->userSurname1 = (char *) soap_malloc (soap,Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1);
loginByUserPasswordKeyOut->userSurname2 = (char *) soap_malloc (soap,Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1);
loginByUserPasswordKeyOut->userPhoto = (char *) soap_malloc (soap,Cns_MAX_BYTES_WWW + 1);
loginByUserPasswordKeyOut->userBirthday = (char *) soap_malloc (soap,Dat_LENGTH_YYYYMMDD + 1);
/***** Default values returned on error *****/
loginByUserPasswordKeyOut->userCode = -1;
loginByUserPasswordKeyOut->wsKey[0] = '\0';
loginByUserPasswordKeyOut->userNickname[0] = '\0';
loginByUserPasswordKeyOut->userID[0] = '\0';
loginByUserPasswordKeyOut->userFirstname[0] = '\0';
loginByUserPasswordKeyOut->userSurname1[0] = '\0';
loginByUserPasswordKeyOut->userSurname2[0] = '\0';
loginByUserPasswordKeyOut->userPhoto[0] = '\0';
loginByUserPasswordKeyOut->userBirthday[0] = '\0';
loginByUserPasswordKeyOut->userRole = 0; // unknown
/***** Get plugin code *****/
if ((ReturnCode = API_GetPlgCodFromAppKey (soap,
(const char *) appKey)) != SOAP_OK)
return ReturnCode;
/***** Check if user's email, @nickname or ID are valid *****/
Str_Copy (UsrIDNickOrEmail,userID,
Cns_MAX_BYTES_EMAIL_ADDRESS);
if (Nck_CheckIfNickWithArrobaIsValid (UsrIDNickOrEmail)) // 1: It's a nickname
{
Str_RemoveLeadingArrobas (UsrIDNickOrEmail);
/* User has typed a nickname */
NumRows =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT usr_nicknames.UsrCod"
" FROM usr_nicknames,usr_data"
" WHERE usr_nicknames.Nickname='%s'"
" AND usr_nicknames.UsrCod=usr_data.UsrCod"
" AND usr_data.Password='%s'",
UsrIDNickOrEmail,userPassword);
}
else if (Mai_CheckIfEmailIsValid (UsrIDNickOrEmail)) // 2: It's an email
{
/* User has typed an email */
// TODO: Get only if email confirmed?
NumRows =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT usr_emails.UsrCod"
" FROM usr_emails,usr_data"
" WHERE usr_emails.E_mail='%s'"
" AND usr_emails.UsrCod=usr_data.UsrCod"
" AND usr_data.Password='%s'",
UsrIDNickOrEmail,userPassword);
}
else // 3: It's not a nickname nor email
{
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (UsrIDNickOrEmail);
Str_ConvertToUpperText (UsrIDNickOrEmail);
if (ID_CheckIfUsrIDIsValid (UsrIDNickOrEmail))
{
/* User has typed a valid user's ID (existing or not) */
// TODO: Get only if ID confirmed?
NumRows =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT usr_IDs.UsrCod"
" FROM usr_IDs,usr_data"
" WHERE usr_IDs.UsrID='%s'"
" AND usr_IDs.UsrCod=usr_data.UsrCod"
" AND usr_data.Password='%s'",
UsrIDNickOrEmail,userPassword);
}
else // String is not a valid user's nickname, email or ID
return soap_receiver_fault (soap,
"Bad log in",
"User's ID or nickname don't exist or password is wrong");
}
/***** Get user's data from database *****/
if (NumRows == 1) // User found in table of users' data
{
row = mysql_fetch_row (mysql_res);
/***** Get user code (row[0]) *****/
Gbl.Usrs.Me.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/***** Get user's data *****/
UsrFound = API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,-1L); // Get some user's data from database
}
else
UsrFound = false;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
if (UsrFound)
{
Gbl.Usrs.Me.Logged = true;
Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
loginByUserPasswordKeyOut->userCode = (int) Gbl.Usrs.Me.UsrDat.UsrCod;
Str_Copy (loginByUserPasswordKeyOut->userNickname,
Gbl.Usrs.Me.UsrDat.Nickname,
Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA);
if (Gbl.Usrs.Me.UsrDat.IDs.Num)
Str_Copy (loginByUserPasswordKeyOut->userID,
Gbl.Usrs.Me.UsrDat.IDs.List[0].ID, // TODO: What user's ID?
ID_MAX_BYTES_USR_ID);
Str_Copy (loginByUserPasswordKeyOut->userSurname1,
Gbl.Usrs.Me.UsrDat.Surname1,
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
Str_Copy (loginByUserPasswordKeyOut->userSurname2,
Gbl.Usrs.Me.UsrDat.Surname2,
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
Str_Copy (loginByUserPasswordKeyOut->userFirstname,
Gbl.Usrs.Me.UsrDat.FirstName,
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
Pho_BuildLinkToPhoto (&Gbl.Usrs.Me.UsrDat,PhotoURL);
Str_Copy (loginByUserPasswordKeyOut->userPhoto,PhotoURL,
Cns_MAX_BYTES_WWW);
Str_Copy (loginByUserPasswordKeyOut->userBirthday,
Gbl.Usrs.Me.UsrDat.Birthday.YYYYMMDD,
Dat_LENGTH_YYYYMMDD);
loginByUserPasswordKeyOut->userRole = API_RolRole_to_SvcRole[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role];
/***** Generate a key used in subsequents calls to other web services *****/
return API_GenerateNewWSKey (soap,
(long) loginByUserPasswordKeyOut->userCode,
loginByUserPasswordKeyOut->wsKey);
}
else
{
loginByUserPasswordKeyOut->userCode = -1;
loginByUserPasswordKeyOut->userID = NULL;
loginByUserPasswordKeyOut->userSurname1 = NULL;
loginByUserPasswordKeyOut->userSurname2 = NULL;
loginByUserPasswordKeyOut->userFirstname = NULL;
loginByUserPasswordKeyOut->userPhoto = NULL;
loginByUserPasswordKeyOut->userRole = 0;
return soap_receiver_fault (soap,
"Bad log in",
"User's ID or nickname don't exist or password is wrong");
}
}
/*****************************************************************************/
/************************** Login user by session ****************************/
/*****************************************************************************/
int swad__loginBySessionKey (struct soap *soap,
char *sessionID,char *appKey, // input
struct swad__loginBySessionKeyOutput *loginBySessionKeyOut) // output
{
int ReturnCode;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumRows;
char PhotoURL[Cns_MAX_BYTES_WWW + 1];
bool UsrFound;
/***** Initializations *****/
API_Set_gSOAP_RuntimeEnv (soap);
Gbl.WebService.Function = API_loginBySessionKey;
/***** Allocate space for strings *****/
loginBySessionKeyOut->wsKey = (char *) soap_malloc (soap,API_BYTES_WS_KEY + 1);
loginBySessionKeyOut->userNickname = (char *) soap_malloc (soap,Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA + 1);
loginBySessionKeyOut->userID = (char *) soap_malloc (soap,ID_MAX_BYTES_USR_ID + 1);
loginBySessionKeyOut->userFirstname = (char *) soap_malloc (soap,Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1);
loginBySessionKeyOut->userSurname1 = (char *) soap_malloc (soap,Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1);
loginBySessionKeyOut->userSurname2 = (char *) soap_malloc (soap,Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1);
loginBySessionKeyOut->userPhoto = (char *) soap_malloc (soap,Cns_MAX_BYTES_WWW + 1);
loginBySessionKeyOut->userBirthday = (char *) soap_malloc (soap,Dat_LENGTH_YYYYMMDD + 1);
loginBySessionKeyOut->degreeName = (char *) soap_malloc (soap,Hie_MAX_BYTES_FULL_NAME + 1);
loginBySessionKeyOut->courseName = (char *) soap_malloc (soap,Hie_MAX_BYTES_FULL_NAME + 1);
/***** Default values returned on error *****/
loginBySessionKeyOut->userCode = -1;
loginBySessionKeyOut->degreeCode = -1;
loginBySessionKeyOut->courseCode = -1;
loginBySessionKeyOut->wsKey[0] = '\0';
loginBySessionKeyOut->userNickname[0] = '\0';
loginBySessionKeyOut->userID[0] = '\0';
loginBySessionKeyOut->userFirstname[0] = '\0';
loginBySessionKeyOut->userSurname1[0] = '\0';
loginBySessionKeyOut->userSurname2[0] = '\0';
loginBySessionKeyOut->userPhoto[0] = '\0';
loginBySessionKeyOut->userBirthday[0] = '\0';
loginBySessionKeyOut->userRole = Rol_UNK;
loginBySessionKeyOut->degreeName[0] = '\0';
loginBySessionKeyOut->courseName[0] = '\0';
/***** Get plugin code *****/
if ((ReturnCode = API_GetPlgCodFromAppKey (soap,
(const char *) appKey)) != SOAP_OK)
return ReturnCode;
/***** Check length of session identifier *****/
if (sessionID == NULL)
return soap_sender_fault (soap,
"SessionID is null",
"Login by session");
/***** Check session identifier coming from an external plugin *****/
if ((ReturnCode = API_CheckIdSession (soap,sessionID)) != SOAP_OK)
return ReturnCode;
// Now, we know that sessionID is a valid session identifier
/***** Query data of the session from database *****/
NumRows =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get session data",
"SELECT UsrCod,DegCod,CrsCod FROM sessions"
" WHERE SessionId='%s'",
sessionID);
if (NumRows == 1) // Session found in table of sessions
{
row = mysql_fetch_row (mysql_res);
/***** Get course (row[2]) *****/
Gbl.Hierarchy.Crs.CrsCod = Str_ConvertStrCodToLongCod (row[2]);
Crs_GetDataOfCourseByCod (&Gbl.Hierarchy.Crs);
loginBySessionKeyOut->courseCode = (int) Gbl.Hierarchy.Crs.CrsCod;
Str_Copy (loginBySessionKeyOut->courseName,Gbl.Hierarchy.Crs.FullName,
Hie_MAX_BYTES_FULL_NAME);
/***** Get user code (row[0]) *****/
Gbl.Usrs.Me.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
UsrFound = API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Gbl.Hierarchy.Crs.CrsCod); // Get some user's data from database
/***** Get degree (row[1]) *****/
Gbl.Hierarchy.Deg.DegCod = Str_ConvertStrCodToLongCod (row[1]);
Deg_GetDataOfDegreeByCod (&Gbl.Hierarchy.Deg);
loginBySessionKeyOut->degreeCode = (int) Gbl.Hierarchy.Deg.DegCod;
Str_Copy (loginBySessionKeyOut->degreeName,Gbl.Hierarchy.Deg.FullName,
Hie_MAX_BYTES_FULL_NAME);
}
else
UsrFound = false;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** Get degree of current course *****/
if ((ReturnCode = API_GetCurrentDegCodFromCurrentCrsCod ()) != SOAP_OK)
return ReturnCode;
if (UsrFound)
{
Gbl.Usrs.Me.Logged = true;
Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
loginBySessionKeyOut->userCode = (int) Gbl.Usrs.Me.UsrDat.UsrCod;
Str_Copy (loginBySessionKeyOut->userNickname,Gbl.Usrs.Me.UsrDat.Nickname,
Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA);
if (Gbl.Usrs.Me.UsrDat.IDs.Num)
Str_Copy (loginBySessionKeyOut->userID,
Gbl.Usrs.Me.UsrDat.IDs.List[0].ID, // TODO: What user's ID?
ID_MAX_BYTES_USR_ID);
Str_Copy (loginBySessionKeyOut->userSurname1,
Gbl.Usrs.Me.UsrDat.Surname1,
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
Str_Copy (loginBySessionKeyOut->userSurname2,
Gbl.Usrs.Me.UsrDat.Surname2,
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
Str_Copy (loginBySessionKeyOut->userFirstname,
Gbl.Usrs.Me.UsrDat.FirstName,
Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME);
Pho_BuildLinkToPhoto (&Gbl.Usrs.Me.UsrDat,PhotoURL);
Str_Copy (loginBySessionKeyOut->userPhoto,PhotoURL,
Cns_MAX_BYTES_WWW);
Str_Copy (loginBySessionKeyOut->userBirthday,
Gbl.Usrs.Me.UsrDat.Birthday.YYYYMMDD,
Dat_LENGTH_YYYYMMDD);
loginBySessionKeyOut->userRole = API_RolRole_to_SvcRole[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role];
/***** Generate a key used in subsequents calls to other web services *****/
return API_GenerateNewWSKey (soap,
(long) loginBySessionKeyOut->userCode,
loginBySessionKeyOut->wsKey);
}
else
return soap_receiver_fault (soap,
"Bad session identifier",
"Session identifier does not exist in database");
}
/*****************************************************************************/
/*********************** Send a new password by email ************************/
/*****************************************************************************/
int swad__getNewPassword (struct soap *soap,
char *userID,char *appKey, // input
struct swad__getNewPasswordOutput *getNewPasswordOut) // output
{
int ReturnCode;
char UsrIDNickOrEmail[Cns_MAX_BYTES_EMAIL_ADDRESS + 1];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumRows;
char NewRandomPlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1];
/***** Initializations *****/
API_Set_gSOAP_RuntimeEnv (soap);
Gbl.WebService.Function = API_getNewPassword;
/***** Default values returned on error *****/
getNewPasswordOut->success = 0; // error
/***** Get plugin code *****/
if ((ReturnCode = API_GetPlgCodFromAppKey (soap,
(const char *) appKey)) != SOAP_OK)
return ReturnCode;
/***** Check if user's email, @nickname or ID are valid *****/
Str_Copy (UsrIDNickOrEmail,userID,
Cns_MAX_BYTES_EMAIL_ADDRESS);
if (Nck_CheckIfNickWithArrobaIsValid (UsrIDNickOrEmail)) // 1: It's a nickname
{
Str_RemoveLeadingArrobas (UsrIDNickOrEmail);
/* User has typed a nickname */
NumRows =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT UsrCod FROM usr_nicknames"
" WHERE Nickname='%s'",
UsrIDNickOrEmail);
}
else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 2: It's an email
{
/* User has typed an email */
// TODO: Get only if email confirmed?
NumRows =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT UsrCod FROM usr_emails"
" WHERE E_mail='%s'",
UsrIDNickOrEmail);
}
else // 3: It's not a nickname nor email
{
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (UsrIDNickOrEmail);
Str_ConvertToUpperText (UsrIDNickOrEmail);
if (ID_CheckIfUsrIDIsValid (UsrIDNickOrEmail))
{
/* User has typed a valid user's ID (existing or not) */
// TODO: Get only if ID confirmed?
NumRows =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's data",
"SELECT UsrCod FROM usr_IDs"
" WHERE UsrID='%s'",
UsrIDNickOrEmail);
}
else // String is not a valid user's nickname, email or ID
return soap_receiver_fault (soap,
"Bad log in",
"User's email, nickname or ID don't exist");
}
/***** Get user's data from database *****/
if (NumRows == 1) // One unique user found in table of users' data
{
row = mysql_fetch_row (mysql_res);
/***** Get user code (row[0]) *****/
Gbl.Usrs.Me.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
Usr_GetUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Usr_DONT_GET_PREFS); // Get my data
if (Gbl.Usrs.Me.UsrDat.Email[0])
if (Pwd_SendNewPasswordByEmail (NewRandomPlainPassword) == 0) // Message sent successfully
{
Pwd_SetMyPendingPassword (NewRandomPlainPassword);
getNewPasswordOut->success = 1;
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return SOAP_OK;
}
/*****************************************************************************/
/************************ Return courses of a user ***************************/
/*****************************************************************************/
int swad__getCourses (struct soap *soap,
char *wsKey, // input
struct swad__getCoursesOutput *getCoursesOut) // output
{
int ReturnCode;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumRow;
unsigned NumRows;
Rol_Role_t Role;
/***** Initializations *****/
API_Set_gSOAP_RuntimeEnv (soap);
Gbl.WebService.Function = API_getCourses;
/***** Check web service key *****/
if ((ReturnCode = API_CheckWSKey (wsKey)) != SOAP_OK)
return ReturnCode;
if (Gbl.Usrs.Me.UsrDat.UsrCod < 0) // Web service key does not exist in database
return soap_receiver_fault (soap,
"Bad web service key",
"Web service key does not exist in database");
/***** Get some of my data *****/
if (!API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,-1L))
return soap_receiver_fault (soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Query my courses from database *****/
NumRows =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's courses",
"SELECT courses.CrsCod,"
"courses.ShortName,"
"courses.FullName,"
"crs_usr.Role"
" FROM crs_usr,courses"
" WHERE crs_usr.UsrCod=%ld"
" AND crs_usr.CrsCod=courses.CrsCod"
" ORDER BY courses.FullName",
Gbl.Usrs.Me.UsrDat.UsrCod);
getCoursesOut->numCourses = (int) NumRows;
getCoursesOut->coursesArray.__size = (int) NumRows;
if (NumRows == 0)
getCoursesOut->coursesArray.__ptr = NULL;
else // Courses found
{
getCoursesOut->coursesArray.__ptr = soap_malloc (soap,
(getCoursesOut->coursesArray.__size) *
sizeof (*(getCoursesOut->coursesArray.__ptr)));
for (NumRow = 0;
NumRow < NumRows;
NumRow++)
{
/* Get next course */
row = mysql_fetch_row (mysql_res);
/* Get course code (row[0]) */
getCoursesOut->coursesArray.__ptr[NumRow].courseCode = (int) Str_ConvertStrCodToLongCod (row[0]);
/* Get course short name (row[1]) */
getCoursesOut->coursesArray.__ptr[NumRow].courseShortName =
(char *) soap_malloc (soap,Hie_MAX_BYTES_SHRT_NAME + 1);
Str_Copy (getCoursesOut->coursesArray.__ptr[NumRow].courseShortName,row[1],
Hie_MAX_BYTES_SHRT_NAME);
/* Get course full name (row[2]) */
getCoursesOut->coursesArray.__ptr[NumRow].courseFullName =
(char *) soap_malloc (soap,Hie_MAX_BYTES_FULL_NAME + 1);
Str_Copy (getCoursesOut->coursesArray.__ptr[NumRow].courseFullName,row[2],
Hie_MAX_BYTES_FULL_NAME);
/* Get role (row[3]) */
if (sscanf (row[3],"%u",&Role) != 1) // Role in this course
Role = Rol_UNK;
getCoursesOut->coursesArray.__ptr[NumRow].userRole = API_RolRole_to_SvcRole[Role];
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return SOAP_OK;
}
/*****************************************************************************/
/************************ Return course information **************************/
/*****************************************************************************/
// TODO: Not completely implemented
int swad__getCourseInfo (struct soap *soap,
char *wsKey,int courseCode,char *infoType, // input
struct swad__getCourseInfoOutput *getCourseInfo) // output
{
int ReturnCode;
struct Syl_Syllabus Syllabus;
Inf_InfoType_t InfoType;
size_t Length;
Inf_InfoSrc_t InfoSrc;
bool MustBeRead;
int Result = SOAP_OK;
const char *NamesInWSForInfoType[Inf_NUM_INFO_TYPES] =
{
[Inf_INTRODUCTION ] = "introduction",
[Inf_TEACHING_GUIDE] = "guide",
[Inf_LECTURES ] = "lectures",
[Inf_PRACTICALS ] = "practicals",
[Inf_BIBLIOGRAPHY ] = "bibliography",
[Inf_FAQ ] = "FAQ",
[Inf_LINKS ] = "links",
[Inf_ASSESSMENT ] = "assessment",
};
const char *NamesInWSForInfoSrc[Inf_NUM_INFO_SOURCES] =
{
[Inf_INFO_SRC_NONE ] = "none",
[Inf_INFO_SRC_EDITOR ] = "editor",
[Inf_INFO_SRC_PLAIN_TEXT] = "plainText",
[Inf_INFO_SRC_RICH_TEXT ] = "richText",
[Inf_INFO_SRC_PAGE ] = "page",
[Inf_INFO_SRC_URL ] = "URL",
};
/***** Initializations *****/
API_Set_gSOAP_RuntimeEnv (soap);
Gbl.WebService.Function = API_getCourseInfo;
Gbl.Hierarchy.Crs.CrsCod = (long) courseCode;
/***** Check web service key *****/
if ((ReturnCode = API_CheckWSKey (wsKey)) != SOAP_OK)
return ReturnCode;
if (Gbl.Usrs.Me.UsrDat.UsrCod < 0) // Web service key does not exist in database
return soap_receiver_fault (soap,
"Bad web service key",
"Web service key does not exist in database");
/***** Check course and group codes *****/
if ((ReturnCode = API_CheckCourseAndGroupCodes (soap,
Gbl.Hierarchy.Crs.CrsCod,
-1L)) != SOAP_OK)
return ReturnCode;
/***** Get some of my data *****/
if (!API_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Gbl.Hierarchy.Crs.CrsCod))
return soap_receiver_fault (soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (soap,
"Request forbidden",
"Requester must belong to course");
/***** Reset syllabus context *****/
Syl_ResetSyllabus (&Syllabus);
/***** Get info source *****/
for (InfoType = (Inf_InfoType_t) 0;
InfoType <= (Inf_InfoType_t) (Inf_NUM_INFO_TYPES - 1);
InfoType++)
if (!strcmp (infoType,NamesInWSForInfoType[InfoType]))
break;
if (InfoType == Inf_NUM_INFO_TYPES) // Not found!
return soap_receiver_fault (soap,
"Bad info type",
"Unknown requested info type");
Gbl.Crs.Info.Type = InfoType;
Inf_GetAndCheckInfoSrcFromDB (&Syllabus,
Gbl.Hierarchy.Crs.CrsCod,
Gbl.Crs.Info.Type,
&InfoSrc,&MustBeRead);
Length = strlen (NamesInWSForInfoSrc[InfoSrc]);
getCourseInfo->infoSrc = (char *) soap_malloc (soap,Length + 1);
Str_Copy (getCourseInfo->infoSrc,NamesInWSForInfoSrc[InfoSrc],
Length);
/***** Set paths *****/
Hie_InitHierarchy ();
/***** Get info text *****/
getCourseInfo->infoTxt = NULL;
switch (InfoSrc)
{
case Inf_INFO_SRC_NONE: // No info available
break;
case Inf_INFO_SRC_EDITOR: // Internal editor (only for syllabus)
switch (Gbl.Crs.Info.Type)
{
case Inf_LECTURES: // Syllabus (lectures)
case Inf_PRACTICALS: // Syllabys (practicals)
Result = API_WriteSyllabusIntoHTMLBuffer (soap,&Syllabus,&(getCourseInfo->infoTxt));
break;
default:
break;
}
break;
case Inf_INFO_SRC_PLAIN_TEXT: // Plain text
case Inf_INFO_SRC_RICH_TEXT: // Rich text (not yet available)
Result = API_WritePlainTextIntoHTMLBuffer (soap,&(getCourseInfo->infoTxt));
break;
case Inf_INFO_SRC_PAGE: // Web page hosted in SWAD server
Result = API_WritePageIntoHTMLBuffer (soap,&(getCourseInfo->infoTxt));
break;
case Inf_INFO_SRC_URL: // Link to a web page
getCourseInfo->infoTxt = (char *) soap_malloc (soap,Cns_MAX_BYTES_WWW + 1);
Inf_WriteURLIntoTxtBuffer (getCourseInfo->infoTxt);
break;
}
/***** Return empty text if pointer is null *****/
if (getCourseInfo->infoTxt == NULL)
{
getCourseInfo->infoTxt = (char *) soap_malloc (soap,1);
getCourseInfo->infoTxt[0] = '\0';
}
return Result;
}
/*****************************************************************************/
/************** Write the syllabus into a temporary HTML file ****************/
/*****************************************************************************/
static int API_WriteSyllabusIntoHTMLBuffer (struct soap *soap,
struct Syl_Syllabus *Syllabus,
char **HTMLBuffer)
{
extern struct LstItemsSyllabus Syl_LstItemsSyllabus;
char FileNameHTMLTmp[PATH_MAX + 1];
FILE *FileHTMLTmp;
size_t Length;
/***** Initialize buffer *****/
*HTMLBuffer = NULL;
/***** Load syllabus from XML file to list of items in memory *****/
Syl_LoadListItemsSyllabusIntoMemory (Syllabus,Gbl.Hierarchy.Crs.CrsCod);
if (Syl_LstItemsSyllabus.NumItems)
{
/***** Create a unique name for the file *****/
snprintf (FileNameHTMLTmp,sizeof (FileNameHTMLTmp),
"%s/%s_syllabus.html",
Cfg_PATH_OUT_PRIVATE,Gbl.UniqueNameEncrypted);
/***** Create a new temporary file for writing and reading *****/
if ((FileHTMLTmp = fopen (FileNameHTMLTmp,"w+b")) == NULL)
{
Syl_FreeListItemsSyllabus ();
return soap_receiver_fault (soap,
"Syllabus can not be copied into buffer",
"Can not create temporary file");
}
/***** Write syllabus in HTML into a temporary file *****/
Syl_WriteSyllabusIntoHTMLTmpFile (FileHTMLTmp);
/***** Write syllabus from list of items in memory to text buffer *****/
/* Compute length of file */
Length = (size_t) ftell (FileHTMLTmp);
/* Allocate memory for buffer */
if ((*HTMLBuffer = (char *) malloc (Length + 1)) == NULL)
{
fclose (FileHTMLTmp);
unlink (FileNameHTMLTmp);
Syl_FreeListItemsSyllabus ();
return soap_receiver_fault (soap,
"Syllabus can not be copied into buffer",
"Not enough memory for buffer");
}
/* Copy file content into buffer */
fseek (FileHTMLTmp,0L,SEEK_SET);
if (fread (*HTMLBuffer,sizeof (char),Length,FileHTMLTmp) != Length)
{
fclose (FileHTMLTmp);
unlink (FileNameHTMLTmp);
Syl_FreeListItemsSyllabus ();
return soap_receiver_fault (soap,
"Syllabus can not be copied into buffer",
"Error reading file into buffer");
}
(*HTMLBuffer)[Length] = '\0';
/***** Close and remove temporary file *****/
fclose (FileHTMLTmp);
unlink (FileNameHTMLTmp);
}
/***** Free list of items *****/
Syl_FreeListItemsSyllabus ();
return SOAP_OK;
}
/*****************************************************************************/
/************* Check if exists and write page into HTML buffer ***************/
/*****************************************************************************/
static int API_WritePlainTextIntoHTMLBuffer (struct soap *soap,
char **HTMLBuffer)
{
extern const char *Txt_INFO_TITLE[Inf_NUM_INFO_TYPES];
char TxtHTML[Cns_MAX_BYTES_LONG_TEXT + 1];
char FileNameHTMLTmp[PATH_MAX + 1];
FILE *FileHTMLTmp;
size_t Length;
/***** Initialize buffer *****/
*HTMLBuffer = NULL;
/***** Get info text from database *****/
Inf_GetInfoTxtFromDB (Gbl.Hierarchy.Crs.CrsCod,Gbl.Crs.Info.Type,
TxtHTML,NULL);
if (TxtHTML[0])
{
/***** Create a unique name for the file *****/
snprintf (FileNameHTMLTmp,sizeof (FileNameHTMLTmp),
"%s/%s_info.html",
Cfg_PATH_OUT_PRIVATE,Gbl.UniqueNameEncrypted);
/***** Create a new temporary file for writing and reading *****/
if ((FileHTMLTmp = fopen (FileNameHTMLTmp,"w+b")) == NULL)
return soap_receiver_fault (soap,
"Plain text can not be copied into buffer",
"Can not create temporary file");
/***** Write start of HTML code *****/
Lay_StartHTMLFile (FileHTMLTmp,Txt_INFO_TITLE[Gbl.Crs.Info.Type]);
fprintf (FileHTMLTmp,"\n"
"\n");
/***** Write plain text into text buffer *****/
/* Convert to respectful HTML and insert links */
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
TxtHTML,Cns_MAX_BYTES_LONG_TEXT,false); // Convert from HTML to recpectful HTML
Str_InsertLinks (TxtHTML,Cns_MAX_BYTES_LONG_TEXT,60); // Insert links
/* Write text */
fprintf (FileHTMLTmp,"%s",TxtHTML);
/***** Write end of page into file *****/
fprintf (FileHTMLTmp,"
\n"
"\n"
"