Version 21.9: Sep 20, 2021 New module swad_ID_database for database queries related to user's IDs.

This commit is contained in:
acanas 2021-09-20 22:01:59 +02:00
parent 0fd2757875
commit 9be6a88866
11 changed files with 482 additions and 359 deletions

View File

@ -55,8 +55,9 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \
swad_group_database.o swad_help.o swad_hierarchy.o \
swad_hierarchy_config.o swad_hierarchy_database.o swad_holiday.o \
swad_holiday_database.o swad_HTML.o \
swad_icon.o swad_ID.o swad_indicator.o swad_info.o swad_institution.o \
swad_institution_config.o swad_institution_database.o \
swad_icon.o swad_ID.o swad_ID_database.o swad_indicator.o swad_info.o \
swad_institution.o swad_institution_config.o \
swad_institution_database.o \
swad_language.o swad_layout.o swad_link.o swad_log.o swad_logo.o \
swad_MAC.o swad_mail.o swad_main.o swad_maintenance.o swad_map.o \
swad_mark.o swad_match.o swad_match_print.o swad_match_result.o \

436
swad_ID.c
View File

@ -39,6 +39,7 @@
#include "swad_hierarchy_level.h"
#include "swad_HTML.h"
#include "swad_ID.h"
#include "swad_ID_database.h"
#include "swad_parameter.h"
#include "swad_QR.h"
#include "swad_user.h"
@ -80,29 +81,8 @@ static void ID_PutParamsRemoveMyID (void *ID);
static void ID_PutParamsRemoveOtherID (void *ID);
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);
/*****************************************************************************/
/*************************** Create new user's ID ****************************/
/*****************************************************************************/
void ID_DB_InsertANewUsrID (long UsrCod,
const char ID[ID_MAX_BYTES_USR_ID + 1],
bool Confirmed)
{
DB_QueryINSERT ("can not create user's ID",
"INSERT INTO usr_ids"
" (UsrCod,UsrID,CreatTime,Confirmed)"
" VALUES"
" (%ld,'%s',NOW(),'%c')",
UsrCod,
ID,
Confirmed ? 'Y' :
'N');
}
/*****************************************************************************/
/********************** Get list of IDs of a user ****************************/
/*****************************************************************************/
@ -122,16 +102,7 @@ void ID_GetListIDsFromUsrCod (struct UsrData *UsrDat)
/***** Get user's IDs from database *****/
// First the confirmed (Confirmed == 'Y')
// Then the unconfirmed (Confirmed == 'N')
NumIDs = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get user's IDs",
"SELECT UsrID," // row[0]
"Confirmed" // row[1]
" FROM usr_ids"
" WHERE UsrCod=%ld"
" ORDER BY Confirmed DESC,"
"UsrID",
UsrDat->UsrCod);
if (NumIDs)
if ((NumIDs = ID_DB_GetIDsFromUsrCod (&mysql_res,UsrDat->UsrCod)))
{
/***** Allocate space for the list *****/
ID_ReallocateListIDs (UsrDat,NumIDs);
@ -200,72 +171,15 @@ unsigned ID_GetListUsrCodsFromUsrID (struct UsrData *UsrDat,
struct ListUsrCods *ListUsrCods,
bool OnlyConfirmedIDs)
{
char *SubQueryAllUsrs = NULL;
char SubQueryOneUsr[1 + ID_MAX_BYTES_USR_ID + 1 + 1];
MYSQL_RES *mysql_res;
size_t MaxLength;
unsigned NumID;
unsigned NumUsr;
bool CheckPassword = false;
if (UsrDat->IDs.Num)
{
if (EncryptedPassword)
if (EncryptedPassword[0])
CheckPassword = true;
/***** Allocate memory for subquery string *****/
MaxLength = 512 + UsrDat->IDs.Num * (1 + ID_MAX_BYTES_USR_ID + 1) - 1;
if ((SubQueryAllUsrs = malloc (MaxLength + 1)) == NULL)
Err_NotEnoughMemoryExit ();
SubQueryAllUsrs[0] = '\0';
/***** Get user's code(s) from database *****/
for (NumID = 0;
NumID < UsrDat->IDs.Num;
NumID++)
{
if (NumID)
Str_Concat (SubQueryAllUsrs,",",MaxLength);
sprintf (SubQueryOneUsr,"'%s'",UsrDat->IDs.List[NumID].ID);
Str_Concat (SubQueryAllUsrs,SubQueryOneUsr,MaxLength);
}
if (CheckPassword)
{
// Get user's code if I have written the correct password
// or if password in database is empty (new user)
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 (SubQueryAllUsrs);
if (ListUsrCods->NumUsrs)
if ((ListUsrCods->NumUsrs = ID_DB_GetUsrCodsFromUsrID (&mysql_res,
UsrDat,
EncryptedPassword,
OnlyConfirmedIDs)))
{
/***** Allocate space for the list of users' codes *****/
Usr_AllocateListUsrCods (ListUsrCods);
@ -516,10 +430,10 @@ static void ID_PutLinkToConfirmID (struct UsrData *UsrDat,unsigned NumID,
Usr_PutParamUsrCodEncrypted (UsrDat->EnUsrCod);
Par_PutHiddenParamString (NULL,"UsrID",UsrDat->IDs.List[NumID].ID);
/***** Put link *****/
HTM_BUTTON_SUBMIT_Begin (Txt_Confirm_ID,The_ClassFormLinkOutBoxBold[Gbl.Prefs.Theme],NULL);
Ico_PutIconTextLink ("check.svg",Txt_Confirm_ID);
HTM_BUTTON_End ();
/***** Put link *****/
HTM_BUTTON_SUBMIT_Begin (Txt_Confirm_ID,The_ClassFormLinkOutBoxBold[Gbl.Prefs.Theme],NULL);
Ico_PutIconTextLink ("check.svg",Txt_Confirm_ID);
HTM_BUTTON_End ();
/***** End form *****/
Frm_EndForm ();
@ -538,18 +452,18 @@ void ID_ShowFormChangeMyID (bool IShouldFillInID)
/***** Begin section *****/
HTM_SECTION_Begin (ID_ID_SECTION_ID);
/***** Begin box *****/
snprintf (StrRecordWidth,sizeof (StrRecordWidth),"%upx",Rec_RECORD_WIDTH);
Box_BoxBegin (StrRecordWidth,Txt_ID,
Acc_PutLinkToRemoveMyAccount,NULL,
Hlp_PROFILE_Account,Box_NOT_CLOSABLE);
/***** Begin box *****/
snprintf (StrRecordWidth,sizeof (StrRecordWidth),"%upx",Rec_RECORD_WIDTH);
Box_BoxBegin (StrRecordWidth,Txt_ID,
Acc_PutLinkToRemoveMyAccount,NULL,
Hlp_PROFILE_Account,Box_NOT_CLOSABLE);
/***** Show form to change ID *****/
ID_ShowFormChangeUsrID (true, // ItsMe
IShouldFillInID);
/***** Show form to change ID *****/
ID_ShowFormChangeUsrID (true, // ItsMe
IShouldFillInID);
/***** End box *****/
Box_BoxEnd ();
/***** End box *****/
Box_BoxEnd ();
/***** End section *****/
HTM_SECTION_End ();
@ -568,18 +482,18 @@ void ID_ShowFormChangeOtherUsrID (void)
/***** Begin section *****/
HTM_SECTION_Begin (ID_ID_SECTION_ID);
/***** Begin box *****/
snprintf (StrRecordWidth,sizeof (StrRecordWidth),"%upx",Rec_RECORD_WIDTH);
Box_BoxBegin (StrRecordWidth,Txt_ID,
NULL,NULL,
Hlp_PROFILE_Account,Box_NOT_CLOSABLE);
/***** Begin box *****/
snprintf (StrRecordWidth,sizeof (StrRecordWidth),"%upx",Rec_RECORD_WIDTH);
Box_BoxBegin (StrRecordWidth,Txt_ID,
NULL,NULL,
Hlp_PROFILE_Account,Box_NOT_CLOSABLE);
/***** Show form to change ID *****/
ID_ShowFormChangeUsrID (false, // ItsMe
false); // IShouldFillInID
/***** Show form to change ID *****/
ID_ShowFormChangeUsrID (false, // ItsMe
false); // IShouldFillInID
/***** End box *****/
Box_BoxEnd ();
/***** End box *****/
Box_BoxEnd ();
/***** End section *****/
HTM_SECTION_End ();
@ -614,128 +528,129 @@ static void ID_ShowFormChangeUsrID (bool ItsMe,bool IShouldFillInID)
/***** Begin table *****/
HTM_TABLE_BeginWidePadding (2);
/***** List existing user's IDs *****/
for (NumID = 0;
NumID < UsrDat->IDs.Num;
NumID++)
{
if (NumID == 0)
/***** List existing user's IDs *****/
for (NumID = 0;
NumID < UsrDat->IDs.Num;
NumID++)
{
HTM_TR_Begin (NULL);
/* Label */
Frm_LabelColumn ("REC_C1_BOT RT",NULL,Txt_ID);
/* Data */
HTM_TD_Begin ("class=\"REC_C2_BOT LT USR_ID\"");
}
else // NumID >= 1
HTM_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 */
Ico_PutIconRemovalNotAllowed ();
else // I can remove
if (NumID == 0)
{
/* Form to remove user's ID */
if (ItsMe)
Ico_PutContextualIconToRemove (ActRemMyID,ID_ID_SECTION_ID,
ID_PutParamsRemoveMyID,UsrDat->IDs.List[NumID].ID);
else
HTM_TR_Begin (NULL);
/* Label */
Frm_LabelColumn ("REC_C1_BOT RT",NULL,Txt_ID);
/* Data */
HTM_TD_Begin ("class=\"REC_C2_BOT LT USR_ID\"");
}
else // NumID >= 1
HTM_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 */
Ico_PutIconRemovalNotAllowed ();
else // I can remove
{
switch (UsrDat->Roles.InCurrentCrs)
/* Form to remove user's ID */
if (ItsMe)
Ico_PutContextualIconToRemove (ActRemMyID,ID_ID_SECTION_ID,
ID_PutParamsRemoveMyID,UsrDat->IDs.List[NumID].ID);
else
{
case Rol_STD:
NextAction = ActRemID_Std;
break;
case Rol_NET:
case Rol_TCH:
NextAction = ActRemID_Tch;
break;
default: // Guest, user or admin
NextAction = ActRemID_Oth;
break;
switch (UsrDat->Roles.InCurrentCrs)
{
case Rol_STD:
NextAction = ActRemID_Std;
break;
case Rol_NET:
case Rol_TCH:
NextAction = ActRemID_Tch;
break;
default: // Guest, user or admin
NextAction = ActRemID_Oth;
break;
}
Ico_PutContextualIconToRemove (NextAction,ID_ID_SECTION_ID,
ID_PutParamsRemoveOtherID,UsrDat->IDs.List[NumID].ID);
}
Ico_PutContextualIconToRemove (NextAction,ID_ID_SECTION_ID,
ID_PutParamsRemoveOtherID,UsrDat->IDs.List[NumID].ID);
}
}
}
/* User's ID */
HTM_SPAN_Begin ("class=\"%s\" title=\"%s\"",
UsrDat->IDs.List[NumID].Confirmed ? "USR_ID_C" :
"USR_ID_NC",
Str_BuildStringStr (UsrDat->IDs.List[NumID].Confirmed ? Txt_ID_X_confirmed :
Txt_ID_X_not_confirmed,
UsrDat->IDs.List[NumID].ID));
Str_FreeString ();
HTM_Txt (UsrDat->IDs.List[NumID].ID);
HTM_Txt (UsrDat->IDs.List[NumID].Confirmed ? "&check;" :
"");
HTM_SPAN_End ();
if (NumID == UsrDat->IDs.Num - 1)
{
HTM_TD_End ();
HTM_TR_End ();
}
}
/* User's ID */
HTM_SPAN_Begin ("class=\"%s\" title=\"%s\"",
UsrDat->IDs.List[NumID].Confirmed ? "USR_ID_C" :
"USR_ID_NC",
Str_BuildStringStr (UsrDat->IDs.List[NumID].Confirmed ? Txt_ID_X_confirmed :
Txt_ID_X_not_confirmed,
UsrDat->IDs.List[NumID].ID));
Str_FreeString ();
HTM_Txt (UsrDat->IDs.List[NumID].ID);
HTM_Txt (UsrDat->IDs.List[NumID].Confirmed ? "&check;" :
"");
HTM_SPAN_End ();
if (UsrDat->IDs.Num < ID_MAX_IDS_PER_USER)
{
/***** Write help text *****/
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"2\" class=\"DAT CM\"");
Ale_ShowAlert (Ale_INFO,Txt_The_ID_is_used_in_order_to_facilitate_);
HTM_TD_End ();
HTM_TR_End ();
/***** Form to enter new user's ID *****/
HTM_TR_Begin (NULL);
/* Label */
Frm_LabelColumn ("REC_C1_BOT RT","NewID",
UsrDat->IDs.Num ? Txt_Another_ID : // A new user's ID
Txt_ID); // The first user's ID
/* Data */
HTM_TD_Begin ("class=\"REC_C2_BOT LT DAT\"");
if (ItsMe)
Frm_BeginFormAnchor (ActChgMyID,ID_ID_SECTION_ID);
else
{
switch (UsrDat->Roles.InCurrentCrs)
if (NumID == UsrDat->IDs.Num - 1)
{
case Rol_STD:
NextAction = ActNewID_Std;
break;
case Rol_NET:
case Rol_TCH:
NextAction = ActNewID_Tch;
break;
default: // Guest, user or admin
NextAction = ActNewID_Oth;
break;
HTM_TD_End ();
HTM_TR_End ();
}
Frm_BeginFormAnchor (NextAction,ID_ID_SECTION_ID);
Usr_PutParamUsrCodEncrypted (UsrDat->EnUsrCod);
}
HTM_INPUT_TEXT ("NewID",ID_MAX_BYTES_USR_ID,
UsrDat->IDs.Num ? UsrDat->IDs.List[UsrDat->IDs.Num - 1].ID :
"", // Show the most recent ID
HTM_DONT_SUBMIT_ON_CHANGE,
"id=\"NewID\" size=\"18\"");
HTM_BR ();
Btn_PutCreateButtonInline (Txt_Add_this_ID);
Frm_EndForm ();
HTM_TD_End ();
HTM_TR_End ();
}
if (UsrDat->IDs.Num < ID_MAX_IDS_PER_USER)
{
/***** Write help text *****/
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"2\" class=\"DAT CM\"");
Ale_ShowAlert (Ale_INFO,Txt_The_ID_is_used_in_order_to_facilitate_);
HTM_TD_End ();
HTM_TR_End ();
/***** Form to enter new user's ID *****/
HTM_TR_Begin (NULL);
/* Label */
Frm_LabelColumn ("REC_C1_BOT RT","NewID",
UsrDat->IDs.Num ? Txt_Another_ID : // A new user's ID
Txt_ID); // The first user's ID
/* Data */
HTM_TD_Begin ("class=\"REC_C2_BOT LT DAT\"");
if (ItsMe)
Frm_BeginFormAnchor (ActChgMyID,ID_ID_SECTION_ID);
else
{
switch (UsrDat->Roles.InCurrentCrs)
{
case Rol_STD:
NextAction = ActNewID_Std;
break;
case Rol_NET:
case Rol_TCH:
NextAction = ActNewID_Tch;
break;
default: // Guest, user or admin
NextAction = ActNewID_Oth;
break;
}
Frm_BeginFormAnchor (NextAction,ID_ID_SECTION_ID);
Usr_PutParamUsrCodEncrypted (UsrDat->EnUsrCod);
}
HTM_INPUT_TEXT ("NewID",ID_MAX_BYTES_USR_ID,
UsrDat->IDs.Num ? UsrDat->IDs.List[UsrDat->IDs.Num - 1].ID :
"", // Show the most recent ID
HTM_DONT_SUBMIT_ON_CHANGE,
"id=\"NewID\" size=\"18\"");
HTM_BR ();
Btn_PutCreateButtonInline (Txt_Add_this_ID);
Frm_EndForm ();
HTM_TD_End ();
HTM_TR_End ();
}
/***** End table *****/
HTM_TABLE_End ();
@ -826,14 +741,14 @@ static void ID_RemoveUsrID (const struct UsrData *UsrDat,bool ItsMe)
ICanRemove = false;
else if (ItsMe)
// I can remove my ID only if it is not confirmed
ICanRemove = !ID_CheckIfConfirmed (UsrDat->UsrCod,UsrID);
ICanRemove = !ID_DB_CheckIfConfirmed (UsrDat->UsrCod,UsrID);
else
ICanRemove = true;
if (ICanRemove)
{
/***** Remove one of the user's IDs *****/
ID_RemoveUsrIDFromDB (UsrDat->UsrCod,UsrID);
ID_DB_RemoveUsrID (UsrDat->UsrCod,UsrID);
/***** Show message *****/
Ale_CreateAlert (Ale_SUCCESS,ID_ID_SECTION_ID,
@ -848,50 +763,6 @@ static void ID_RemoveUsrID (const struct UsrData *UsrDat,bool ItsMe)
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
}
/*****************************************************************************/
/************************ Check if an ID is confirmed ************************/
/*****************************************************************************/
static bool ID_CheckIfConfirmed (long UsrCod,const char *UsrID)
{
/***** Get if ID is confirmed from database *****/
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);
}
/*****************************************************************************/
/**************** 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 *****/
DB_QueryREPLACE ("can not remove a user's ID",
"DELETE FROM usr_ids"
" WHERE UsrCod=%ld"
" AND UsrID='%s'",
UsrCod,
UsrID);
}
/*****************************************************************************/
/****************************** Remove user's IDs ****************************/
/*****************************************************************************/
void ID_DB_RemoveUsrIDs (long UsrCod)
{
DB_QueryDELETE ("can not remove user's IDs",
"DELETE FROM usr_ids"
" WHERE UsrCod=%ld",
UsrCod);
}
/*****************************************************************************/
/************************* New user's ID for me ******************************/
/*****************************************************************************/
@ -984,7 +855,7 @@ static void ID_NewUsrID (const struct UsrData *UsrDat,bool ItsMe)
else // It's not me && !Confirmed
{
/***** Mark this ID as confirmed *****/
ID_ConfirmUsrID (UsrDat,NewID);
ID_DB_ConfirmUsrID (UsrDat->UsrCod,NewID);
Ale_CreateAlert (Ale_SUCCESS,ID_ID_SECTION_ID,
Txt_The_ID_X_has_been_confirmed,
@ -1081,8 +952,8 @@ void ID_ConfirmOtherUsrID (void)
else
{
/***** Mark this ID as confirmed *****/
ID_ConfirmUsrID (&Gbl.Usrs.Other.UsrDat,
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].ID);
ID_DB_ConfirmUsrID (Gbl.Usrs.Other.UsrDat.UsrCod,
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].ID);
Gbl.Usrs.Other.UsrDat.IDs.List[NumIDFound].Confirmed = true;
/***** Write success message *****/
@ -1122,20 +993,3 @@ void ID_ConfirmOtherUsrID (void)
break;
}
}
/*****************************************************************************/
/*********************** Set a user's ID as confirmed ************************/
/*****************************************************************************/
void ID_ConfirmUsrID (const struct UsrData *UsrDat,const char *UsrID)
{
/***** Update database *****/
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);
}

