swad-core/swad_ID.c

1105 lines
37 KiB
C
Raw Normal View History

2014-12-01 23:55:08 +01:00
// swad_ID.c: Users' IDs
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
2019-01-07 21:52:19 +01:00
Copyright (C) 1999-2019 Antonio Ca<EFBFBD>as Vargas
2014-12-01 23:55:08 +01:00
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#include <ctype.h> // For isalnum, isdigit, etc.
2015-10-16 02:24:29 +02:00
#include <stdbool.h> // For boolean type
2014-12-01 23:55:08 +01:00
#include <stdlib.h> // For exit, system, malloc, free, rand, etc.
#include <string.h> // For string functions
2014-12-12 22:39:55 +01:00
#include "swad_account.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2014-12-01 23:55:08 +01:00
#include "swad_database.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-01 23:55:08 +01:00
#include "swad_global.h"
#include "swad_ID.h"
#include "swad_parameter.h"
#include "swad_QR.h"
2017-06-11 20:09:59 +02:00
#include "swad_table.h"
2014-12-01 23:55:08 +01:00
#include "swad_user.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
#define ID_MAX_IDS_PER_USER 3 // Maximum number of IDs per user
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
2018-10-16 01:36:13 +02:00
const char *ID_ID_SECTION_ID = "id_section";
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static bool ID_CheckIfUsrIDIsValidUsingMinDigits (const char *UsrID,unsigned MinDigits);
2017-05-09 20:56:02 +02:00
static void ID_PutLinkToConfirmID (struct UsrData *UsrDat,unsigned NumID,
const char *Anchor);
2016-04-23 19:59:45 +02:00
2018-10-15 14:07:12 +02:00
static void ID_ShowFormChangeUsrID (const struct UsrData *UsrDat,
2019-02-15 21:09:18 +01:00
bool ItsMe,bool IShouldFillInID);
2018-10-15 14:07:12 +02:00
2014-12-01 23:55:08 +01:00
static void ID_RemoveUsrID (const struct UsrData *UsrDat,bool ItsMe);
static bool ID_CheckIfConfirmed (long UsrCod,const char *UsrID);
static void ID_RemoveUsrIDFromDB (long UsrCod,const char *UsrID);
static void ID_NewUsrID (const struct UsrData *UsrDat,bool ItsMe);
static void ID_InsertANewUsrIDInDB (long UsrCod,const char *NewID,bool Confirmed);
/*****************************************************************************/
/********************** Get list of IDs of a user ****************************/
/*****************************************************************************/
void ID_GetListIDsFromUsrCod (struct UsrData *UsrDat)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumIDs;
unsigned NumID;
/***** Initialize list of IDs to an empty list *****/
ID_FreeListIDs (UsrDat);
if (UsrDat->UsrCod > 0)
{
/***** Get user's IDs from database *****/
2018-10-31 13:00:40 +01:00
// First the confirmed (Confirmed == 'Y')
2014-12-01 23:55:08 +01:00
// Then the unconfirmed (Confirmed == 'N')
2018-10-31 13:00:40 +01:00
NumIDs = (unsigned) DB_QuerySELECT (&mysql_res,"can not get user's IDs",
"SELECT UsrID,Confirmed FROM usr_IDs"
" WHERE UsrCod=%ld"
" ORDER BY Confirmed DESC,UsrID",
UsrDat->UsrCod);
if (NumIDs)
2014-12-01 23:55:08 +01:00
{
/***** Allocate space for the list *****/
ID_ReallocateListIDs (UsrDat,NumIDs);
/***** Get list of IDs *****/
for (NumID = 0;
NumID < NumIDs;
NumID++)
{
row = mysql_fetch_row (mysql_res);
/* Get ID from row[0] */
2017-01-17 03:10:43 +01:00
Str_Copy (UsrDat->IDs.List[NumID].ID,row[0],
2017-03-07 01:56:41 +01:00
ID_MAX_BYTES_USR_ID);
2014-12-01 23:55:08 +01:00
/* Get if ID is confirmed from row[1] */
2016-09-07 18:48:10 +02:00
UsrDat->IDs.List[NumID].Confirmed = (row[1][0] == 'Y');
2014-12-01 23:55:08 +01:00
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
}
/*****************************************************************************/
/***************** Free memory allocated for list of IDs *********************/
/*****************************************************************************/
void ID_ReallocateListIDs (struct UsrData *UsrDat,unsigned NumIDs)
{
/***** Free list of IDs if used *****/
ID_FreeListIDs (UsrDat);
/***** Assign number of IDs in list *****/
UsrDat->IDs.Num = NumIDs;
/***** Allocate space for the list *****/
if ((UsrDat->IDs.List = (struct ListIDs *) malloc (NumIDs * sizeof (struct ListIDs))) == NULL)
2018-10-18 20:06:54 +02:00
Lay_NotEnoughMemoryExit ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************** Free memory allocated for list of IDs *********************/
/*****************************************************************************/
void ID_FreeListIDs (struct UsrData *UsrDat)
{
/***** Free list *****/
if (UsrDat->IDs.Num && UsrDat->IDs.List)
free ((void *) UsrDat->IDs.List);
/***** Reset list *****/
UsrDat->IDs.List = NULL;
UsrDat->IDs.Num = 0;
}
/*****************************************************************************/
/***************** Get list of user codes from user's IDs ********************/
/*****************************************************************************/
// Returns the number of users with any of these IDs
// The list of users' codes is allocated inside this function and should be freed by caller
unsigned ID_GetListUsrCodsFromUsrID (struct UsrData *UsrDat,
const char *EncryptedPassword, // If NULL or empty ==> do not check password
struct ListUsrCods *ListUsrCods,
bool OnlyConfirmedIDs)
{
2018-11-04 21:28:11 +01:00
char *SubQueryAllUsrs = NULL;
char SubQueryOneUsr[1 + ID_MAX_BYTES_USR_ID + 1 + 1];
2014-12-01 23:55:08 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2017-01-16 01:51:01 +01:00
size_t MaxLength;
2014-12-01 23:55:08 +01:00
unsigned NumID;
unsigned NumUsr;
bool CheckPassword = false;
if (UsrDat->IDs.Num)
{
if (EncryptedPassword)
if (EncryptedPassword[0])
CheckPassword = true;
2018-11-04 21:28:11 +01:00
/***** Allocate memory for subquery string *****/
2017-03-07 01:56:41 +01:00
MaxLength = 512 + UsrDat->IDs.Num * (1 + ID_MAX_BYTES_USR_ID + 1) - 1;
2018-11-04 21:28:11 +01:00
if ((SubQueryAllUsrs = (char *) malloc (MaxLength + 1)) == NULL)
2018-10-18 20:06:54 +02:00
Lay_NotEnoughMemoryExit ();
2018-11-04 21:28:11 +01:00
SubQueryAllUsrs[0] = '\0';
2014-12-01 23:55:08 +01:00
/***** Get user's code(s) from database *****/
for (NumID = 0;
NumID < UsrDat->IDs.Num;
NumID++)
{
if (NumID)
2018-11-04 21:28:11 +01:00
Str_Concat (SubQueryAllUsrs,",",
2017-01-17 03:33:05 +01:00
MaxLength);
2018-11-04 21:28:11 +01:00
sprintf (SubQueryOneUsr,"'%s'",UsrDat->IDs.List[NumID].ID);
2017-01-16 01:51:01 +01:00
2018-11-04 21:28:11 +01:00
Str_Concat (SubQueryAllUsrs,SubQueryOneUsr,
2017-01-17 03:33:05 +01:00
MaxLength);
2014-12-01 23:55:08 +01:00
}
if (CheckPassword)
2018-11-04 21:28:11 +01:00
{
2014-12-01 23:55:08 +01:00
// Get user's code if I have written the correct password
// or if password in database is empty (new user)
2018-11-04 21:28:11 +01:00
ListUsrCods->NumUsrs =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's codes",
"SELECT DISTINCT(usr_IDs.UsrCod) FROM usr_IDs,usr_data"
" WHERE usr_IDs.UsrID IN (%s)"
"%s"
" AND usr_IDs.UsrCod=usr_data.UsrCod"
" AND (usr_data.Password='%s' OR usr_data.Password='')",
SubQueryAllUsrs,
OnlyConfirmedIDs ? " AND usr_IDs.Confirmed='Y'" :
"",
EncryptedPassword);
}
else
ListUsrCods->NumUsrs =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get user's codes",
"SELECT DISTINCT(UsrCod) FROM usr_IDs"
" WHERE UsrID IN (%s)"
"%s",
SubQueryAllUsrs,
OnlyConfirmedIDs ? " AND Confirmed='Y'" :
"");
/***** Free memory for subquery string *****/
free ((void *) SubQueryAllUsrs);
2018-11-04 20:51:38 +01:00
2014-12-01 23:55:08 +01:00
if (ListUsrCods->NumUsrs)
{
/***** Allocate space for the list of users' codes *****/
Usr_AllocateListUsrCods (ListUsrCods);
// The list should be freed by caller
/***** Fill the list *****/
for (NumUsr = 0;
NumUsr < ListUsrCods->NumUsrs;
NumUsr++)
{
/***** Get user's code *****/
row = mysql_fetch_row (mysql_res);
ListUsrCods->Lst[NumUsr] = Str_ConvertStrCodToLongCod (row[0]);
}
UsrDat->UsrCod = ListUsrCods->Lst[0]; // The first user found
}
else // ListUsrCods->NumUsrs == 0
{
ListUsrCods->Lst = NULL;
UsrDat->UsrCod = -1L;
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
else // List of user's IDs is empty
{
ListUsrCods->NumUsrs = 0;
ListUsrCods->Lst = NULL;
UsrDat->UsrCod = -1L;
}
return ListUsrCods->NumUsrs;
}
/*****************************************************************************/
/******* Put hidden parameter with the plain user's ID of other user *********/
/*****************************************************************************/
void ID_PutParamOtherUsrIDPlain (void)
{
Par_PutHiddenParamString ("OtherUsrID",
(Gbl.Usrs.Other.UsrDat.IDs.Num &&
Gbl.Usrs.Other.UsrDat.IDs.List) ? Gbl.Usrs.Other.UsrDat.IDs.List[0].ID :
"");
}
/*****************************************************************************/
/********* Get parameter plain user's ID of other user from a form ***********/
/*****************************************************************************/
void ID_GetParamOtherUsrIDPlain (void)
{
/***** Allocate space for the list *****/
ID_ReallocateListIDs (&Gbl.Usrs.Other.UsrDat,1);
/***** Get parameter *****/
2017-01-29 12:42:19 +01:00
Par_GetParToText ("OtherUsrID",Gbl.Usrs.Other.UsrDat.IDs.List[0].ID,
2017-03-07 01:56:41 +01:00
ID_MAX_BYTES_USR_ID);
2014-12-01 23:55:08 +01:00
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID);
Str_ConvertToUpperText (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID);
Gbl.Usrs.Other.UsrDat.IDs.List[0].Confirmed = true;
}
/*****************************************************************************/
/****** Check whether a user's ID without the ending letter is valid *********/
/*****************************************************************************/
// Returns true if the user's ID string is valid, or false if not
// A valid user's ID must...:
2017-03-07 01:56:41 +01:00
// 1. Must be ID_MIN_BYTES_USR_ID <= characters <= ID_MAX_BYTES_USR_ID.
2014-12-01 23:55:08 +01:00
// 2. All characters must be digits or letters
// 3. Must have a minimum number of digits
// Wrapper function to avoid passing extra parameters
bool ID_CheckIfUsrIDIsValid (const char *UsrID)
{
2015-10-07 19:55:13 +02:00
if (UsrID)
if (UsrID[0])
return ID_CheckIfUsrIDIsValidUsingMinDigits (UsrID,ID_MIN_DIGITS_USR_ID);
return false;
2014-12-01 23:55:08 +01:00
}
// Wrapper function to avoid passing extra parameters
bool ID_CheckIfUsrIDSeemsAValidID (const char *UsrID)
{
2015-10-07 19:55:13 +02:00
if (UsrID)
if (UsrID[0])
return ID_CheckIfUsrIDIsValidUsingMinDigits (UsrID,ID_MIN_DIGITS_AUTOMATIC_DETECT_USR_ID);
return false;
2014-12-01 23:55:08 +01:00
}
static bool ID_CheckIfUsrIDIsValidUsingMinDigits (const char *UsrID,unsigned MinDigits)
{
const char *Ptr;
unsigned NumDigits = 0;
2015-10-07 19:55:13 +02:00
unsigned Length;
2014-12-01 23:55:08 +01:00
/***** Check length *****/
2015-10-07 19:55:13 +02:00
if (!UsrID)
return false;
if (!UsrID[0])
return false;
Length = strlen (UsrID);
2017-03-07 01:56:41 +01:00
if (Length < ID_MIN_BYTES_USR_ID ||
Length > ID_MAX_BYTES_USR_ID)
return false; // 1. Must be ID_MIN_BYTES_USR_ID <= characters <= ID_MAX_BYTES_USR_ID
2014-12-01 23:55:08 +01:00
/**** Loop through user's ID *****/
for (Ptr = UsrID;
*Ptr;
Ptr++)
if (isdigit ((int) *Ptr)) // If character is digit
NumDigits++;
else if (!((*Ptr >= 'A' && *Ptr <= 'Z') ||
(*Ptr >= 'a' && *Ptr <= 'z'))) // If character is not alpha
return false; // 2. All characters must be digits or letters
return (NumDigits >= MinDigits); // 3. Must have MinDigits digits at least
}
/*****************************************************************************/
/*************************** Write list of user's ID *************************/
/*****************************************************************************/
2017-05-09 20:56:02 +02:00
void ID_WriteUsrIDs (struct UsrData *UsrDat,const char *Anchor)
2014-12-01 23:55:08 +01:00
{
unsigned NumID;
2016-04-23 19:59:45 +02:00
bool ICanSeeUsrID;
bool ICanConfirmUsrID;
2017-01-27 01:02:52 +01:00
ICanSeeUsrID = ID_ICanSeeOtherUsrIDs (UsrDat);
ICanConfirmUsrID = ICanSeeUsrID &&
2019-04-19 13:11:54 +02:00
(UsrDat->UsrCod != Gbl.Usrs.Me.UsrDat.UsrCod) && // Not me
!Gbl.Form.Inside && // Not inside another form
2018-04-24 13:21:53 +02:00
Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB; // Only in main browser tab
2014-12-01 23:55:08 +01:00
2016-04-23 13:23:09 +02:00
for (NumID = 0;
NumID < UsrDat->IDs.Num;
NumID++)
{
if (NumID)
fprintf (Gbl.F.Out,"<br />");
2015-03-05 21:42:02 +01:00
2016-04-23 13:23:09 +02:00
fprintf (Gbl.F.Out,"<span class=\"%s\">",
UsrDat->IDs.List[NumID].Confirmed ? "USR_ID_C" :
"USR_ID_NC");
if (ICanSeeUsrID)
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"%s",UsrDat->IDs.List[NumID].ID);
2016-04-23 13:23:09 +02:00
else
fprintf (Gbl.F.Out,"********");
fprintf (Gbl.F.Out,"</span>");
2016-04-23 19:59:45 +02:00
if (ICanConfirmUsrID &&
!UsrDat->IDs.List[NumID].Confirmed)
2017-05-09 20:56:02 +02:00
ID_PutLinkToConfirmID (UsrDat,NumID,Anchor);
2016-04-23 19:59:45 +02:00
}
}
/*****************************************************************************/
/***************** Check if I can see another user's IDs *********************/
/*****************************************************************************/
2017-01-27 01:02:52 +01:00
bool ID_ICanSeeOtherUsrIDs (const struct UsrData *UsrDat)
2016-04-23 19:59:45 +02:00
{
2018-10-10 23:56:42 +02:00
bool ItsMe = Usr_ItsMe (UsrDat->UsrCod);
2018-10-10 14:03:06 +02:00
if (ItsMe)
2017-01-27 01:02:52 +01:00
return true;
2016-04-23 19:59:45 +02:00
/***** Check if I have permission to see another user's IDs *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2016-04-23 19:59:45 +02:00
{
2017-05-22 12:23:08 +02:00
case Rol_NET:
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2017-01-27 15:21:01 +01:00
/* Check 1: I can see the IDs of users who do not exist in database */
if (UsrDat->UsrCod <= 0) // User does not exist (when creating a new user)
return true;
/* Check 2: I can see the IDs of confirmed students */
2017-06-08 15:32:33 +02:00
if (UsrDat->Roles.InCurrentCrs.Role == Rol_STD && // A student
2017-06-11 20:09:59 +02:00
UsrDat->Accepted) // who accepted registration
2017-01-27 15:21:01 +01:00
return true;
/* Check 3: I can see the IDs of users with user's data empty */
2017-01-27 18:45:38 +01:00
// This check is made to not view simultaneously:
// - an ID
// - a name or an email
2017-01-27 15:21:01 +01:00
if (!UsrDat->Password[0] && // User has no password (never logged)
!UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1)
!UsrDat->Surname2[0] && // and who has no surname 2 (nobody filled user's surname 2)
2017-01-27 18:45:38 +01:00
!UsrDat->FirstName[0] && // and who has no first name (nobody filled user's first name)
!UsrDat->Email[0]) // and who has no email (nobody filled user's email)
2017-01-27 15:21:01 +01:00
return true;
return false;
2016-04-23 19:59:45 +02:00
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
2017-01-28 18:08:06 +01:00
return Usr_ICanEditOtherUsr (UsrDat);
2016-04-23 19:59:45 +02:00
default:
return false;
2016-04-23 13:23:09 +02:00
}
2014-12-01 23:55:08 +01:00
}
2016-04-23 23:47:22 +02:00
/*****************************************************************************/
2017-06-11 20:09:59 +02:00
/****************** Put a link to confirm another user's ID ******************/
2016-04-23 23:47:22 +02:00
/*****************************************************************************/
2017-05-09 20:56:02 +02:00
static void ID_PutLinkToConfirmID (struct UsrData *UsrDat,unsigned NumID,
const char *Anchor)
2016-04-23 23:47:22 +02:00
{
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES];
2016-04-24 22:01:22 +02:00
extern const char *Txt_Confirm_ID;
2017-05-22 12:23:08 +02:00
Act_Action_t NextAction;
2016-04-24 02:42:23 +02:00
2017-05-09 20:56:02 +02:00
/***** Start form *****/
2017-06-08 15:32:33 +02:00
switch (UsrDat->Roles.InCurrentCrs.Role)
2017-05-22 12:23:08 +02:00
{
case Rol_STD:
NextAction = ActCnfID_Std;
break;
case Rol_NET:
case Rol_TCH:
NextAction = ActCnfID_Tch;
break;
2017-05-22 14:52:11 +02:00
default: // Guest, user or admin
2017-05-22 12:23:08 +02:00
NextAction = ActCnfID_Oth;
break;
}
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (NextAction,Anchor);
2017-05-09 20:56:02 +02:00
if (Gbl.Action.Original != ActUnk)
{
2017-05-10 10:09:19 +02:00
Par_PutHiddenParamLong ("OriginalActCod",
2018-04-24 13:21:53 +02:00
Act_GetActCod (Gbl.Action.Original)); // Original action, used to know where we came from
2017-05-09 20:56:02 +02:00
switch (Gbl.Action.Original)
{
2019-03-11 13:33:34 +01:00
case ActSeeRecSevGst:
case ActSeeRecSevStd:
case ActSeeRecSevTch:
2019-04-25 02:58:42 +02:00
Usr_PutHiddenParSelectedUsrsCods ();
2017-05-09 20:56:02 +02:00
break;
2019-04-22 10:10:21 +02:00
default:
break;
2017-05-09 20:56:02 +02:00
}
}
2016-04-24 02:42:23 +02:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
fprintf (Gbl.F.Out,"<input type=\"hidden\" name=\"UsrID\" value=\"%s\" />",
UsrDat->IDs.List[NumID].ID);
2017-05-09 20:56:02 +02:00
/***** Put link *****/
2019-02-22 21:47:50 +01:00
Frm_LinkFormSubmit (Txt_Confirm_ID,The_ClassFormOutBoxBold[Gbl.Prefs.Theme],NULL);
2019-01-12 19:46:33 +01:00
Ico_PutIconTextLink ("check.svg",
Txt_Confirm_ID);
2019-01-12 03:00:59 +01:00
fprintf (Gbl.F.Out,"</a>");
2016-04-24 02:42:23 +02:00
2017-05-09 20:56:02 +02:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2016-04-23 23:47:22 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*********************** Show form to change my user's ID ********************/
/*****************************************************************************/
2019-02-15 21:09:18 +01:00
void ID_ShowFormChangeMyID (bool IShouldFillInID)
2014-12-01 23:55:08 +01:00
{
2018-10-15 14:07:12 +02:00
extern const char *Hlp_PROFILE_Account;
2014-12-01 23:55:08 +01:00
extern const char *Txt_ID;
2018-10-15 14:07:12 +02:00
char StrRecordWidth[10 + 1];
/***** Start section *****/
Lay_StartSection (ID_ID_SECTION_ID);
/***** Start box *****/
2018-10-18 02:02:32 +02:00
snprintf (StrRecordWidth,sizeof (StrRecordWidth),
"%upx",
Rec_RECORD_WIDTH);
2018-10-15 14:07:12 +02:00
Box_StartBox (StrRecordWidth,Txt_ID,Acc_PutLinkToRemoveMyAccount,
Hlp_PROFILE_Account,Box_NOT_CLOSABLE);
/***** Show form to change ID *****/
ID_ShowFormChangeUsrID (&Gbl.Usrs.Me.UsrDat,
true, // ItsMe
2019-02-15 21:09:18 +01:00
IShouldFillInID);
2018-10-15 14:07:12 +02:00
/***** End box *****/
Box_EndBox ();
/***** End section *****/
Lay_EndSection ();
}
/*****************************************************************************/
/*********************** Show form to change my user's ID ********************/
/*****************************************************************************/
void ID_ShowFormChangeOtherUsrID (void)
{
2018-10-16 01:36:13 +02:00
extern const char *Hlp_PROFILE_Account;
extern const char *Txt_ID;
char StrRecordWidth[10 + 1];
2018-10-15 14:07:12 +02:00
/***** Start section *****/
Lay_StartSection (ID_ID_SECTION_ID);
2018-10-16 01:36:13 +02:00
/***** Start box *****/
2018-10-18 02:02:32 +02:00
snprintf (StrRecordWidth,sizeof (StrRecordWidth),
"%upx",
Rec_RECORD_WIDTH);
2018-10-16 01:36:13 +02:00
Box_StartBox (StrRecordWidth,Txt_ID,NULL,
Hlp_PROFILE_Account,Box_NOT_CLOSABLE);
2018-10-15 14:07:12 +02:00
/***** Show form to change ID *****/
ID_ShowFormChangeUsrID (&Gbl.Usrs.Other.UsrDat,
false, // ItsMe
2019-02-15 21:09:18 +01:00
false); // IShouldFillInID
2018-10-15 14:07:12 +02:00
2018-10-16 01:36:13 +02:00
/***** End box *****/
Box_EndBox ();
2018-10-15 14:07:12 +02:00
/***** End section *****/
Lay_EndSection ();
}
/*****************************************************************************/
/*********************** Show form to change my user's ID ********************/
/*****************************************************************************/
static void ID_ShowFormChangeUsrID (const struct UsrData *UsrDat,
2019-02-15 21:09:18 +01:00
bool ItsMe,bool IShouldFillInID)
2018-10-15 14:07:12 +02:00
{
extern const char *Hlp_PROFILE_Account;
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormInBox[The_NUM_THEMES];
2018-10-15 14:07:12 +02:00
extern const char *Txt_Please_fill_in_your_ID;
2014-12-01 23:55:08 +01:00
extern const char *Txt_ID_X_confirmed;
2016-04-23 17:12:01 +02:00
extern const char *Txt_ID_X_not_confirmed;
2018-10-15 14:07:12 +02:00
extern const char *Txt_ID;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Another_ID;
extern const char *Txt_Add_this_ID;
2014-12-13 21:38:31 +01:00
extern const char *Txt_The_ID_is_used_in_order_to_facilitate_;
2014-12-01 23:55:08 +01:00
unsigned NumID;
2017-05-22 12:23:08 +02:00
Act_Action_t NextAction;
2014-12-01 23:55:08 +01:00
2019-03-09 20:12:44 +01:00
/***** Show possible alerts *****/
Ale_ShowAlerts (ID_ID_SECTION_ID);
2018-10-15 14:07:12 +02:00
/***** Help message *****/
2019-02-15 21:09:18 +01:00
if (IShouldFillInID)
2019-02-16 16:18:54 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_Please_fill_in_your_ID);
2018-10-15 14:07:12 +02:00
/***** Start table *****/
2019-10-03 22:43:36 +02:00
Tbl_StartTableWidePadding (2);
2018-10-15 14:07:12 +02:00
2014-12-01 23:55:08 +01:00
/***** List existing user's IDs *****/
for (NumID = 0;
NumID < UsrDat->IDs.Num;
NumID++)
{
if (NumID == 0)
2019-10-04 14:42:59 +02:00
{
Tbl_StartRow ();
fprintf (Gbl.F.Out,"<td class=\"REC_C1_BOT RIGHT_TOP\">"
2018-10-15 14:07:12 +02:00
"<label for=\"UsrID\" class=\"%s\">"
2014-12-23 01:36:58 +01:00
"%s:"
2018-10-15 14:07:12 +02:00
"</label>"
2014-12-23 01:36:58 +01:00
"</td>"
2018-10-15 14:07:12 +02:00
"<td class=\"REC_C2_BOT LEFT_TOP USR_ID\">",
2019-02-22 21:47:50 +01:00
The_ClassFormInBox[Gbl.Prefs.Theme],Txt_ID);
2019-10-04 14:42:59 +02:00
}
2014-12-01 23:55:08 +01:00
else // NumID >= 1
fprintf (Gbl.F.Out,"<br />");
if (UsrDat->IDs.Num > 1) // I have two or more IDs
{
if (ItsMe && UsrDat->IDs.List[NumID].Confirmed) // I can not remove my confirmed IDs
/* Put disabled icon to remove user's ID */
2017-06-11 19:13:28 +02:00
Ico_PutIconRemovalNotAllowed ();
2014-12-01 23:55:08 +01:00
else // I can remove
{
/* Form to remove user's ID */
if (ItsMe)
2019-02-15 21:09:18 +01:00
Frm_StartFormAnchor (ActRemMyID,ID_ID_SECTION_ID);
2014-12-01 23:55:08 +01:00
else
{
2017-06-08 15:32:33 +02:00
switch (UsrDat->Roles.InCurrentCrs.Role)
2017-05-22 12:23:08 +02:00
{
case Rol_STD:
NextAction = ActRemID_Std;
break;
case Rol_NET:
case Rol_TCH:
NextAction = ActRemID_Tch;
break;
2017-05-22 14:52:11 +02:00
default: // Guest, user or admin
2017-05-22 12:23:08 +02:00
NextAction = ActRemID_Oth;
break;
}
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (NextAction,ID_ID_SECTION_ID);
2015-04-02 18:39:49 +02:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2014-12-01 23:55:08 +01:00
}
2018-10-15 14:07:12 +02:00
fprintf (Gbl.F.Out,"<input type=\"hidden\" name=\"UsrID\""
" value=\"%s\" />",
2014-12-01 23:55:08 +01:00
UsrDat->IDs.List[NumID].ID);
2017-06-11 19:13:28 +02:00
Ico_PutIconRemove ();
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
}
}
/* User's ID */
2018-10-18 02:02:32 +02:00
snprintf (Gbl.Title,sizeof (Gbl.Title),
UsrDat->IDs.List[NumID].Confirmed ? Txt_ID_X_confirmed :
Txt_ID_X_not_confirmed,
UsrDat->IDs.List[NumID].ID);
2019-01-11 03:45:13 +01:00
fprintf (Gbl.F.Out,"<span class=\"%s\" title=\"%s\">%s%s</span>",
2016-04-23 17:12:01 +02:00
UsrDat->IDs.List[NumID].Confirmed ? "USR_ID_C" :
"USR_ID_NC",
Gbl.Title,
2019-01-11 03:45:13 +01:00
UsrDat->IDs.List[NumID].ID,
UsrDat->IDs.List[NumID].Confirmed ? "&check;" :
"");
2014-12-01 23:55:08 +01:00
if (NumID == UsrDat->IDs.Num - 1)
2019-10-04 20:43:43 +02:00
{
2019-10-06 12:00:55 +02:00
Tbl_EndCell ();
2019-10-04 20:43:43 +02:00
Tbl_EndRow ();
}
2014-12-01 23:55:08 +01:00
}
if (UsrDat->IDs.Num < ID_MAX_IDS_PER_USER)
{
2018-10-10 14:03:06 +02:00
/***** Write help text *****/
2019-10-04 14:42:59 +02:00
Tbl_StartRow ();
fprintf (Gbl.F.Out,"<td colspan=\"2\" class=\"DAT CENTER_MIDDLE\">");
2019-02-16 16:18:54 +01:00
Ale_ShowAlert (Ale_INFO,Txt_The_ID_is_used_in_order_to_facilitate_);
2019-10-06 12:00:55 +02:00
Tbl_EndCell ();
2019-10-04 20:43:43 +02:00
Tbl_EndRow ();
2018-10-10 14:03:06 +02:00
/***** Form to enter new user's ID *****/
2019-10-04 14:42:59 +02:00
Tbl_StartRow ();
fprintf (Gbl.F.Out,"<td class=\"REC_C1_BOT RIGHT_TOP\">"
2016-12-24 01:07:48 +01:00
"<label for=\"NewID\" class=\"%s\">%s:</label>"
2014-12-23 01:36:58 +01:00
"</td>"
2018-10-15 14:07:12 +02:00
"<td class=\"REC_C2_BOT LEFT_TOP DAT\">",
2019-02-22 21:47:50 +01:00
The_ClassFormInBox[Gbl.Prefs.Theme],
2014-12-01 23:55:08 +01:00
UsrDat->IDs.Num ? Txt_Another_ID : // A new user's ID
Txt_ID); // The first user's ID
if (ItsMe)
2019-02-15 21:09:18 +01:00
Frm_StartFormAnchor (ActChgMyID,ID_ID_SECTION_ID);
2014-12-01 23:55:08 +01:00
else
{
2017-06-08 15:32:33 +02:00
switch (UsrDat->Roles.InCurrentCrs.Role)
2017-05-22 12:23:08 +02:00
{
case Rol_STD:
NextAction = ActNewID_Std;
break;
case Rol_NET:
case Rol_TCH:
NextAction = ActNewID_Tch;
break;
2017-05-22 14:52:11 +02:00
default: // Guest, user or admin
2017-05-22 12:23:08 +02:00
NextAction = ActNewID_Oth;
break;
}
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (NextAction,ID_ID_SECTION_ID);
2015-04-02 18:39:49 +02:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2014-12-01 23:55:08 +01:00
}
2018-10-15 14:07:12 +02:00
fprintf (Gbl.F.Out,"<input type=\"text\" id=\"NewID\" name=\"NewID\""
2016-12-10 18:32:35 +01:00
" size=\"18\" maxlength=\"%u\" value=\"%s\" />"
2018-10-15 14:07:12 +02:00
"<br />",
2017-03-07 01:56:41 +01:00
ID_MAX_BYTES_USR_ID,
2014-12-01 23:55:08 +01:00
UsrDat->IDs.Num ? UsrDat->IDs.List[UsrDat->IDs.Num - 1].ID :
2015-03-24 17:47:26 +01:00
""); // Show the most recent ID
2017-06-11 19:02:40 +02:00
Btn_PutCreateButtonInline (Txt_Add_this_ID);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2019-10-06 12:00:55 +02:00
Tbl_EndCell ();
2019-10-04 20:43:43 +02:00
Tbl_EndRow ();
2014-12-01 23:55:08 +01:00
}
2018-10-15 14:07:12 +02:00
/***** End table *****/
Tbl_EndTable ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************** Remove one of my user's IDs **************************/
/*****************************************************************************/
void ID_RemoveMyUsrID (void)
{
/***** Remove user's ID *****/
2018-10-10 14:03:06 +02:00
ID_RemoveUsrID (&Gbl.Usrs.Me.UsrDat,
true); // It's me
2014-12-01 23:55:08 +01:00
/***** Update list of IDs *****/
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Me.UsrDat);
/***** Show my account again *****/
2018-10-15 14:07:12 +02:00
Acc_ShowFormChgMyAccount ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Remove one of the user's IDs of another user ***************/
/*****************************************************************************/
void ID_RemoveOtherUsrID (void)
{
2018-10-10 14:03:06 +02:00
bool ItsMe;
2014-12-01 23:55:08 +01:00
/***** Get other user's code from form and get user's data *****/
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
{
2018-10-16 08:48:51 +02:00
if (Usr_ICanEditOtherUsr (&Gbl.Usrs.Other.UsrDat))
{
/***** Remove user's ID *****/
ItsMe = Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod);
ID_RemoveUsrID (&Gbl.Usrs.Other.UsrDat,ItsMe);
2014-12-01 23:55:08 +01:00
2018-10-16 08:48:51 +02:00
/***** Update list of IDs *****/
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Other.UsrDat);
2014-12-01 23:55:08 +01:00
2018-10-16 08:48:51 +02:00
/***** Show form again *****/
Acc_ShowFormChgOtherUsrAccount ();
}
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-01 23:55:08 +01:00
}
else // User not found
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************************** Remove user's ID ******************************/
/*****************************************************************************/
static void ID_RemoveUsrID (const struct UsrData *UsrDat,bool ItsMe)
{
extern const char *Txt_ID_X_removed;
extern const char *Txt_You_can_not_delete_this_ID;
2017-03-07 01:56:41 +01:00
char UsrID[ID_MAX_BYTES_USR_ID + 1];
2014-12-01 23:55:08 +01:00
bool ICanRemove;
2017-01-28 18:08:06 +01:00
if (Usr_ICanEditOtherUsr (UsrDat))
2014-12-01 23:55:08 +01:00
{
2016-04-24 02:42:23 +02:00
/***** Get user's ID from form *****/
2017-03-07 01:56:41 +01:00
Par_GetParToText ("UsrID",UsrID,ID_MAX_BYTES_USR_ID);
2014-12-01 23:55:08 +01:00
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (UsrID);
Str_ConvertToUpperText (UsrID);
if (UsrDat->IDs.Num < 2) // One unique ID
ICanRemove = false;
else if (ItsMe)
2014-12-03 20:06:16 +01:00
// I can remove my ID only if it is not confirmed
ICanRemove = !ID_CheckIfConfirmed (UsrDat->UsrCod,UsrID);
2014-12-01 23:55:08 +01:00
else
ICanRemove = true;
if (ICanRemove)
{
/***** Remove one of the user's IDs *****/
ID_RemoveUsrIDFromDB (UsrDat->UsrCod,UsrID);
/***** Show message *****/
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_SUCCESS,ID_ID_SECTION_ID,
Txt_ID_X_removed,
UsrID);
2014-12-01 23:55:08 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,ID_ID_SECTION_ID,
Txt_You_can_not_delete_this_ID);
2014-12-01 23:55:08 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************ Check if an ID is confirmed ************************/
/*****************************************************************************/
static bool ID_CheckIfConfirmed (long UsrCod,const char *UsrID)
{
/***** Get if ID is confirmed from database *****/
2018-11-03 20:52:00 +01:00
return (DB_QueryCOUNT ("can not check if ID is confirmed",
"SELECT COUNT(*) FROM usr_IDs"
" WHERE UsrCod=%ld AND UsrID='%s' AND Confirmed='Y'",
UsrCod,UsrID) != 0);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Remove one of my user's IDs from database ******************/
/*****************************************************************************/
static void ID_RemoveUsrIDFromDB (long UsrCod,const char *UsrID)
{
/***** Remove one of my user's IDs *****/
2018-11-02 16:39:35 +01:00
DB_QueryREPLACE ("can not remove a user's ID",
"DELETE FROM usr_IDs"
" WHERE UsrCod=%ld AND UsrID='%s'",
UsrCod,UsrID);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************* New user's ID for me ******************************/
/*****************************************************************************/
void ID_NewMyUsrID (void)
{
2018-10-16 01:36:13 +02:00
/***** New user's ID *****/
2018-10-10 14:03:06 +02:00
ID_NewUsrID (&Gbl.Usrs.Me.UsrDat,
true); // It's me
2014-12-01 23:55:08 +01:00
/***** Update list of IDs *****/
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Me.UsrDat);
/***** Show my account again *****/
2018-10-15 14:07:12 +02:00
Acc_ShowFormChgMyAccount ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************* New user's ID for another user ************************/
/*****************************************************************************/
void ID_NewOtherUsrID (void)
{
2018-10-10 14:03:06 +02:00
bool ItsMe;
2014-12-01 23:55:08 +01:00
/***** Get other user's code from form and get user's data *****/
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
{
2018-10-16 08:48:51 +02:00
if (Usr_ICanEditOtherUsr (&Gbl.Usrs.Other.UsrDat))
{
/***** New user's ID *****/
ItsMe = Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod);
ID_NewUsrID (&Gbl.Usrs.Other.UsrDat,ItsMe);
2014-12-01 23:55:08 +01:00
2018-10-16 08:48:51 +02:00
/***** Update list of IDs *****/
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Other.UsrDat);
2014-12-01 23:55:08 +01:00
2018-10-16 08:48:51 +02:00
/***** Show form again *****/
Acc_ShowFormChgOtherUsrAccount ();
}
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-01 23:55:08 +01:00
}
else // User not found
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************************** New user's ID *********************************/
/*****************************************************************************/
static void ID_NewUsrID (const struct UsrData *UsrDat,bool ItsMe)
{
extern const char *Txt_The_ID_X_matches_one_of_the_existing;
extern const char *Txt_The_ID_X_has_been_confirmed;
extern const char *Txt_A_user_can_not_have_more_than_X_IDs;
extern const char *Txt_The_ID_X_has_been_registered_successfully;
extern const char *Txt_The_ID_X_is_not_valid;
2017-03-07 01:56:41 +01:00
char NewID[ID_MAX_BYTES_USR_ID + 1];
2014-12-01 23:55:08 +01:00
unsigned NumID;
bool AlreadyExists;
2016-04-25 01:54:25 +02:00
unsigned NumIDFound = 0; // Initialized to avoid warning
2014-12-01 23:55:08 +01:00
2017-01-28 18:08:06 +01:00
if (Usr_ICanEditOtherUsr (UsrDat))
2014-12-01 23:55:08 +01:00
{
/***** Get new user's ID from form *****/
2017-03-07 01:56:41 +01:00
Par_GetParToText ("NewID",NewID,ID_MAX_BYTES_USR_ID);
2014-12-01 23:55:08 +01:00
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (NewID);
Str_ConvertToUpperText (NewID);
if (ID_CheckIfUsrIDIsValid (NewID)) // If new ID is valid
{
/***** Check if the new ID matches any of the old IDs *****/
for (NumID = 0, AlreadyExists = false;
NumID < UsrDat->IDs.Num && !AlreadyExists;
NumID++)
2016-04-25 00:06:44 +02:00
if (!strcasecmp (UsrDat->IDs.List[NumID].ID,NewID))
{
AlreadyExists = true;
NumIDFound = NumID;
}
2014-12-01 23:55:08 +01:00
if (AlreadyExists) // This new ID was already associated to this user
{
2016-04-25 00:06:44 +02:00
if (ItsMe || UsrDat->IDs.List[NumIDFound].Confirmed)
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,ID_ID_SECTION_ID,
Txt_The_ID_X_matches_one_of_the_existing,
NewID);
2014-12-01 23:55:08 +01:00
else // It's not me && !Confirmed
{
/***** Mark this ID as confirmed *****/
2016-04-25 00:06:44 +02:00
ID_ConfirmUsrID (UsrDat,NewID);
2018-10-15 14:07:12 +02:00
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_SUCCESS,ID_ID_SECTION_ID,
Txt_The_ID_X_has_been_confirmed,
NewID);
2014-12-01 23:55:08 +01:00
}
}
else if (UsrDat->IDs.Num >= ID_MAX_IDS_PER_USER)
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,ID_ID_SECTION_ID,
Txt_A_user_can_not_have_more_than_X_IDs,
ID_MAX_IDS_PER_USER);
2014-12-01 23:55:08 +01:00
else // OK ==> add this new ID to my list of IDs
{
/***** Save this new ID *****/
// It's me ==> ID not confirmed
2018-10-10 14:03:06 +02:00
// Not me ==> ID confirmed
2014-12-01 23:55:08 +01:00
ID_InsertANewUsrIDInDB (UsrDat->UsrCod,NewID,!ItsMe);
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_SUCCESS,ID_ID_SECTION_ID,
Txt_The_ID_X_has_been_registered_successfully,
NewID);
2014-12-01 23:55:08 +01:00
}
}
else // New ID is not valid
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_WARNING,ID_ID_SECTION_ID,
Txt_The_ID_X_is_not_valid,
NewID);
2014-12-01 23:55:08 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************* Insert a new ID for me in database **********************/
/*****************************************************************************/
static void ID_InsertANewUsrIDInDB (long UsrCod,const char *NewID,bool Confirmed)
{
/***** Update my nickname in database *****/
2018-11-02 19:37:11 +01:00
DB_QueryINSERT ("can not insert a new ID",
"INSERT INTO usr_IDs"
" (UsrCod,UsrID,CreatTime,Confirmed)"
" VALUES"
" (%ld,'%s',NOW(),'%c')",
UsrCod,NewID,
Confirmed ? 'Y' :
'N');
2014-12-01 23:55:08 +01:00
}
2016-04-25 00:06:44 +02:00
/*****************************************************************************/
/************************ Confirm another user's ID **************************/
/*****************************************************************************/
void ID_ConfirmOtherUsrID (void)
2016-04-24 02:42:23 +02:00
{
2016-04-24 22:01:22 +02:00
extern const char *Txt_ID_X_had_already_been_confirmed;
2016-04-25 00:06:44 +02:00
extern const char *Txt_The_ID_X_has_been_confirmed;
2017-05-09 20:56:02 +02:00
long OriginalActCod;
2017-03-07 01:56:41 +01:00
char UsrID[ID_MAX_BYTES_USR_ID + 1];
2017-01-27 18:45:38 +01:00
bool ICanConfirm;
2018-10-10 23:56:42 +02:00
bool ItsMe;
2016-04-24 02:42:23 +02:00
bool Found;
unsigned NumID;
2016-04-25 01:54:25 +02:00
unsigned NumIDFound = 0; // Initialized to avoid warning
2016-04-24 02:42:23 +02:00
2017-05-09 20:56:02 +02:00
/***** Get where we came from *****/
OriginalActCod = Par_GetParToLong ("OriginalActCod");
Gbl.Action.Original = Act_GetActionFromActCod (OriginalActCod);
2016-04-24 02:42:23 +02:00
/***** Get other user's code from form and get user's data *****/
2017-01-27 18:45:38 +01:00
ICanConfirm = false;
2016-04-24 02:42:23 +02:00
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
2018-10-10 23:56:42 +02:00
{
ItsMe = Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod);
if (!ItsMe) // Not me
2019-03-11 13:33:34 +01:00
{
/* If user is a student in current course,
check if he/she has accepted */
2019-04-03 20:57:04 +02:00
if (Gbl.Hierarchy.Level == Hie_CRS)
2019-03-11 13:33:34 +01:00
if (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role == Rol_STD)
2019-03-12 01:46:40 +01:00
Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat);
2019-03-11 13:33:34 +01:00
2017-01-27 18:45:38 +01:00
if (ID_ICanSeeOtherUsrIDs (&Gbl.Usrs.Other.UsrDat))
2016-04-24 02:42:23 +02:00
ICanConfirm = true;
2019-03-11 13:33:34 +01:00
}
2018-10-10 23:56:42 +02:00
}
2016-04-24 02:42:23 +02:00
if (ICanConfirm)
{
/***** Get user's ID from form *****/
2017-03-07 01:56:41 +01:00
Par_GetParToText ("UsrID",UsrID,ID_MAX_BYTES_USR_ID);
2016-04-24 02:42:23 +02:00
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (UsrID);
Str_ConvertToUpperText (UsrID);
for (NumID = 0, Found = false;
NumID < Gbl.Usrs.Other.UsrDat.IDs.Num && !Found;
NumID++)
2016-04-25 00:06:44 +02:00
if (!strcasecmp (UsrID,Gbl.Usrs.Other.UsrDat.IDs.List[NumID].ID))
2016-04-24 02:42:23 +02:00
{
Found = true;
NumIDFound = NumID;
}
if (Found) // Found
{
if (Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].Confirmed)
/***** ID found and already confirmed *****/
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_INFO,ID_ID_SECTION_ID,
Txt_ID_X_had_already_been_confirmed,
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].ID);
2016-04-24 02:42:23 +02:00
else
{
2017-05-09 20:56:02 +02:00
/***** Mark this ID as confirmed *****/
ID_ConfirmUsrID (&Gbl.Usrs.Other.UsrDat,
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].ID);
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].Confirmed = true;
/***** Write success message *****/
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_SUCCESS,ID_ID_SECTION_ID,
Txt_The_ID_X_has_been_confirmed,
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].ID);
2016-04-24 02:42:23 +02:00
}
}
else // User's ID not found
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-05-09 20:56:02 +02:00
}
else // I can not confirm
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2016-04-24 02:42:23 +02:00
2017-05-09 20:56:02 +02:00
/***** Show one or multiple records *****/
switch (Gbl.Action.Original)
{
2019-03-11 13:33:34 +01:00
case ActSeeRecSevGst:
2017-05-09 20:56:02 +02:00
/* Show multiple records of guests again (including the updated one) */
Rec_ListRecordsGstsShow ();
break;
2019-03-11 13:33:34 +01:00
case ActSeeRecSevStd:
2017-05-09 20:56:02 +02:00
/* Show multiple records of students again (including the updated one) */
Rec_ListRecordsStdsShow ();
break;
2019-03-11 13:33:34 +01:00
case ActSeeRecSevTch:
2017-05-09 20:56:02 +02:00
/* Show multiple records of teachers again (including the updated one) */
Rec_ListRecordsTchsShow ();
break;
default:
/* Show optional alert */
2019-03-09 20:12:44 +01:00
Ale_ShowAlerts (NULL);
2017-05-09 20:56:02 +02:00
/* Show only the updated record of this user */
Rec_ShowSharedUsrRecord (Rec_SHA_RECORD_LIST,
&Gbl.Usrs.Other.UsrDat,NULL);
break;
2016-04-24 02:42:23 +02:00
}
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*********************** Set a user's ID as confirmed ************************/
/*****************************************************************************/
2016-04-25 00:06:44 +02:00
void ID_ConfirmUsrID (const struct UsrData *UsrDat,const char *UsrID)
2014-12-01 23:55:08 +01:00
{
2016-04-25 00:06:44 +02:00
/***** Update database *****/
2018-11-02 19:37:11 +01:00
DB_QueryINSERT ("can not confirm a user's ID",
"UPDATE usr_IDs SET Confirmed='Y'"
" WHERE UsrCod=%ld AND UsrID='%s' AND Confirmed<>'Y'",
UsrDat->UsrCod,UsrID);
2014-12-01 23:55:08 +01:00
}