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.
|
2016-01-01 20:19:43 +01:00
|
|
|
|
Copyright (C) 1999-2016 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"
|
2014-12-01 23:55:08 +01:00
|
|
|
|
#include "swad_database.h"
|
|
|
|
|
#include "swad_global.h"
|
|
|
|
|
#include "swad_ID.h"
|
|
|
|
|
#include "swad_parameter.h"
|
|
|
|
|
#include "swad_QR.h"
|
|
|
|
|
#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 *******************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-04-25 00:06:44 +02:00
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
ID_REQUEST_CONFIRM_ID,
|
|
|
|
|
ID_CONFIRM_ID,
|
|
|
|
|
} ID_ReqConfOrConfID_t;
|
|
|
|
|
|
2014-12-01 23:55:08 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private variables *****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private prototypes ****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static bool ID_CheckIfUsrIDIsValidUsingMinDigits (const char *UsrID,unsigned MinDigits);
|
|
|
|
|
|
2016-04-23 19:59:45 +02:00
|
|
|
|
static bool ID_ICanSeeAnotherUsrID (struct UsrData *UsrDat);
|
2016-04-24 02:42:23 +02:00
|
|
|
|
static void ID_PutButtonToReqConfirmID (struct UsrData *UsrDat,unsigned NumID);
|
|
|
|
|
static void ID_PutButtonToConfirmID (struct UsrData *UsrDat,unsigned NumID);
|
2016-04-23 19:59:45 +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);
|
|
|
|
|
|
2016-04-25 00:06:44 +02:00
|
|
|
|
static void ID_ReqConfOrConfOtherUsrID (ID_ReqConfOrConfID_t ReqConfOrConfID);
|
|
|
|
|
|
2014-12-01 23:55:08 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********************** Get list of IDs of a user ****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_GetListIDsFromUsrCod (struct UsrData *UsrDat)
|
|
|
|
|
{
|
|
|
|
|
char Query[256];
|
|
|
|
|
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 *****/
|
|
|
|
|
// First the confirmed (Confirmed == 'Y')
|
|
|
|
|
// Then the unconfirmed (Confirmed == 'N')
|
|
|
|
|
sprintf (Query,"SELECT UsrID,Confirmed FROM usr_IDs"
|
|
|
|
|
" WHERE UsrCod='%ld'" \
|
|
|
|
|
" ORDER BY Confirmed DESC,UsrID",
|
|
|
|
|
UsrDat->UsrCod);
|
|
|
|
|
if ((NumIDs = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get user's IDs")))
|
|
|
|
|
{
|
|
|
|
|
/***** 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] */
|
|
|
|
|
strncpy (UsrDat->IDs.List[NumID].ID,row[0],ID_MAX_LENGTH_USR_ID);
|
|
|
|
|
UsrDat->IDs.List[NumID].ID[ID_MAX_LENGTH_USR_ID] = '\0';
|
|
|
|
|
|
|
|
|
|
/* Get if ID is confirmed from row[1] */
|
|
|
|
|
UsrDat->IDs.List[NumID].Confirmed = (Str_ConvertToUpperLetter (row[1][0]) == 'Y');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** 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)
|
|
|
|
|
Lay_ShowErrorAndExit ("Not enough memory to store list of user's IDs.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************** 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)
|
|
|
|
|
{
|
|
|
|
|
char SubQuery[256];
|
|
|
|
|
char *Query;
|
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
unsigned NumID;
|
|
|
|
|
unsigned NumUsr;
|
|
|
|
|
bool CheckPassword = false;
|
|
|
|
|
|
|
|
|
|
if (UsrDat->IDs.Num)
|
|
|
|
|
{
|
|
|
|
|
if (EncryptedPassword)
|
|
|
|
|
if (EncryptedPassword[0])
|
|
|
|
|
CheckPassword = true;
|
|
|
|
|
|
|
|
|
|
/***** Allocate memory for query string *****/
|
|
|
|
|
if ((Query = (char *) malloc (512 + UsrDat->IDs.Num * (1 + ID_MAX_LENGTH_USR_ID + 1))) == NULL)
|
|
|
|
|
Lay_ShowErrorAndExit ("Not enough memory to store list of user's IDs.");
|
|
|
|
|
|
|
|
|
|
/***** Get user's code(s) from database *****/
|
|
|
|
|
strcpy (Query,CheckPassword ? "SELECT DISTINCT(usr_IDs.UsrCod) FROM usr_IDs,usr_data"
|
|
|
|
|
" WHERE usr_IDs.UsrID IN (" :
|
|
|
|
|
"SELECT DISTINCT(UsrCod) FROM usr_IDs"
|
|
|
|
|
" WHERE UsrID IN (");
|
|
|
|
|
for (NumID = 0;
|
|
|
|
|
NumID < UsrDat->IDs.Num;
|
|
|
|
|
NumID++)
|
|
|
|
|
{
|
|
|
|
|
if (NumID)
|
|
|
|
|
strcat (Query,",");
|
|
|
|
|
sprintf (SubQuery,"'%s'",UsrDat->IDs.List[NumID].ID);
|
|
|
|
|
strcat (Query,SubQuery);
|
|
|
|
|
}
|
|
|
|
|
strcat (Query,")");
|
|
|
|
|
|
|
|
|
|
if (CheckPassword)
|
|
|
|
|
{
|
|
|
|
|
if (OnlyConfirmedIDs)
|
|
|
|
|
strcat (Query," AND usr_IDs.Confirmed='Y'");
|
|
|
|
|
|
|
|
|
|
// Get user's code if I have written the correct password
|
|
|
|
|
// or if password in database is empty (new user)
|
|
|
|
|
sprintf (SubQuery," AND usr_IDs.UsrCod=usr_data.UsrCod"
|
|
|
|
|
" AND (usr_data.Password='%s' OR usr_data.Password='')",
|
|
|
|
|
EncryptedPassword);
|
|
|
|
|
strcat (Query,SubQuery);
|
|
|
|
|
}
|
|
|
|
|
else if (OnlyConfirmedIDs)
|
|
|
|
|
strcat (Query," AND Confirmed='Y'");
|
|
|
|
|
|
|
|
|
|
ListUsrCods->NumUsrs = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get user's codes");
|
|
|
|
|
|
|
|
|
|
/***** Free memory for query string *****/
|
|
|
|
|
free ((void *) Query);
|
|
|
|
|
|
|
|
|
|
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 *****/
|
|
|
|
|
Par_GetParToText ("OtherUsrID",Gbl.Usrs.Other.UsrDat.IDs.List[0].ID,ID_MAX_LENGTH_USR_ID);
|
|
|
|
|
// 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...:
|
|
|
|
|
// 1. Must be ID_MIN_LENGTH_USR_ID <= characters <= ID_MAX_LENGTH_USR_ID.
|
|
|
|
|
// 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);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
if (Length < ID_MIN_LENGTH_USR_ID ||
|
|
|
|
|
Length > ID_MAX_LENGTH_USR_ID)
|
|
|
|
|
return false; // 1. Must be ID_MIN_LENGTH_USR_ID <= characters <= ID_MAX_LENGTH_USR_ID
|
|
|
|
|
|
|
|
|
|
/**** 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 *************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-04-23 13:23:09 +02:00
|
|
|
|
void ID_WriteUsrIDs (struct UsrData *UsrDat)
|
2014-12-01 23:55:08 +01:00
|
|
|
|
{
|
2016-04-23 23:39:07 +02:00
|
|
|
|
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
|
2014-12-01 23:55:08 +01:00
|
|
|
|
unsigned NumID;
|
2016-04-23 19:59:45 +02:00
|
|
|
|
bool ItsMe = (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
|
|
|
|
|
bool ICanSeeUsrID;
|
|
|
|
|
bool ICanConfirmUsrID;
|
|
|
|
|
|
|
|
|
|
if (ItsMe)
|
|
|
|
|
{
|
|
|
|
|
ICanSeeUsrID = true;
|
|
|
|
|
ICanConfirmUsrID = false;
|
|
|
|
|
}
|
|
|
|
|
else // A user distinct than me
|
|
|
|
|
{
|
|
|
|
|
ICanSeeUsrID = ID_ICanSeeAnotherUsrID (UsrDat);
|
|
|
|
|
ICanConfirmUsrID = ICanSeeUsrID &&
|
2016-04-23 23:39:07 +02:00
|
|
|
|
!Gbl.Form.Inside && // Only if not inside another form
|
|
|
|
|
Act_Actions[Gbl.Action.Act].BrowserWindow == Act_MAIN_WINDOW; // Only in main window
|
2016-04-23 19:59:45 +02:00
|
|
|
|
}
|
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)
|
2016-04-24 02:42:23 +02:00
|
|
|
|
ID_PutButtonToReqConfirmID (UsrDat,NumID);
|
2016-04-23 19:59:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************** Check if I can see another user's IDs *********************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
// This function should not be called when UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod
|
|
|
|
|
|
|
|
|
|
static bool ID_ICanSeeAnotherUsrID (struct UsrData *UsrDat)
|
|
|
|
|
{
|
|
|
|
|
/***** Check if I have permission to see another user's IDs *****/
|
|
|
|
|
switch (Gbl.Usrs.Me.LoggedRole)
|
|
|
|
|
{
|
|
|
|
|
case Rol_TEACHER:
|
|
|
|
|
/* If I am a teacher of current course,
|
|
|
|
|
I only can see the user's IDs of students from current course */
|
|
|
|
|
return (UsrDat->Accepted &&
|
|
|
|
|
UsrDat->RoleInCurrentCrsDB == Rol_STUDENT);
|
|
|
|
|
case Rol_DEG_ADM:
|
|
|
|
|
/* If I am an administrator of current degree,
|
|
|
|
|
I only can see the user's IDs of users from current degree */
|
|
|
|
|
return Usr_CheckIfUsrBelongsToDeg (UsrDat->UsrCod,Gbl.CurrentDeg.Deg.DegCod,true);
|
|
|
|
|
case Rol_CTR_ADM:
|
|
|
|
|
/* If I am an administrator of current centre,
|
|
|
|
|
I only can see the user's IDs of users from current centre */
|
|
|
|
|
return Usr_CheckIfUsrBelongsToCtr (UsrDat->UsrCod,Gbl.CurrentCtr.Ctr.CtrCod,true);
|
|
|
|
|
case Rol_INS_ADM:
|
|
|
|
|
/* If I am an administrator of current institution,
|
|
|
|
|
I only can see the user's IDs of users from current institution */
|
|
|
|
|
return Usr_CheckIfUsrBelongsToIns (UsrDat->UsrCod,Gbl.CurrentIns.Ins.InsCod,true);
|
|
|
|
|
case Rol_SYS_ADM:
|
|
|
|
|
return true;
|
|
|
|
|
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
|
|
|
|
/*****************************************************************************/
|
2016-04-24 02:42:23 +02:00
|
|
|
|
/******* Put a button to request the confirmation of another user's ID *******/
|
2016-04-23 23:47:22 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-04-24 02:42:23 +02:00
|
|
|
|
static void ID_PutButtonToReqConfirmID (struct UsrData *UsrDat,unsigned NumID)
|
2016-04-23 23:47:22 +02:00
|
|
|
|
{
|
2016-04-24 22:01:22 +02:00
|
|
|
|
extern const char *The_ClassFormBold[The_NUM_THEMES];
|
|
|
|
|
extern const char *Txt_Confirm_ID;
|
2016-04-24 02:42:23 +02:00
|
|
|
|
|
|
|
|
|
Act_FormStart ( UsrDat->RoleInCurrentCrsDB == Rol_STUDENT ? ActReqCnfID_Std :
|
|
|
|
|
(UsrDat->RoleInCurrentCrsDB == Rol_TEACHER ? ActReqCnfID_Tch :
|
|
|
|
|
ActReqCnfID_Oth)); // Guest, visitor or admin
|
|
|
|
|
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
|
|
|
|
|
fprintf (Gbl.F.Out,"<input type=\"hidden\" name=\"UsrID\" value=\"%s\" />",
|
|
|
|
|
UsrDat->IDs.List[NumID].ID);
|
2016-04-24 22:01:22 +02:00
|
|
|
|
Lay_PutIconLink ("ok_on16x16.gif",Txt_Confirm_ID,Txt_Confirm_ID,
|
|
|
|
|
The_ClassFormBold[Gbl.Prefs.Theme]);
|
2016-04-24 02:42:23 +02:00
|
|
|
|
Act_FormEnd ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/**************** Put a button to confirm another user's ID ******************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void ID_PutButtonToConfirmID (struct UsrData *UsrDat,unsigned NumID)
|
|
|
|
|
{
|
2016-04-24 22:01:22 +02:00
|
|
|
|
extern const char *Txt_Confirm_ID;
|
2016-04-24 02:42:23 +02:00
|
|
|
|
|
|
|
|
|
Act_FormStart ( UsrDat->RoleInCurrentCrsDB == Rol_STUDENT ? ActCnfID_Std :
|
|
|
|
|
(UsrDat->RoleInCurrentCrsDB == Rol_TEACHER ? ActCnfID_Tch :
|
|
|
|
|
ActCnfID_Oth)); // Guest, visitor or admin
|
|
|
|
|
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
|
|
|
|
|
fprintf (Gbl.F.Out,"<input type=\"hidden\" name=\"UsrID\" value=\"%s\" />",
|
|
|
|
|
UsrDat->IDs.List[NumID].ID);
|
2016-04-24 22:01:22 +02:00
|
|
|
|
Lay_PutCreateButton (Txt_Confirm_ID);
|
2016-04-24 02:42:23 +02:00
|
|
|
|
Act_FormEnd ();
|
2016-04-23 23:47:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-01 23:55:08 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*********** Put a link to the action used to request user's IDs *************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2015-04-02 18:39:49 +02:00
|
|
|
|
void ID_PutLinkToChangeUsrIDs (void)
|
2014-12-01 23:55:08 +01:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Change_IDs;
|
|
|
|
|
|
|
|
|
|
/***** Link for changing the password *****/
|
2015-04-03 00:15:51 +02:00
|
|
|
|
if (Gbl.Usrs.Other.UsrDat.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me
|
2015-12-13 18:32:37 +01:00
|
|
|
|
Lay_PutContextualLink (ActFrmUsrAcc,NULL,
|
2015-12-13 19:02:06 +01:00
|
|
|
|
"arroba64x64.gif",
|
|
|
|
|
Txt_Change_IDs,Txt_Change_IDs);
|
2015-04-03 00:15:51 +02:00
|
|
|
|
else // Not me
|
2015-12-13 18:32:37 +01:00
|
|
|
|
Lay_PutContextualLink ( Gbl.Usrs.Other.UsrDat.RoleInCurrentCrsDB == Rol_STUDENT ? ActFrmIDsStd :
|
2015-09-17 16:54:02 +02:00
|
|
|
|
(Gbl.Usrs.Other.UsrDat.RoleInCurrentCrsDB == Rol_TEACHER ? ActFrmIDsTch :
|
|
|
|
|
ActFrmIDsOth), // Guest, visitor or admin
|
2015-09-17 01:08:05 +02:00
|
|
|
|
Usr_PutParamOtherUsrCodEncrypted,
|
2015-12-13 19:02:06 +01:00
|
|
|
|
"arroba64x64.gif",
|
|
|
|
|
Txt_Change_IDs,Txt_Change_IDs);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************* Show form to the change of IDs of another user ****************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_ShowFormOthIDs (void)
|
|
|
|
|
{
|
2015-09-18 18:08:43 +02:00
|
|
|
|
extern const char *Txt_ID;
|
2014-12-01 23:55:08 +01:00
|
|
|
|
extern const char *Txt_User_not_found_or_you_do_not_have_permission_;
|
|
|
|
|
|
|
|
|
|
/***** Get user whose password must be changed *****/
|
|
|
|
|
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
|
|
|
|
|
{
|
|
|
|
|
if (Pwd_CheckIfICanChangeOtherUsrPassword (Gbl.Usrs.Other.UsrDat.UsrCod))
|
|
|
|
|
{
|
2015-09-18 18:08:43 +02:00
|
|
|
|
/***** Start frame *****/
|
2016-03-16 11:15:25 +01:00
|
|
|
|
Lay_StartRoundFrame (NULL,Txt_ID,NULL);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
|
2015-09-18 18:08:43 +02:00
|
|
|
|
/***** Show user's record *****/
|
2015-03-05 21:42:02 +01:00
|
|
|
|
Rec_ShowSharedUsrRecord (Rec_RECORD_LIST,&Gbl.Usrs.Other.UsrDat);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
|
2015-09-18 18:08:43 +02:00
|
|
|
|
/***** Form with the user's ID *****/
|
2016-03-18 14:07:21 +01:00
|
|
|
|
fprintf (Gbl.F.Out,"<table class=\"FRAME_TABLE CELLS_PAD_2\">");
|
2014-12-01 23:55:08 +01:00
|
|
|
|
ID_ShowFormChangeUsrID (&Gbl.Usrs.Other.UsrDat,
|
|
|
|
|
(Gbl.Usrs.Other.UsrDat.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod)); // It's me?
|
2015-09-18 18:08:43 +02:00
|
|
|
|
fprintf (Gbl.F.Out,"</table>");
|
|
|
|
|
|
|
|
|
|
/***** End frame *****/
|
|
|
|
|
Lay_EndRoundFrame ();
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_);
|
|
|
|
|
}
|
|
|
|
|
else // User not found
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*********************** Show form to change my user's ID ********************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_ShowFormChangeUsrID (const struct UsrData *UsrDat,bool ItsMe)
|
|
|
|
|
{
|
2015-07-27 21:25:45 +02:00
|
|
|
|
extern const char *The_ClassForm[The_NUM_THEMES];
|
2014-12-01 23:55:08 +01:00
|
|
|
|
extern const char *Txt_ID;
|
|
|
|
|
extern const char *Txt_ID_X_confirmed;
|
2016-04-23 17:12:01 +02:00
|
|
|
|
extern const char *Txt_ID_X_not_confirmed;
|
2014-12-01 23:55:08 +01:00
|
|
|
|
extern const char *Txt_Another_ID;
|
|
|
|
|
extern const char *Txt_Add_this_ID;
|
|
|
|
|
extern const char *Txt_If_there_are_multiple_versions_of_the_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;
|
|
|
|
|
|
|
|
|
|
/***** List existing user's IDs *****/
|
|
|
|
|
for (NumID = 0;
|
|
|
|
|
NumID < UsrDat->IDs.Num;
|
|
|
|
|
NumID++)
|
|
|
|
|
{
|
|
|
|
|
if (NumID == 0)
|
|
|
|
|
fprintf (Gbl.F.Out,"<tr>"
|
2015-07-27 21:25:45 +02:00
|
|
|
|
"<td class=\"%s RIGHT_TOP\">"
|
2014-12-23 01:36:58 +01:00
|
|
|
|
"%s:"
|
|
|
|
|
"</td>"
|
2015-09-18 02:15:35 +02:00
|
|
|
|
"<td class=\"LEFT_TOP\">",
|
2015-07-27 21:25:45 +02:00
|
|
|
|
The_ClassForm[Gbl.Prefs.Theme],Txt_ID);
|
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 */
|
2015-07-22 19:20:30 +02:00
|
|
|
|
Lay_PutIconRemovalNotAllowed ();
|
2014-12-01 23:55:08 +01:00
|
|
|
|
else // I can remove
|
|
|
|
|
{
|
|
|
|
|
/* Form to remove user's ID */
|
|
|
|
|
if (ItsMe)
|
2015-11-16 14:54:12 +01:00
|
|
|
|
Act_FormStart (ActRemID_Me);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
2015-09-17 16:54:02 +02:00
|
|
|
|
Act_FormStart ( UsrDat->RoleInCurrentCrsDB == Rol_STUDENT ? ActRemID_Std :
|
|
|
|
|
(UsrDat->RoleInCurrentCrsDB == Rol_TEACHER ? ActRemID_Tch :
|
|
|
|
|
ActRemID_Oth)); // Guest, visitor or admin
|
2015-04-02 18:39:49 +02:00
|
|
|
|
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
2015-07-22 19:59:28 +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);
|
2015-07-22 19:59:28 +02:00
|
|
|
|
Lay_PutIconRemove ();
|
2015-03-13 00:16:02 +01:00
|
|
|
|
Act_FormEnd ();
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* User's ID */
|
2016-04-23 17:12:01 +02:00
|
|
|
|
sprintf (Gbl.Title,
|
|
|
|
|
UsrDat->IDs.List[NumID].Confirmed ? Txt_ID_X_confirmed :
|
|
|
|
|
Txt_ID_X_not_confirmed,
|
|
|
|
|
UsrDat->IDs.List[NumID].ID);
|
|
|
|
|
fprintf (Gbl.F.Out,"<span class=\"USR_ID %s\" title=\"%s\">%s</span>",
|
|
|
|
|
UsrDat->IDs.List[NumID].Confirmed ? "USR_ID_C" :
|
|
|
|
|
"USR_ID_NC",
|
|
|
|
|
Gbl.Title,
|
|
|
|
|
UsrDat->IDs.List[NumID].ID);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
|
|
|
|
|
/* ID confirmed? */
|
|
|
|
|
if (UsrDat->IDs.List[NumID].Confirmed)
|
|
|
|
|
{
|
|
|
|
|
sprintf (Gbl.Title,Txt_ID_X_confirmed,UsrDat->IDs.List[NumID].ID);
|
|
|
|
|
fprintf (Gbl.F.Out,"<img src=\"%s/ok_green16x16.gif\""
|
2015-07-22 11:30:21 +02:00
|
|
|
|
" alt=\"%s\" title=\"%s\""
|
2015-12-13 12:51:41 +01:00
|
|
|
|
" class=\"ICON20x20\" />",
|
2014-12-01 23:55:08 +01:00
|
|
|
|
Gbl.Prefs.IconsURL,
|
2015-07-22 11:30:21 +02:00
|
|
|
|
Gbl.Title,Gbl.Title);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NumID == UsrDat->IDs.Num - 1)
|
|
|
|
|
fprintf (Gbl.F.Out,"</td>"
|
|
|
|
|
"</tr>");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Form to enter new user's ID *****/
|
|
|
|
|
if (UsrDat->IDs.Num < ID_MAX_IDS_PER_USER)
|
|
|
|
|
{
|
|
|
|
|
fprintf (Gbl.F.Out,"<tr>"
|
2015-07-27 21:25:45 +02:00
|
|
|
|
"<td class=\"%s RIGHT_MIDDLE\">"
|
2014-12-23 01:36:58 +01:00
|
|
|
|
"%s:"
|
|
|
|
|
"</td>"
|
2015-08-03 20:22:41 +02:00
|
|
|
|
"<td class=\"LEFT_MIDDLE\">",
|
2015-07-27 21:25:45 +02:00
|
|
|
|
The_ClassForm[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)
|
|
|
|
|
Act_FormStart (ActNewIDMe);
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-09-17 16:54:02 +02:00
|
|
|
|
Act_FormStart ( UsrDat->RoleInCurrentCrsDB == Rol_STUDENT ? ActNewID_Std :
|
|
|
|
|
(UsrDat->RoleInCurrentCrsDB == Rol_TEACHER ? ActNewID_Tch :
|
|
|
|
|
ActNewID_Oth)); // Guest, visitor or admin
|
2015-04-02 18:39:49 +02:00
|
|
|
|
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
2015-09-18 02:15:35 +02:00
|
|
|
|
fprintf (Gbl.F.Out,"<div class=\"FORM_ACCOUNT\">"
|
|
|
|
|
"<input type=\"text\" name=\"NewID\""
|
|
|
|
|
" size=\"20\" maxlength=\"%u\" value=\"%s\" />"
|
|
|
|
|
"</div>",
|
2014-12-01 23:55:08 +01:00
|
|
|
|
ID_MAX_LENGTH_USR_ID,
|
|
|
|
|
UsrDat->IDs.Num ? UsrDat->IDs.List[UsrDat->IDs.Num - 1].ID :
|
2015-03-24 17:47:26 +01:00
|
|
|
|
""); // Show the most recent ID
|
|
|
|
|
Lay_PutCreateButtonInline (Txt_Add_this_ID);
|
2015-03-13 00:16:02 +01:00
|
|
|
|
Act_FormEnd ();
|
|
|
|
|
fprintf (Gbl.F.Out,"</td>"
|
|
|
|
|
"</tr>"
|
|
|
|
|
"<tr>");
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Write help text *****/
|
2015-09-18 02:15:35 +02:00
|
|
|
|
fprintf (Gbl.F.Out,"<td colspan=\"2\" class=\"DAT CENTER_MIDDLE\">");
|
2014-12-13 21:38:31 +01:00
|
|
|
|
if (ItsMe)
|
|
|
|
|
fprintf (Gbl.F.Out,"%s ",
|
|
|
|
|
Txt_The_ID_is_used_in_order_to_facilitate_);
|
|
|
|
|
fprintf (Gbl.F.Out,"%s"
|
2014-12-01 23:55:08 +01:00
|
|
|
|
"</td>"
|
|
|
|
|
"</tr>",
|
|
|
|
|
Txt_If_there_are_multiple_versions_of_the_ID_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********************** Remove one of my user's IDs **************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_RemoveMyUsrID (void)
|
|
|
|
|
{
|
|
|
|
|
/***** Remove user's ID *****/
|
|
|
|
|
ID_RemoveUsrID (&Gbl.Usrs.Me.UsrDat,true); // It's me
|
|
|
|
|
|
|
|
|
|
/***** Update list of IDs *****/
|
|
|
|
|
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Me.UsrDat);
|
|
|
|
|
|
|
|
|
|
/***** Show my account again *****/
|
2014-12-12 22:39:55 +01:00
|
|
|
|
Acc_ShowFormChangeMyAccount ();
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/**************** Remove one of the user's IDs of another user ***************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_RemoveOtherUsrID (void)
|
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_User_not_found_or_you_do_not_have_permission_;
|
|
|
|
|
|
|
|
|
|
/***** Get other user's code from form and get user's data *****/
|
|
|
|
|
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
|
|
|
|
|
{
|
|
|
|
|
/***** Remove user's ID *****/
|
|
|
|
|
ID_RemoveUsrID (&Gbl.Usrs.Other.UsrDat,
|
|
|
|
|
(Gbl.Usrs.Other.UsrDat.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod)); // It's me?
|
|
|
|
|
|
|
|
|
|
/***** Update list of IDs *****/
|
|
|
|
|
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Other.UsrDat);
|
|
|
|
|
|
|
|
|
|
/***** Show user's record *****/
|
2015-03-05 21:42:02 +01:00
|
|
|
|
Rec_ShowSharedUsrRecord (Rec_RECORD_LIST,&Gbl.Usrs.Other.UsrDat);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
else // User not found
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** 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;
|
|
|
|
|
extern const char *Txt_User_not_found_or_you_do_not_have_permission_;
|
|
|
|
|
char UsrID[ID_MAX_LENGTH_USR_ID+1];
|
|
|
|
|
bool ICanRemove;
|
|
|
|
|
|
|
|
|
|
if (Pwd_CheckIfICanChangeOtherUsrPassword (UsrDat->UsrCod))
|
|
|
|
|
{
|
2016-04-24 02:42:23 +02:00
|
|
|
|
/***** Get user's ID from form *****/
|
2014-12-01 23:55:08 +01:00
|
|
|
|
Par_GetParToText ("UsrID",UsrID,ID_MAX_LENGTH_USR_ID);
|
|
|
|
|
// 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 *****/
|
|
|
|
|
sprintf (Gbl.Message,Txt_ID_X_removed,UsrID);
|
|
|
|
|
Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_You_can_not_delete_this_ID);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************************ Check if an ID is confirmed ************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static bool ID_CheckIfConfirmed (long UsrCod,const char *UsrID)
|
|
|
|
|
{
|
|
|
|
|
char Query[128];
|
|
|
|
|
|
|
|
|
|
/***** Get if ID is confirmed from database *****/
|
|
|
|
|
sprintf (Query,"SELECT COUNT(*) FROM usr_IDs"
|
|
|
|
|
" WHERE UsrCod='%ld' AND UsrID='%s' AND Confirmed='Y'",
|
|
|
|
|
UsrCod,UsrID);
|
|
|
|
|
return (DB_QueryCOUNT (Query,"can not check if ID is confirmed") != 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/**************** Remove one of my user's IDs from database ******************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void ID_RemoveUsrIDFromDB (long UsrCod,const char *UsrID)
|
|
|
|
|
{
|
|
|
|
|
char Query[256+ID_MAX_LENGTH_USR_ID];
|
|
|
|
|
|
|
|
|
|
/***** Remove one of my user's IDs *****/
|
|
|
|
|
sprintf (Query,"DELETE FROM usr_IDs"
|
|
|
|
|
" WHERE UsrCod='%ld' AND UsrID='%s'",
|
|
|
|
|
UsrCod,UsrID);
|
|
|
|
|
DB_QueryREPLACE (Query,"can not remove a user's ID");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************************* New user's ID for me ******************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_NewMyUsrID (void)
|
|
|
|
|
{
|
|
|
|
|
/***** Remove user's ID *****/
|
|
|
|
|
ID_NewUsrID (&Gbl.Usrs.Me.UsrDat,true); // It's me
|
|
|
|
|
|
|
|
|
|
/***** Update list of IDs *****/
|
|
|
|
|
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Me.UsrDat);
|
|
|
|
|
|
|
|
|
|
/***** Show my account again *****/
|
2014-12-12 22:39:55 +01:00
|
|
|
|
Acc_ShowFormChangeMyAccount ();
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********************* New user's ID for another user ************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_NewOtherUsrID (void)
|
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_User_not_found_or_you_do_not_have_permission_;
|
|
|
|
|
|
|
|
|
|
/***** Get other user's code from form and get user's data *****/
|
|
|
|
|
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
|
|
|
|
|
{
|
2015-11-16 14:54:12 +01:00
|
|
|
|
/***** New user's ID *****/
|
2014-12-01 23:55:08 +01:00
|
|
|
|
ID_NewUsrID (&Gbl.Usrs.Other.UsrDat,
|
|
|
|
|
(Gbl.Usrs.Other.UsrDat.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod)); // It's me?
|
|
|
|
|
|
|
|
|
|
/***** Update list of IDs *****/
|
|
|
|
|
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Other.UsrDat);
|
|
|
|
|
|
|
|
|
|
/***** Show user's record *****/
|
2015-03-05 21:42:02 +01:00
|
|
|
|
Rec_ShowSharedUsrRecord (Rec_RECORD_LIST,&Gbl.Usrs.Other.UsrDat);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
}
|
|
|
|
|
else // User not found
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** 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;
|
|
|
|
|
extern const char *Txt_User_not_found_or_you_do_not_have_permission_;
|
|
|
|
|
char NewID[ID_MAX_LENGTH_USR_ID+1];
|
|
|
|
|
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
|
|
|
|
bool Error = false;
|
|
|
|
|
|
|
|
|
|
if (Pwd_CheckIfICanChangeOtherUsrPassword (UsrDat->UsrCod))
|
|
|
|
|
{
|
|
|
|
|
/***** Get new user's ID from form *****/
|
|
|
|
|
Par_GetParToText ("NewID",NewID,ID_MAX_LENGTH_USR_ID);
|
|
|
|
|
// 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)
|
2014-12-01 23:55:08 +01:00
|
|
|
|
{
|
|
|
|
|
Error = true;
|
|
|
|
|
sprintf (Gbl.Message,Txt_The_ID_X_matches_one_of_the_existing,
|
|
|
|
|
NewID);
|
|
|
|
|
}
|
|
|
|
|
else // It's not me && !Confirmed
|
|
|
|
|
{
|
|
|
|
|
/***** Mark this ID as confirmed *****/
|
2016-04-25 00:06:44 +02:00
|
|
|
|
ID_ConfirmUsrID (UsrDat,NewID);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
sprintf (Gbl.Message,Txt_The_ID_X_has_been_confirmed,
|
|
|
|
|
NewID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (UsrDat->IDs.Num >= ID_MAX_IDS_PER_USER)
|
|
|
|
|
{
|
|
|
|
|
Error = true;
|
|
|
|
|
sprintf (Gbl.Message,Txt_A_user_can_not_have_more_than_X_IDs,
|
|
|
|
|
ID_MAX_IDS_PER_USER);
|
|
|
|
|
}
|
|
|
|
|
else // OK ==> add this new ID to my list of IDs
|
|
|
|
|
{
|
|
|
|
|
/***** Save this new ID *****/
|
|
|
|
|
// It's me ==> ID not confirmed
|
|
|
|
|
// It's not me ==> ID confirmed
|
|
|
|
|
ID_InsertANewUsrIDInDB (UsrDat->UsrCod,NewID,!ItsMe);
|
|
|
|
|
|
|
|
|
|
sprintf (Gbl.Message,Txt_The_ID_X_has_been_registered_successfully,
|
|
|
|
|
NewID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // New ID is not valid
|
|
|
|
|
{
|
|
|
|
|
Error = true;
|
|
|
|
|
sprintf (Gbl.Message,Txt_The_ID_X_is_not_valid,NewID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Show message *****/
|
|
|
|
|
Lay_ShowAlert (Error ? Lay_WARNING :
|
2016-04-25 00:06:44 +02:00
|
|
|
|
Lay_SUCCESS,
|
2014-12-01 23:55:08 +01:00
|
|
|
|
Gbl.Message);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/******************* Insert a new ID for me in database **********************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void ID_InsertANewUsrIDInDB (long UsrCod,const char *NewID,bool Confirmed)
|
|
|
|
|
{
|
|
|
|
|
char Query[256+ID_MAX_LENGTH_USR_ID];
|
|
|
|
|
|
|
|
|
|
/***** Update my nickname in database *****/
|
|
|
|
|
sprintf (Query,"INSERT INTO usr_IDs"
|
|
|
|
|
" (UsrCod,UsrID,CreatTime,Confirmed)"
|
|
|
|
|
" VALUES ('%ld','%s',NOW(),'%c')",
|
|
|
|
|
UsrCod,NewID,
|
|
|
|
|
Confirmed ? 'Y' :
|
|
|
|
|
'N');
|
|
|
|
|
DB_QueryINSERT (Query,"can not insert a new ID");
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-24 02:42:23 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*************** Request the confirmation of another user's ID ***************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_RequestConfirmOtherUsrID (void)
|
2016-04-25 00:06:44 +02:00
|
|
|
|
{
|
|
|
|
|
ID_ReqConfOrConfOtherUsrID (ID_REQUEST_CONFIRM_ID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************************ Confirm another user's ID **************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void ID_ConfirmOtherUsrID (void)
|
|
|
|
|
{
|
|
|
|
|
ID_ReqConfOrConfOtherUsrID (ID_CONFIRM_ID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********** Request the confirmation or confirm another user's ID ************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void ID_ReqConfOrConfOtherUsrID (ID_ReqConfOrConfID_t ReqConfOrConfID)
|
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;
|
|
|
|
|
extern const char *Txt_Do_you_want_to_confirm_the_ID_X;
|
2016-04-25 00:06:44 +02:00
|
|
|
|
extern const char *Txt_The_ID_X_has_been_confirmed;
|
2016-04-24 02:42:23 +02:00
|
|
|
|
extern const char *Txt_User_not_found_or_you_do_not_have_permission_;
|
|
|
|
|
char UsrID[ID_MAX_LENGTH_USR_ID+1];
|
|
|
|
|
bool ICanConfirm = false;
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
/***** Get other user's code from form and get user's data *****/
|
|
|
|
|
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
|
|
|
|
|
if (Gbl.Usrs.Other.UsrDat.UsrCod != Gbl.Usrs.Me.UsrDat.UsrCod) // Not me
|
|
|
|
|
if (ID_ICanSeeAnotherUsrID (&Gbl.Usrs.Other.UsrDat))
|
|
|
|
|
ICanConfirm = true;
|
|
|
|
|
|
|
|
|
|
if (ICanConfirm)
|
|
|
|
|
{
|
|
|
|
|
/***** Get user's ID from form *****/
|
|
|
|
|
Par_GetParToText ("UsrID",UsrID,ID_MAX_LENGTH_USR_ID);
|
|
|
|
|
// 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 *****/
|
2016-04-24 22:01:22 +02:00
|
|
|
|
sprintf (Gbl.Message,Txt_ID_X_had_already_been_confirmed,
|
2016-04-24 02:42:23 +02:00
|
|
|
|
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].ID);
|
|
|
|
|
Lay_ShowAlert (Lay_INFO,Gbl.Message);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-04-25 00:06:44 +02:00
|
|
|
|
switch (ReqConfOrConfID)
|
|
|
|
|
{
|
|
|
|
|
case ID_REQUEST_CONFIRM_ID: // Ask if confirm ID
|
|
|
|
|
/***** Ask for confirmation *****/
|
|
|
|
|
sprintf (Gbl.Message,Txt_Do_you_want_to_confirm_the_ID_X,
|
|
|
|
|
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].ID);
|
|
|
|
|
Lay_ShowAlert (Lay_INFO,Gbl.Message);
|
|
|
|
|
|
|
|
|
|
/***** Put button to confirm ID *****/
|
|
|
|
|
ID_PutButtonToConfirmID (&Gbl.Usrs.Other.UsrDat,NumIDFound);
|
|
|
|
|
break;
|
|
|
|
|
case ID_CONFIRM_ID: // Confirm ID
|
|
|
|
|
/***** 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 *****/
|
|
|
|
|
sprintf (Gbl.Message,Txt_The_ID_X_has_been_confirmed,
|
|
|
|
|
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].ID);
|
|
|
|
|
Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-04-24 02:42:23 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // User's ID not found
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_);
|
|
|
|
|
|
|
|
|
|
/***** Show user's record *****/
|
|
|
|
|
Rec_ShowSharedUsrRecord (Rec_RECORD_LIST,&Gbl.Usrs.Other.UsrDat);
|
|
|
|
|
}
|
|
|
|
|
else // User not found
|
|
|
|
|
Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_);
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
{
|
|
|
|
|
char Query[256+ID_MAX_LENGTH_USR_ID];
|
|
|
|
|
|
2016-04-25 00:06:44 +02:00
|
|
|
|
/***** Update database *****/
|
2014-12-01 23:55:08 +01:00
|
|
|
|
sprintf (Query,"UPDATE usr_IDs SET Confirmed='Y'"
|
|
|
|
|
" WHERE UsrCod='%ld' AND UsrID='%s' AND Confirmed<>'Y'",
|
2016-04-25 00:06:44 +02:00
|
|
|
|
UsrDat->UsrCod,UsrID);
|
2014-12-01 23:55:08 +01:00
|
|
|
|
DB_QueryINSERT (Query,"can not confirm a user's ID");
|
|
|
|
|
}
|