View File

@ -55,10 +55,6 @@ struct ListIDs
/***************************** Public prototypes *****************************/
/*****************************************************************************/
void ID_DB_InsertANewUsrID (long UsrCod,
const char ID[ID_MAX_BYTES_USR_ID + 1],
bool Confirmed);
void ID_GetListIDsFromUsrCod (struct UsrData *UsrDat);
void ID_ReallocateListIDs (struct UsrData *UsrDat,unsigned NumIDs);
void ID_FreeListIDs (struct UsrData *UsrDat);
@ -81,11 +77,9 @@ void ID_ShowFormChangeOtherUsrID (void);
void ID_RemoveMyUsrID (void);
void ID_RemoveOtherUsrID (void);
void ID_DB_RemoveUsrIDs (long UsrCod);
void ID_NewMyUsrID (void);
void ID_NewOtherUsrID (void);
void ID_ConfirmOtherUsrID (void);
void ID_ConfirmUsrID (const struct UsrData *UsrDat,const char *UsrID);
#endif

221
swad_ID_database.c Normal file
View File

@ -0,0 +1,221 @@
// swad_ID_database.c: Users' IDs operations with database
/*
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.
Copyright (C) 1999-2021 Antonio Cañas Vargas
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 "swad_database.h"
#include "swad_error.h"
#include "swad_ID.h"
#include "swad_ID_database.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
/*****************************************************************************/
/*************************** Create new user's ID ****************************/
/*****************************************************************************/
void ID_DB_InsertANewUsrID (long UsrCod,
const char ID[ID_MAX_BYTES_USR_ID + 1],
bool Confirmed)
{
DB_QueryINSERT ("can not create user's ID",
"INSERT INTO usr_ids"
" (UsrCod,UsrID,CreatTime,Confirmed)"
" VALUES"
" (%ld,'%s',NOW(),'%c')",
UsrCod,
ID,
Confirmed ? 'Y' :
'N');
}
/*****************************************************************************/
/*********************** Set a user's ID as confirmed ************************/
/*****************************************************************************/
void ID_DB_ConfirmUsrID (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1])
{
DB_QueryINSERT ("can not confirm a user's ID",
"UPDATE usr_ids"
" SET Confirmed='Y'"
" WHERE UsrCod=%ld"
" AND UsrID='%s'"
" AND Confirmed<>'Y'",
UsrCod,
ID);
}
/*****************************************************************************/
/********************** Get list of IDs of a user ****************************/
/*****************************************************************************/
unsigned ID_DB_GetIDsFromUsrCod (MYSQL_RES **mysql_res,long UsrCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get user's IDs",
"SELECT UsrID," // row[0]
"Confirmed" // row[1]
" FROM usr_ids"
" WHERE UsrCod=%ld"
" ORDER BY Confirmed DESC,"
"UsrID",
UsrCod);
}
/*****************************************************************************/
/************************ Check if an ID is confirmed ************************/
/*****************************************************************************/
bool ID_DB_CheckIfConfirmed (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1])
{
/***** Get if ID is confirmed from database *****/
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,
ID) != 0);
}
/*****************************************************************************/
/***************** Get list of user codes from user's IDs ********************/
/*****************************************************************************/
// Returns the number of users with any of these IDs
unsigned ID_DB_GetUsrCodsFromUsrID (MYSQL_RES **mysql_res,
const struct UsrData *UsrDat,
const char *EncryptedPassword, // If NULL or empty ==> do not check password
bool OnlyConfirmedIDs)
{
char *SubQueryAllUsrs = NULL;
char SubQueryOneUsr[1 + ID_MAX_BYTES_USR_ID + 1 + 1];
size_t MaxLength;
unsigned NumID;
unsigned NumUsrs;
bool CheckPassword = false;
if (EncryptedPassword)
if (EncryptedPassword[0])
CheckPassword = true;
/***** Allocate memory for subquery string *****/
MaxLength = 512 + UsrDat->IDs.Num * (1 + ID_MAX_BYTES_USR_ID + 1) - 1;
if ((SubQueryAllUsrs = malloc (MaxLength + 1)) == NULL)
Err_NotEnoughMemoryExit ();
SubQueryAllUsrs[0] = '\0';
/***** Get user's code(s) from database *****/
for (NumID = 0;
NumID < UsrDat->IDs.Num;
NumID++)
{
if (NumID)
Str_Concat (SubQueryAllUsrs,",",MaxLength);
sprintf (SubQueryOneUsr,"'%s'",UsrDat->IDs.List[NumID].ID);
Str_Concat (SubQueryAllUsrs,SubQueryOneUsr,MaxLength);
}
if (CheckPassword)
{
// Get user's code if I have written the correct password
// or if password in database is empty (new user)
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
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 (SubQueryAllUsrs);
return NumUsrs;
}
/*****************************************************************************/
/**************** Remove one of my user's IDs from database ******************/
/*****************************************************************************/
void ID_DB_RemoveUsrID (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1])
{
DB_QueryREPLACE ("can not remove a user's ID",
"DELETE FROM usr_ids"
" WHERE UsrCod=%ld"
" AND UsrID='%s'",
UsrCod,
ID);
}
/*****************************************************************************/
/****************************** Remove user's IDs ****************************/
/*****************************************************************************/
void ID_DB_RemoveUsrIDs (long UsrCod)
{
DB_QueryDELETE ("can not remove user's IDs",
"DELETE FROM usr_ids"
" WHERE UsrCod=%ld",
UsrCod);
}

