diff --git a/Makefile b/Makefile index 9710524c..d5bf2854 100644 --- a/Makefile +++ b/Makefile @@ -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 \ diff --git a/swad_ID.c b/swad_ID.c index 90f98430..1b054c63 100644 --- a/swad_ID.c +++ b/swad_ID.c @@ -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 ? "✓" : - ""); - 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 ? "✓" : + ""); + 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); - } diff --git a/swad_ID.h b/swad_ID.h index 0c01ce50..d4bb4747 100644 --- a/swad_ID.h +++ b/swad_ID.h @@ -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 diff --git a/swad_ID_database.c b/swad_ID_database.c new file mode 100644 index 00000000..6f0be50e --- /dev/null +++ b/swad_ID_database.c @@ -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 . +*/ +/*****************************************************************************/ +/********************************* 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); + } diff --git a/swad_ID_database.h b/swad_ID_database.h new file mode 100644 index 00000000..1a94b667 --- /dev/null +++ b/swad_ID_database.h @@ -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 . +*/ +/*****************************************************************************/ +/********************************* 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 diff --git a/swad_account.c b/swad_account.c index b71c667c..c09b5454 100644 --- a/swad_account.c +++ b/swad_account.c @@ -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" diff --git a/swad_changelog.h b/swad_changelog.h index 91c82ccd..0300ba05 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -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) diff --git a/swad_holiday_database.c b/swad_holiday_database.c index ec7c14b1..3e36a371 100644 --- a/swad_holiday_database.c +++ b/swad_holiday_database.c @@ -25,21 +25,9 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ -// #include // For NULL -// #include // For calloc -// #include // 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 ****************/ diff --git a/swad_icon.c b/swad_icon.c index b9c14f25..d13be884 100644 --- a/swad_icon.c +++ b/swad_icon.c @@ -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 (); diff --git a/swad_setting.c b/swad_setting.c index b85a7f4e..8c52abf3 100644 --- a/swad_setting.c +++ b/swad_setting.c @@ -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 ****************/ /*****************************************************************************/ diff --git a/swad_setting.h b/swad_setting.h index 8cf8615d..0d46f87c 100644 --- a/swad_setting.h +++ b/swad_setting.h @@ -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);