53
swad_ID_database.h Normal file
View File

@ -0,0 +1,53 @@
// swad_ID_database.h: Users' IDs operations with database
#ifndef _SWAD_ID_DB
#define _SWAD_ID_DB
/*
SWAD (Shared Workspace At a Distance in Spanish),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2021 Antonio Cañas Vargas
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 ***********************************/
/*****************************************************************************/
/*****************************************************************************/
/************************* Public types and constants ************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
void ID_DB_InsertANewUsrID (long UsrCod,
const char ID[ID_MAX_BYTES_USR_ID + 1],
bool Confirmed);
void ID_DB_ConfirmUsrID (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1]);
unsigned ID_DB_GetIDsFromUsrCod (MYSQL_RES **mysql_res,long UsrCod);
bool ID_DB_CheckIfConfirmed (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1]);
unsigned ID_DB_GetUsrCodsFromUsrID (MYSQL_RES **mysql_res,
const struct UsrData *UsrDat,
const char *EncryptedPassword,
bool OnlyConfirmedIDs);
void ID_DB_RemoveUsrID (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1]);
void ID_DB_RemoveUsrIDs (long UsrCod);
#endif

View File

@ -48,6 +48,7 @@
#include "swad_global.h"
#include "swad_HTML.h"
#include "swad_ID.h"
#include "swad_ID_database.h"
#include "swad_language.h"
#include "swad_match.h"
#include "swad_message.h"

View File

@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
*/
#define Log_PLATFORM_VERSION "SWAD 21.8.1 (2021-09-20)"
#define Log_PLATFORM_VERSION "SWAD 21.9 (2021-09-20)"
#define CSS_FILE "swad20.45.css"
#define JS_FILE "swad20.69.1.js"
/*
TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
Version 21.9: Sep 20, 2021 New module swad_ID_database for database queries related to user's IDs. (316021 lines)
Version 21.8.1: Sep 20, 2021 Queries moved to module swad_holiday_database. (315927 lines)
Version 21.8: Sep 20, 2021 New module swad_holiday_database for database queries related to holidays. (315883 lines)
Version 21.7: Sep 20, 2021 New module swad_hierarchy_database for database queries related to hierarchy. (315774 lines)

View File

@ -25,21 +25,9 @@
/********************************* Headers ***********************************/
/*****************************************************************************/
// #include <stddef.h> // For NULL
// #include <stdlib.h> // For calloc
// #include <string.h> // For string functions
// #include "swad_box.h"
// #include "swad_calendar.h"
#include "swad_database.h"
// #include "swad_error.h"
// #include "swad_form.h"
#include "swad_global.h"
// #include "swad_holiday.h"
#include "swad_holiday_database.h"
// #include "swad_HTML.h"
// #include "swad_language.h"
// #include "swad_parameter.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/

View File

@ -118,26 +118,26 @@ void Ico_PutIconsToSelectIconSet (void)
Box_BoxBegin (NULL,Txt_Icons,
Ico_PutIconsIconSet,NULL,
Hlp_PROFILE_Settings_icons,Box_NOT_CLOSABLE);
Set_BeginSettingsHead ();
Set_BeginOneSettingSelector ();
for (IconSet = (Ico_IconSet_t) 0;
IconSet <= (Ico_IconSet_t) (Ico_NUM_ICON_SETS - 1);
IconSet++)
{
HTM_DIV_Begin ("class=\"%s\"",
IconSet == Gbl.Prefs.IconSet ? "PREF_ON" :
"PREF_OFF");
Frm_BeginForm (ActChgIco);
Par_PutHiddenParamString (NULL,"IconSet",Ico_IconSetId[IconSet]);
snprintf (Icon,sizeof (Icon),"%s/%s/cog.svg",
Cfg_ICON_FOLDER_SETS,
Ico_IconSetId[IconSet]);
Ico_PutSettingIconLink (Icon,Ico_IconSetNames[IconSet]);
Frm_EndForm ();
HTM_DIV_End ();
}
Set_EndOneSettingSelector ();
Set_EndSettingsHead ();
Set_BeginSettingsHead ();
Set_BeginOneSettingSelector ();
for (IconSet = (Ico_IconSet_t) 0;
IconSet <= (Ico_IconSet_t) (Ico_NUM_ICON_SETS - 1);
IconSet++)
{
HTM_DIV_Begin ("class=\"%s\"",
IconSet == Gbl.Prefs.IconSet ? "PREF_ON" :
"PREF_OFF");
Frm_BeginForm (ActChgIco);
Par_PutHiddenParamString (NULL,"IconSet",Ico_IconSetId[IconSet]);
snprintf (Icon,sizeof (Icon),"%s/%s/cog.svg",
Cfg_ICON_FOLDER_SETS,
Ico_IconSetId[IconSet]);
Ico_PutSettingIconLink (Icon,Ico_IconSetNames[IconSet]);
Frm_EndForm ();
HTM_DIV_End ();
}
Set_EndOneSettingSelector ();
Set_EndSettingsHead ();
Box_BoxEnd ();
}
@ -165,12 +165,7 @@ void Ico_ChangeIconSet (void)
/***** Store icon set in database *****/
if (Gbl.Usrs.Me.Logged)
DB_QueryUPDATE ("can not update your setting about icon set",
"UPDATE usr_data"
" SET IconSet='%s'"
" WHERE UsrCod=%ld",
Ico_IconSetId[Gbl.Prefs.IconSet],
Gbl.Usrs.Me.UsrDat.UsrCod);
Set_DB_ChangeIconSet (Ico_IconSetId[Gbl.Prefs.IconSet]);
/***** Set settings from current IP *****/
Set_SetSettingsFromIP ();

View File

@ -82,17 +82,17 @@ void Set_EditSettings (void)
NULL,NULL,
Hlp_PROFILE_Settings_internationalization,Box_NOT_CLOSABLE);
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Lan_PutBoxToSelectLanguage (); // 1. Language
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Lan_PutBoxToSelectLanguage (); // 1. Language
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Cal_PutIconsToSelectFirstDayOfWeek (); // 2. First day of week
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Cal_PutIconsToSelectFirstDayOfWeek (); // 2. First day of week
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Dat_PutBoxToSelectDateFormat (); // 3. Date format
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Dat_PutBoxToSelectDateFormat (); // 3. Date format
HTM_DIV_End ();
Box_BoxEnd ();
@ -101,21 +101,21 @@ void Set_EditSettings (void)
NULL,NULL,
Hlp_PROFILE_Settings_design,Box_NOT_CLOSABLE);
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Ico_PutIconsToSelectIconSet (); // 4. Icon set
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Ico_PutIconsToSelectIconSet (); // 4. Icon set
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Mnu_PutIconsToSelectMenu (); // 5. Menu
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Mnu_PutIconsToSelectMenu (); // 5. Menu
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
The_PutIconsToSelectTheme (); // 6. Theme
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
The_PutIconsToSelectTheme (); // 6. Theme
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Set_PutIconsToSelectSideCols (); // 7. Side columns
HTM_DIV_End ();
HTM_DIV_Begin ("class=\"FRAME_INLINE\"");
Set_PutIconsToSelectSideCols (); // 7. Side columns
HTM_DIV_End ();
Box_BoxEnd ();
@ -367,6 +367,20 @@ void Set_DB_ChangeFirstDayOfWeek (unsigned FirstDayOfWeek)
Gbl.Usrs.Me.UsrDat.UsrCod);
}
/*****************************************************************************/
/********************* Update my settings about icon set *********************/
/*****************************************************************************/
void Set_DB_ChangeIconSet (const char *IconSetId)
{
DB_QueryUPDATE ("can not update your setting about icon set",
"UPDATE usr_data"
" SET IconSet='%s'"
" WHERE UsrCod=%ld",
IconSetId,
Gbl.Usrs.Me.UsrDat.UsrCod);
}
/*****************************************************************************/
/***************** Update my settings about first day of week ****************/
/*****************************************************************************/

View File

@ -52,6 +52,7 @@ unsigned Set_GetParamSideCols (void);
void Set_DB_UpdateMySettingsAboutDateFormat (Dat_Format_t DateFormat);
void Set_DB_ChangeFirstDayOfWeek (unsigned FirstDayOfWeek);
void Set_DB_ChangeIconSet (const char *IconSetId);
void Set_DB_ChangeMenu (Mnu_Menu_t Menu);
void Set_BeginSettingsHead (void);