diff --git a/swad_ID.c b/swad_ID.c index 1a83e994..c84ba2b9 100644 --- a/swad_ID.c +++ b/swad_ID.c @@ -370,22 +370,14 @@ void ID_WriteUsrIDs (struct UsrData *UsrDat) { extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS]; unsigned NumID; - 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 && - !Gbl.Form.Inside && // Only if not inside another form - Act_Actions[Gbl.Action.Act].BrowserWindow == Act_THIS_WINDOW; // Only in main window - } + ICanSeeUsrID = ID_ICanSeeOtherUsrIDs (UsrDat); + ICanConfirmUsrID = ICanSeeUsrID && + (UsrDat->UsrCod != Gbl.Usrs.Me.UsrDat.UsrCod) && // Not me + !Gbl.Form.Inside && // Not inside another form + Act_Actions[Gbl.Action.Act].BrowserWindow == Act_THIS_WINDOW; // Only in main window for (NumID = 0; NumID < UsrDat->IDs.Num; @@ -412,31 +404,71 @@ void ID_WriteUsrIDs (struct UsrData *UsrDat) /*****************************************************************************/ /***************** Check if I can see another user's IDs *********************/ /*****************************************************************************/ -// This function should not be called when UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod -bool ID_ICanSeeAnotherUsrID (struct UsrData *UsrDat) +bool ID_ICanSeeOtherUsrIDs (const struct UsrData *UsrDat) { + if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me + return true; + /***** 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->RoleInCurrentCrsDB == Rol_STUDENT && UsrDat->Accepted); + return (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT && // A student + UsrDat->Accepted) || // who has accepted inscription in course + ( + (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT || // A student + UsrDat->RoleInCurrentCrsDB == Rol_TEACHER) && // or a teacher + !UsrDat->Password[0] && // who has no password (never logged) + !UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1) + !UsrDat->FirstName[0] // and who has no first name (nobody filled user's first name) + ); + return (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT && // A student + UsrDat->Accepted) || // who has accepted inscription in course + ( + (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT || // A student + UsrDat->RoleInCurrentCrsDB == Rol_TEACHER) && // or a teacher + !UsrDat->Password[0] && // who has no password (never logged) + !UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1) + !UsrDat->FirstName[0] // and who has no first name (nobody filled user's first name) + ); 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; + return Usr_CheckIfIAsAdminCanEditOtherUsr (UsrDat); + default: + return false; + } + } + +/*****************************************************************************/ +/***************** Check if I can change another user's IDs ******************/ +/*****************************************************************************/ + +bool ID_ICanChangeOtherUsrIDs (const struct UsrData *UsrDat) + { + if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me + return true; + + /***** 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 change the user's IDs of empty users from current course */ + return (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT || // A student + UsrDat->RoleInCurrentCrsDB == Rol_TEACHER) && // or a teacher + !UsrDat->Password[0] && // who has no password (never logged) + !UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1) + !UsrDat->FirstName[0]; // and who has no first name (nobody filled user's first name) + case Rol_DEG_ADM: + case Rol_CTR_ADM: + case Rol_INS_ADM: + case Rol_SYS_ADM: + return Usr_CheckIfIAsAdminCanEditOtherUsr (UsrDat); default: return false; } @@ -516,7 +548,7 @@ void ID_ShowFormOthIDs (void) /***** Get user whose password must be changed *****/ if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) { - if (Pwd_CheckIfICanChangeOtherUsrPassword (Gbl.Usrs.Other.UsrDat.UsrCod)) + if (ID_ICanChangeOtherUsrIDs (&Gbl.Usrs.Other.UsrDat)) { /***** Start frame *****/ Lay_StartRoundFrame (NULL,Txt_ID,NULL,NULL); @@ -720,7 +752,7 @@ static void ID_RemoveUsrID (const struct UsrData *UsrDat,bool ItsMe) char UsrID[ID_MAX_LENGTH_USR_ID+1]; bool ICanRemove; - if (Pwd_CheckIfICanChangeOtherUsrPassword (UsrDat->UsrCod)) + if (ID_ICanChangeOtherUsrIDs (UsrDat)) { /***** Get user's ID from form *****/ Par_GetParToText ("UsrID",UsrID,ID_MAX_LENGTH_USR_ID); @@ -841,7 +873,7 @@ static void ID_NewUsrID (const struct UsrData *UsrDat,bool ItsMe) unsigned NumIDFound = 0; // Initialized to avoid warning bool Error = false; - if (Pwd_CheckIfICanChangeOtherUsrPassword (UsrDat->UsrCod)) + if (ID_ICanChangeOtherUsrIDs (UsrDat)) { /***** Get new user's ID from form *****/ Par_GetParToText ("NewID",NewID,ID_MAX_LENGTH_USR_ID); @@ -964,7 +996,7 @@ static void ID_ReqConfOrConfOtherUsrID (ID_ReqConfOrConfID_t ReqConfOrConfID) /***** 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)) + if (ID_ICanChangeOtherUsrIDs (&Gbl.Usrs.Other.UsrDat)) ICanConfirm = true; if (ICanConfirm) diff --git a/swad_ID.h b/swad_ID.h index 5b068d70..cb0dfc0e 100644 --- a/swad_ID.h +++ b/swad_ID.h @@ -65,7 +65,8 @@ bool ID_CheckIfUsrIDIsValid (const char *UsrID); bool ID_CheckIfUsrIDSeemsAValidID (const char *UsrID); void ID_WriteUsrIDs (struct UsrData *UsrDat); -bool ID_ICanSeeAnotherUsrID (struct UsrData *UsrDat); +bool ID_ICanSeeOtherUsrIDs (const struct UsrData *UsrDat); +bool ID_ICanChangeOtherUsrIDs (const struct UsrData *UsrDat); void ID_PutLinkToChangeUsrIDs (void); void ID_ShowFormOthIDs (void); diff --git a/swad_action.c b/swad_action.c index 5ec7e4c2..49c110d0 100644 --- a/swad_action.c +++ b/swad_action.c @@ -2471,14 +2471,14 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActCnfID_Tch */{1570,-1,TabUnk,ActLstTch ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_ConfirmOtherUsrID ,NULL}, /* ActFrmIDsOth */{1447,-1,TabUnk,ActLstOth ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_ShowFormOthIDs ,NULL}, - /* ActFrmIDsStd */{1448,-1,TabUnk,ActLstStd ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_ShowFormOthIDs ,NULL}, - /* ActFrmIDsTch */{1449,-1,TabUnk,ActLstTch ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_ShowFormOthIDs ,NULL}, + /* ActFrmIDsStd */{1448,-1,TabUnk,ActLstStd ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_ShowFormOthIDs ,NULL}, + /* ActFrmIDsTch */{1449,-1,TabUnk,ActLstTch ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_ShowFormOthIDs ,NULL}, /* ActRemID_Oth */{1450,-1,TabUnk,ActLstOth ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_RemoveOtherUsrID ,NULL}, - /* ActRemID_Std */{1451,-1,TabUnk,ActLstStd ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_RemoveOtherUsrID ,NULL}, - /* ActRemID_Tch */{1452,-1,TabUnk,ActLstTch ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_RemoveOtherUsrID ,NULL}, + /* ActRemID_Std */{1451,-1,TabUnk,ActLstStd ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_RemoveOtherUsrID ,NULL}, + /* ActRemID_Tch */{1452,-1,TabUnk,ActLstTch ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_RemoveOtherUsrID ,NULL}, /* ActNewID_Oth */{1453,-1,TabUnk,ActLstOth ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_NewOtherUsrID ,NULL}, - /* ActNewID_Std */{1454,-1,TabUnk,ActLstStd ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_NewOtherUsrID ,NULL}, - /* ActNewID_Tch */{1455,-1,TabUnk,ActLstTch ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_NewOtherUsrID ,NULL}, + /* ActNewID_Std */{1454,-1,TabUnk,ActLstStd ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_NewOtherUsrID ,NULL}, + /* ActNewID_Tch */{1455,-1,TabUnk,ActLstTch ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_NewOtherUsrID ,NULL}, /* ActFrmPwdOth */{1464,-1,TabUnk,ActLstOth ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Pwd_ShowFormOthPwd ,NULL}, /* ActFrmPwdStd */{1465,-1,TabUnk,ActLstStd ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Pwd_ShowFormOthPwd ,NULL}, @@ -2488,14 +2488,14 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActChgPwdTch */{1469,-1,TabUnk,ActLstTch ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,Pwd_UpdateOtherPwd1 ,Pwd_UpdateOtherPwd2 ,NULL}, /* ActFrmMaiOth */{1475,-1,TabUnk,ActLstOth ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_ShowFormOthEmail ,NULL}, - /* ActFrmMaiStd */{1476,-1,TabUnk,ActLstStd ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_ShowFormOthEmail ,NULL}, - /* ActFrmMaiTch */{1477,-1,TabUnk,ActLstTch ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_ShowFormOthEmail ,NULL}, + /* ActFrmMaiStd */{1476,-1,TabUnk,ActLstStd ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_ShowFormOthEmail ,NULL}, + /* ActFrmMaiTch */{1477,-1,TabUnk,ActLstTch ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_ShowFormOthEmail ,NULL}, /* ActRemMaiOth */{1478,-1,TabUnk,ActLstOth ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_RemoveOtherUsrEmail ,NULL}, - /* ActRemMaiStd */{1479,-1,TabUnk,ActLstStd ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_RemoveOtherUsrEmail ,NULL}, - /* ActRemMaiTch */{1480,-1,TabUnk,ActLstTch ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_RemoveOtherUsrEmail ,NULL}, + /* ActRemMaiStd */{1479,-1,TabUnk,ActLstStd ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_RemoveOtherUsrEmail ,NULL}, + /* ActRemMaiTch */{1480,-1,TabUnk,ActLstTch ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_RemoveOtherUsrEmail ,NULL}, /* ActNewMaiOth */{1481,-1,TabUnk,ActLstOth ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_NewOtherUsrEmail ,NULL}, - /* ActNewMaiStd */{1482,-1,TabUnk,ActLstStd ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_NewOtherUsrEmail ,NULL}, - /* ActNewMaiTch */{1483,-1,TabUnk,ActLstTch ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_NewOtherUsrEmail ,NULL}, + /* ActNewMaiStd */{1482,-1,TabUnk,ActLstStd ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_NewOtherUsrEmail ,NULL}, + /* ActNewMaiTch */{1483,-1,TabUnk,ActLstTch ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Mai_NewOtherUsrEmail ,NULL}, /* ActRemStdCrs */{1462,-1,TabUnk,ActLstStd ,0x1F8,0x1E0,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Enr_RemUsrFromCrs ,NULL}, /* ActRemTchCrs */{1463,-1,TabUnk,ActLstTch ,0x1F0,0x1E0,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Enr_RemUsrFromCrs ,NULL}, diff --git a/swad_changelog.h b/swad_changelog.h index 1e6fe492..1ab23947 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -187,19 +187,19 @@ // TODO: Fix bug when creating a new attendance event: if title is repeated, form is cleared // TODO: Fix bug: When registering an administrator, the user's name changes are ignored -// TODO: Teachers sbould view ID of students/teachers with no name/email - /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.123.4 (2017-01-25)" +#define Log_PLATFORM_VERSION "SWAD 16.125 (2017-01-27)" #define CSS_FILE "swad16.123.css" #define JS_FILE "swad16.123.js" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1 /* + Version 16.125: Jan 27, 2017 Code refactoring related to permissions to view/change another user's data. (212152 lines) + Version 16.124: Jan 26, 2017 Code refactoring related to permissions to view/change another user's data. (212163 lines) Version 16.123.4: Jan 26, 2017 Surname1 and first name can not be deleted when editing user's data. (212000 lines) Version 16.123.3: Jan 25, 2017 Code refactoring in edition of user's record. (211987 lines) Version 16.123.2: Jan 25, 2017 Teachers can edit names of students/teachers with no name/email. (211989 lines) diff --git a/swad_enrollment.c b/swad_enrollment.c index acea0729..ed98333d 100644 --- a/swad_enrollment.c +++ b/swad_enrollment.c @@ -3153,14 +3153,19 @@ static void Enr_ShowFormToEditOtherUsr (void) { /***** Buttons for edition *****/ fprintf (Gbl.F.Out,"
"); - if (Pwd_CheckIfICanChangeOtherUsrPassword (Gbl.Usrs.Other.UsrDat.UsrCod)) - { + + if (Pwd_ICanChangeOtherUsrPassword (&Gbl.Usrs.Other.UsrDat)) Pwd_PutLinkToChangeOtherUsrPassword (); // Put link (form) to change user's password - Mai_PutLinkToChangeOtherUsrEmail (); // Put link (form) to change user's email + + if (Mai_ICanChangeOtherUsrEmails (&Gbl.Usrs.Other.UsrDat)) + Mai_PutLinkToChangeOtherUsrEmails (); // Put link (form) to change user's emails + + if (ID_ICanChangeOtherUsrIDs (&Gbl.Usrs.Other.UsrDat)) ID_PutLinkToChangeUsrIDs (); // Put link (form) to change user's IDs - } - if (Pho_CheckIfICanChangeOtherUsrPhoto (&Gbl.Usrs.Other.UsrDat)) + + if (Pho_ICanChangeOtherUsrPhoto (&Gbl.Usrs.Other.UsrDat)) Pho_PutLinkToChangeOtherUsrPhoto (); // Put link (form) to change user's photo + fprintf (Gbl.F.Out,"
"); /***** User's record *****/ diff --git a/swad_mail.c b/swad_mail.c index 974696f1..2a9fc7a9 100644 --- a/swad_mail.c +++ b/swad_mail.c @@ -1114,10 +1114,10 @@ long Mai_GetUsrCodFromEmail (const char *Email) } /*****************************************************************************/ -/********** Put a link to the action used to change user's email *************/ +/********** Put a link to the action used to change user's emails ************/ /*****************************************************************************/ -void Mai_PutLinkToChangeOtherUsrEmail (void) +void Mai_PutLinkToChangeOtherUsrEmails (void) { extern const char *Txt_Change_email; @@ -1137,6 +1137,37 @@ void Mai_PutLinkToChangeOtherUsrEmail (void) NULL); } +/*****************************************************************************/ +/************** Check if I can change the email of another user **************/ +/*****************************************************************************/ + +bool Mai_ICanChangeOtherUsrEmails (const struct UsrData *UsrDat) + { + if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me + return true; + + /***** Check if I have permission to change another user's emails *****/ + switch (Gbl.Usrs.Me.LoggedRole) + { + case Rol_TEACHER: + /* If I am a teacher of current course, + I only can change the user's emails + of empty users from current course */ + return (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT || // A student + UsrDat->RoleInCurrentCrsDB == Rol_TEACHER) && // or a teacher + !UsrDat->Password[0] && // who has no password (never logged) + !UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1) + !UsrDat->FirstName[0]; // and who has no first name (nobody filled user's first name) + case Rol_DEG_ADM: + case Rol_CTR_ADM: + case Rol_INS_ADM: + case Rol_SYS_ADM: + return Usr_CheckIfIAsAdminCanEditOtherUsr (UsrDat); + default: + return false; + } + } + /*****************************************************************************/ /*********** Show form to the change the email of another user ***************/ /*****************************************************************************/ @@ -1149,7 +1180,7 @@ void Mai_ShowFormOthEmail (void) /***** Get user whose password must be changed *****/ if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) { - if (Pwd_CheckIfICanChangeOtherUsrPassword (Gbl.Usrs.Other.UsrDat.UsrCod)) + if (Mai_ICanChangeOtherUsrEmails (&Gbl.Usrs.Other.UsrDat)) { /***** Start frame *****/ Lay_StartRoundFrame (NULL,Txt_Email,NULL,NULL); @@ -1368,7 +1399,7 @@ static void Mai_RemoveEmail (struct UsrData *UsrDat) extern const char *Txt_User_not_found_or_you_do_not_have_permission_; char Email[Usr_MAX_BYTES_USR_EMAIL+1]; - if (Pwd_CheckIfICanChangeOtherUsrPassword (UsrDat->UsrCod)) + if (Mai_ICanChangeOtherUsrEmails (UsrDat)) { /***** Get new email from form *****/ Par_GetParToText ("Email",Email,Usr_MAX_BYTES_USR_EMAIL); @@ -1450,7 +1481,7 @@ static void Mai_NewUsrEmail (struct UsrData *UsrDat,bool ItsMe) extern const char *Txt_User_not_found_or_you_do_not_have_permission_; char NewEmail[Usr_MAX_BYTES_USR_EMAIL+1]; - if (Pwd_CheckIfICanChangeOtherUsrPassword (UsrDat->UsrCod)) + if (Mai_ICanChangeOtherUsrEmails (UsrDat)) { /***** Get new email from form *****/ Par_GetParToText ("NewEmail",NewEmail,Usr_MAX_BYTES_USR_EMAIL); @@ -1807,7 +1838,7 @@ void Mai_WriteFootNoteEMail (Txt_Language_t Language) /**************** Check if I can see another user's email ********************/ /*****************************************************************************/ -bool Mai_ICanSeeEmail (struct UsrData *UsrDat) +bool Mai_ICanSeeEmail (const struct UsrData *UsrDat) { bool ItsMe = (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod); @@ -1825,21 +1856,27 @@ bool Mai_ICanSeeEmail (struct UsrData *UsrDat) case Rol_TEACHER: /* If I am a teacher of current course, I only can see the user's email of students or teachers from current course */ - return (UsrDat->Accepted && - (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT || - UsrDat->RoleInCurrentCrsDB == Rol_TEACHER)); + return ((UsrDat->RoleInCurrentCrsDB == Rol_STUDENT || + UsrDat->RoleInCurrentCrsDB == Rol_TEACHER) && // A student or a teacher + (UsrDat->Accepted || // who has accepted inscription in course + !UsrDat->Email[0] || // or whose email is empty + !UsrDat->Surname1[0] || // or whose surname 1 is empty + !UsrDat->FirstName[0])); // or whose first name is empty case Rol_DEG_ADM: /* If I am an administrator of current degree, I only can see the user's email of users from current degree */ - return Usr_CheckIfUsrBelongsToDeg (UsrDat->UsrCod,Gbl.CurrentDeg.Deg.DegCod,true); + return Usr_CheckIfUsrBelongsToDeg (UsrDat->UsrCod, + Gbl.CurrentDeg.Deg.DegCod); case Rol_CTR_ADM: /* If I am an administrator of current centre, I only can see the user's email of users from current centre */ - return Usr_CheckIfUsrBelongsToCtr (UsrDat->UsrCod,Gbl.CurrentCtr.Ctr.CtrCod,true); + return Usr_CheckIfUsrBelongsToCtr (UsrDat->UsrCod, + Gbl.CurrentCtr.Ctr.CtrCod); case Rol_INS_ADM: /* If I am an administrator of current institution, I only can see the user's email of users from current institution */ - return Usr_CheckIfUsrBelongsToIns (UsrDat->UsrCod,Gbl.CurrentIns.Ins.InsCod,true); + return Usr_CheckIfUsrBelongsToIns (UsrDat->UsrCod, + Gbl.CurrentIns.Ins.InsCod); case Rol_SYS_ADM: return true; default: diff --git a/swad_mail.h b/swad_mail.h index 5abf4918..b7fc8e56 100644 --- a/swad_mail.h +++ b/swad_mail.h @@ -77,7 +77,8 @@ bool Mai_CheckIfEmailIsValid (const char *Email); bool Mai_GetEmailFromUsrCod (struct UsrData *UsrDat); long Mai_GetUsrCodFromEmail (const char *Email); -void Mai_PutLinkToChangeOtherUsrEmail (void); +void Mai_PutLinkToChangeOtherUsrEmails (void); +bool Mai_ICanChangeOtherUsrEmails (const struct UsrData *UsrDat); void Mai_ShowFormOthEmail (void); void Mai_ShowFormChangeUsrEmail (const struct UsrData *UsrDat,bool ItsMe); void Mai_RemoveMyUsrEmail (void); @@ -95,6 +96,6 @@ void Mai_CreateFileNameMail (void); void Mai_WriteWelcomeNoteEMail (struct UsrData *UsrDat); void Mai_WriteFootNoteEMail (Txt_Language_t Language); -bool Mai_ICanSeeEmail (struct UsrData *UsrDat); +bool Mai_ICanSeeEmail (const struct UsrData *UsrDat); #endif diff --git a/swad_password.c b/swad_password.c index f8e41307..6a23e13b 100644 --- a/swad_password.c +++ b/swad_password.c @@ -491,7 +491,7 @@ void Pwd_UpdateOtherPwd1 (void) /***** Get other user's code from form and get user's data *****/ if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) { - if (Pwd_CheckIfICanChangeOtherUsrPassword (Gbl.Usrs.Other.UsrDat.UsrCod)) + if (Pwd_ICanChangeOtherUsrPassword (&Gbl.Usrs.Other.UsrDat)) { Par_GetParToText ("Paswd1",NewPlainPassword[0],Pwd_MAX_LENGTH_PLAIN_PASSWORD); Par_GetParToText ("Paswd2",NewPlainPassword[1],Pwd_MAX_LENGTH_PLAIN_PASSWORD); @@ -813,7 +813,7 @@ void Pwd_ShowFormOthPwd (void) /***** Get user whose password must be changed *****/ if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) { - if (Pwd_CheckIfICanChangeOtherUsrPassword (Gbl.Usrs.Other.UsrDat.UsrCod)) + if (Pwd_ICanChangeOtherUsrPassword (&Gbl.Usrs.Other.UsrDat)) { /***** Start frame *****/ Lay_StartRoundFrame (NULL,Txt_Password,NULL,NULL); @@ -884,35 +884,16 @@ void Pwd_PutLinkToChangeOtherUsrPassword (void) } /*****************************************************************************/ -/************ Check if I can change th password of another user **************/ +/************ Check if I can change the password of another user *************/ /*****************************************************************************/ -bool Pwd_CheckIfICanChangeOtherUsrPassword (long UsrCod) +bool Pwd_ICanChangeOtherUsrPassword (const struct UsrData *UsrDat) { - if (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me + if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me return true; - /* Check if I have permission to change another user's password. - Only users who have accepted registration in courses are counted */ - switch (Gbl.Usrs.Me.LoggedRole) - { - case Rol_DEG_ADM: - /* If I am an administrator of current degree, - I only can change the password of users from current degree */ - return Usr_CheckIfUsrBelongsToDeg (UsrCod,Gbl.CurrentDeg.Deg.DegCod,true); - case Rol_CTR_ADM: - /* If I am an administrator of current centre, - I only can change the password of users from current centre */ - return Usr_CheckIfUsrBelongsToCtr (UsrCod,Gbl.CurrentCtr.Ctr.CtrCod,true); - case Rol_INS_ADM: - /* If I am an administrator of current institution, - I only can change the password of users from current institution */ - return Usr_CheckIfUsrBelongsToIns (UsrCod,Gbl.CurrentIns.Ins.InsCod,true); - case Rol_SYS_ADM: - return true; - default: - return false; - } + /***** Check if I have permission to change another user's password *****/ + return Usr_CheckIfIAsAdminCanEditOtherUsr (UsrDat); } /*****************************************************************************/ diff --git a/swad_password.h b/swad_password.h index fa045188..965d9ec1 100644 --- a/swad_password.h +++ b/swad_password.h @@ -69,7 +69,7 @@ void Pwd_ShowFormOthPwd (void); void Pwd_PutLinkToChangeMyPassword (void); void Pwd_PutLinkToChangeOtherUsrPassword (void); -bool Pwd_CheckIfICanChangeOtherUsrPassword (long UsrCod); +bool Pwd_ICanChangeOtherUsrPassword (const struct UsrData *UsrDat); void Pwd_AskForConfirmationOnDangerousAction (void); bool Pwd_GetConfirmationOnDangerousAction (void); diff --git a/swad_photo.c b/swad_photo.c index a83a1c6d..e5062d79 100644 --- a/swad_photo.c +++ b/swad_photo.c @@ -131,40 +131,31 @@ static void Pho_ComputePhotoSize (int NumStds,int NumStdsWithPhoto,unsigned *Pho /************** Check if I can change the photo of another user **************/ /*****************************************************************************/ -bool Pho_CheckIfICanChangeOtherUsrPhoto (const struct UsrData *UsrDat) +bool Pho_ICanChangeOtherUsrPhoto (const struct UsrData *UsrDat) { if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me return true; - /* Check if I have permission to change user's photo - Only users who have accepted registration in courses are counted */ + /* Check if I have permission to change user's photo */ switch (Gbl.Usrs.Me.LoggedRole) { case Rol_TEACHER: /* If I am a teacher in current course, I only can change the photo of students from current course */ - return (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT && - UsrDat->Accepted); + return (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT && // A student + UsrDat->Accepted) || // who has accepted inscription in course + ( + (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT || // A student + UsrDat->RoleInCurrentCrsDB == Rol_TEACHER) && // or a teacher + !UsrDat->Password[0] && // who has no password (never logged) + !UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1) + !UsrDat->FirstName[0] // and who has no first name (nobody filled user's first name) + ); case Rol_DEG_ADM: - /* If I am an administrator of current degree, - I only can change the photo 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 change the photo 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 change the photo of users from current institution */ - return Usr_CheckIfUsrBelongsToIns (UsrDat->UsrCod, - Gbl.CurrentIns.Ins.InsCod, - true); case Rol_SYS_ADM: - return true; + return Usr_CheckIfIAsAdminCanEditOtherUsr (UsrDat); default: return false; } @@ -203,7 +194,7 @@ void Pho_PutLinkToChangeOtherUsrPhoto (void) if (Gbl.Usrs.Other.UsrDat.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me Pho_PutLinkToChangeMyPhoto (); else // Not me - if (Pho_CheckIfICanChangeOtherUsrPhoto (&Gbl.Usrs.Other.UsrDat)) + if (Pho_ICanChangeOtherUsrPhoto (&Gbl.Usrs.Other.UsrDat)) { PhotoExists = Pho_BuildLinkToPhoto (&Gbl.Usrs.Other.UsrDat,PhotoURL); TitleText = PhotoExists ? Txt_Change_photo : @@ -360,7 +351,7 @@ void Pho_SendPhotoUsr (void) /***** Get user whose photo must be sent or removed *****/ if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) { - if (Pho_CheckIfICanChangeOtherUsrPhoto (&Gbl.Usrs.Other.UsrDat)) // If I have permission to change user's photo... + if (Pho_ICanChangeOtherUsrPhoto (&Gbl.Usrs.Other.UsrDat)) // If I have permission to change user's photo... { Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrBelongsToCrs (Gbl.Usrs.Other.UsrDat.UsrCod, Gbl.CurrentCrs.Crs.CrsCod, @@ -488,7 +479,7 @@ void Pho_ReqRemoveUsrPhoto (void) /***** Get password, user type and user's data from database *****/ if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat)) { - if (Pho_CheckIfICanChangeOtherUsrPhoto (&Gbl.Usrs.Other.UsrDat)) + if (Pho_ICanChangeOtherUsrPhoto (&Gbl.Usrs.Other.UsrDat)) { /***** Show current photo and help message *****/ if (Pho_BuildLinkToPhoto (&Gbl.Usrs.Other.UsrDat,PhotoURL)) diff --git a/swad_photo.h b/swad_photo.h index 91c0f763..c4d6acf3 100644 --- a/swad_photo.h +++ b/swad_photo.h @@ -80,7 +80,7 @@ typedef enum /***************************** Public prototypes *****************************/ /*****************************************************************************/ -bool Pho_CheckIfICanChangeOtherUsrPhoto (const struct UsrData *UsrDat); +bool Pho_ICanChangeOtherUsrPhoto (const struct UsrData *UsrDat); void Pho_PutLinkToChangeMyPhoto (void); void Pho_PutLinkToChangeOtherUsrPhoto (void); void Pho_ReqMyPhotoWithContextLinks (void); diff --git a/swad_user.c b/swad_user.c index 341e8888..fd9a04da 100644 --- a/swad_user.c +++ b/swad_user.c @@ -792,12 +792,72 @@ bool Usr_CheckIfUsrIsSuperuser (long UsrCod) { extern const char *Sco_ScopeDB[Sco_NUM_SCOPES]; char Query[128]; + static struct + { + long UsrCod; + bool IsSuperuser; + } Cache = + { + -1L, + false + }; - /***** Get if a user is superuser from database *****/ - sprintf (Query,"SELECT COUNT(*) FROM admin" - " WHERE UsrCod='%ld' AND Scope='%s'", - UsrCod,Sco_ScopeDB[Sco_SCOPE_SYS]); - return (DB_QueryCOUNT (Query,"can not check if a user is superuser") != 0); + if (UsrCod <= 0) + { + /***** Trivial case *****/ + Cache.UsrCod = -1L; + Cache.IsSuperuser = false; + } + else if (UsrCod != Cache.UsrCod) // If not cached... + { + /***** Get if a user is superuser from database *****/ + sprintf (Query,"SELECT COUNT(*) FROM admin" + " WHERE UsrCod='%ld' AND Scope='%s'", + UsrCod,Sco_ScopeDB[Sco_SCOPE_SYS]); + Cache.UsrCod = UsrCod; + Cache.IsSuperuser = (DB_QueryCOUNT (Query,"can not check if a user is superuser") != 0); + } + + return Cache.IsSuperuser; + } + +/*****************************************************************************/ +/************ Check if I (as admin) can edit another user's data *************/ +/*****************************************************************************/ + +bool Usr_CheckIfIAsAdminCanEditOtherUsr (const struct UsrData *UsrDat) + { + switch (Gbl.Usrs.Me.LoggedRole) + { + case Rol_DEG_ADM: + /* If I am an administrator of current degree, + I only can edit users from current degree who have accepted */ + if (Usr_CheckIfUsrBelongsToDeg (UsrDat->UsrCod,Gbl.CurrentDeg.Deg.DegCod)) + // Degree admins can't edit superusers' data + if (!Usr_CheckIfUsrIsSuperuser (UsrDat->UsrCod)) + return true; + return false; + case Rol_CTR_ADM: + /* If I am an administrator of current centre, + I only can edit from current centre who have accepted */ + if (Usr_CheckIfUsrBelongsToCtr (UsrDat->UsrCod,Gbl.CurrentCtr.Ctr.CtrCod)) + // Centre admins can't edit superusers' data + if (!Usr_CheckIfUsrIsSuperuser (UsrDat->UsrCod)) + return true; + return false; + case Rol_INS_ADM: + /* If I am an administrator of current institution, + I only can edit from current institution who have accepted */ + if (Usr_CheckIfUsrBelongsToIns (UsrDat->UsrCod,Gbl.CurrentIns.Ins.InsCod)) + // Institution admins can't edit superusers' data + if (!Usr_CheckIfUsrIsSuperuser (UsrDat->UsrCod)) + return true; + return false; + case Rol_SYS_ADM: + return true; + default: + return false; + } } /*****************************************************************************/ @@ -1432,95 +1492,148 @@ static void Usr_RemoveTemporaryTableMyCourses (void) /**************** Check if a user belongs to an institution ******************/ /*****************************************************************************/ -bool Usr_CheckIfUsrBelongsToIns (long UsrCod, - long InsCod, - bool CountOnlyAcceptedCourses) +bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod) { char Query[512]; - const char *SubQuery; + static struct + { + long UsrCod; + long InsCod; + bool Belongs; + } Cache = + { + -1L, + -1L, + false + }; - /***** Trivial case *****/ if (UsrCod <= 0 || InsCod <= 0) - return false; + { + /***** Trivial case *****/ + Cache.UsrCod = -1L; + Cache.InsCod = -1L; + Cache.Belongs = false; + } + else if (UsrCod != Cache.UsrCod || + InsCod != Cache.InsCod) // If not cached... + { + /***** Get is a user belongs to an institution from database *****/ + sprintf (Query,"SELECT COUNT(DISTINCT centres.InsCod)" + " FROM crs_usr,courses,degrees,centres" + " WHERE crs_usr.UsrCod='%ld'" + " AND crs_usr.Accepted='Y'" + " AND crs_usr.CrsCod=courses.CrsCod" + " AND courses.DegCod=degrees.DegCod" + " AND degrees.CtrCod=centres.CtrCod" + " AND centres.InsCod='%ld'", + UsrCod,InsCod); + Cache.UsrCod = UsrCod; + Cache.InsCod = InsCod; + Cache.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to an institution") != 0); + } - /***** Get is a user belongs to an institution from database *****/ - SubQuery = (CountOnlyAcceptedCourses ? " AND crs_usr.Accepted='Y'" : - ""); - sprintf (Query,"SELECT COUNT(DISTINCT centres.InsCod)" - " FROM crs_usr,courses,degrees,centres" - " WHERE crs_usr.UsrCod='%ld'%s" - " AND crs_usr.CrsCod=courses.CrsCod" - " AND courses.DegCod=degrees.DegCod" - " AND degrees.CtrCod=centres.CtrCod" - " AND centres.InsCod='%ld'", - UsrCod,SubQuery,InsCod); - return (DB_QueryCOUNT (Query,"can not check if a user belongs to an institution") != 0); + return Cache.Belongs; } /*****************************************************************************/ /******************* Check if a user belongs to a centre *********************/ /*****************************************************************************/ -bool Usr_CheckIfUsrBelongsToCtr (long UsrCod, - long CtrCod, - bool CountOnlyAcceptedCourses) +bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod) { char Query[512]; - const char *SubQuery; + static struct + { + long UsrCod; + long CtrCod; + bool Belongs; + } Cache = + { + -1L, + -1L, + false + }; - /***** Trivial case *****/ if (UsrCod <= 0 || CtrCod <= 0) - return false; + { + /***** Trivial case *****/ + Cache.UsrCod = -1L; + Cache.CtrCod = -1L; + Cache.Belongs = false; + } + else if (UsrCod != Cache.UsrCod || + CtrCod != Cache.CtrCod) // If not cached... + { + /***** Get is a user belongs to a centre from database *****/ + sprintf (Query,"SELECT COUNT(DISTINCT degrees.CtrCod)" + " FROM crs_usr,courses,degrees" + " WHERE crs_usr.UsrCod='%ld'" + " AND crs_usr.Accepted='Y'" // Only if user accepted + " AND crs_usr.CrsCod=courses.CrsCod" + " AND courses.DegCod=degrees.DegCod" + " AND degrees.CtrCod='%ld'", + UsrCod,CtrCod); + Cache.UsrCod = UsrCod; + Cache.CtrCod = CtrCod; + Cache.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a centre") != 0); + } - /***** Get is a user belongs to a centre from database *****/ - SubQuery = (CountOnlyAcceptedCourses ? " AND crs_usr.Accepted='Y'" : - ""); - sprintf (Query,"SELECT COUNT(DISTINCT degrees.CtrCod)" - " FROM crs_usr,courses,degrees" - " WHERE crs_usr.UsrCod='%ld'%s" - " AND crs_usr.CrsCod=courses.CrsCod" - " AND courses.DegCod=degrees.DegCod" - " AND degrees.CtrCod='%ld'", - UsrCod,SubQuery,CtrCod); - return (DB_QueryCOUNT (Query,"can not check if a user belongs to a centre") != 0); + return Cache.Belongs; } /*****************************************************************************/ /******************* Check if a user belongs to a degree *********************/ /*****************************************************************************/ -bool Usr_CheckIfUsrBelongsToDeg (long UsrCod, - long DegCod, - bool CountOnlyAcceptedCourses) +bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod) { char Query[512]; - const char *SubQuery; + static struct + { + long UsrCod; + long DegCod; + bool Belongs; + } Cache = + { + -1L, + -1L, + false + }; - /***** Trivial case *****/ if (UsrCod <= 0 || DegCod <= 0) - return false; + { + /***** Trivial case *****/ + Cache.UsrCod = -1L; + Cache.DegCod = -1L; + Cache.Belongs = false; + } + else if (UsrCod != Cache.UsrCod || + DegCod != Cache.DegCod) // If not cached... + { + /***** Get is a user belongs to a degree from database *****/ + sprintf (Query,"SELECT COUNT(DISTINCT courses.DegCod)" + " FROM crs_usr,courses" + " WHERE crs_usr.UsrCod='%ld'" + " AND crs_usr.Accepted='Y'" // Only if user accepted + " AND crs_usr.CrsCod=courses.CrsCod" + " AND courses.DegCod='%ld'", + UsrCod,DegCod); + Cache.UsrCod = UsrCod; + Cache.DegCod = DegCod; + Cache.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a degree") != 0); + } - /***** Get is a user belongs to a degree from database *****/ - SubQuery = (CountOnlyAcceptedCourses ? " AND crs_usr.Accepted='Y'" : - ""); - sprintf (Query,"SELECT COUNT(DISTINCT courses.DegCod)" - " FROM crs_usr,courses" - " WHERE crs_usr.UsrCod='%ld'%s" - " AND crs_usr.CrsCod=courses.CrsCod" - " AND courses.DegCod='%ld'", - UsrCod,SubQuery,DegCod); - return (DB_QueryCOUNT (Query,"can not check if a user belongs to a degree") != 0); + return Cache.Belongs; } /*****************************************************************************/ /******************** Check if a user belongs to a course ********************/ /*****************************************************************************/ -bool Usr_CheckIfUsrBelongsToCrs (long UsrCod, - long CrsCod, +bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, bool CountOnlyAcceptedCourses) { char Query[512]; @@ -3797,6 +3910,7 @@ static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role, const char *QueryFields = "usr_data.UsrCod," "usr_data.EncryptedUsrCod," + "usr_data.Password," "usr_data.Surname1," "usr_data.Surname2," "usr_data.FirstName," @@ -3809,15 +3923,16 @@ static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role, /* row[ 0]: usr_data.UsrCod row[ 1]: usr_data.EncryptedUsrCod - row[ 2]: usr_data.Surname1 - row[ 3]: usr_data.Surname2 - row[ 4]: usr_data.FirstName - row[ 5]: usr_data.Sex - row[ 6]: usr_data.Photo - row[ 7]: usr_data.PhotoVisibility - row[ 8]: usr_data.InsCod - row[ 9]: crs_usr.Role (only if Scope == Sco_SCOPE_CRS) - row[10]: crs_usr.Accepted (only if Scope == Sco_SCOPE_CRS) + row[ 2]: usr_data.Password (used to check if a teacher can edit user's data) + row[ 3]: usr_data.Surname1 + row[ 4]: usr_data.Surname2 + row[ 5]: usr_data.FirstName + row[ 6]: usr_data.Sex + row[ 7]: usr_data.Photo + row[ 8]: usr_data.PhotoVisibility + row[ 9]: usr_data.InsCod + row[10]: crs_usr.Role (only if Scope == Sco_SCOPE_CRS) + row[11]: crs_usr.Accepted (only if Scope == Sco_SCOPE_CRS) */ /***** If there are no groups selected, don't do anything *****/ @@ -3969,6 +4084,7 @@ void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope) const char *QueryFields = "DISTINCT usr_data.UsrCod," "usr_data.EncryptedUsrCod," + "usr_data.Password," "usr_data.Surname1," "usr_data.Surname2," "usr_data.FirstName," @@ -3979,15 +4095,16 @@ void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope) /* row[ 0]: usr_data.UsrCod row[ 1]: usr_data.EncryptedUsrCod - row[ 2]: usr_data.Surname1 - row[ 3]: usr_data.Surname2 - row[ 4]: usr_data.FirstName - row[ 5]: usr_data.Sex - row[ 6]: usr_data.Photo - row[ 7]: usr_data.PhotoVisibility - row[ 8]: usr_data.InsCod - row[ 9]: crs_usr.Role (only if Scope == Sco_SCOPE_CRS) - row[10]: crs_usr.Accepted (only if Scope == Sco_SCOPE_CRS) + row[ 2]: usr_data.Password (used to check if a teacher can edit user's data) + row[ 3]: usr_data.Surname1 + row[ 4]: usr_data.Surname2 + row[ 5]: usr_data.FirstName + row[ 6]: usr_data.Sex + row[ 7]: usr_data.Photo + row[ 8]: usr_data.PhotoVisibility + row[ 9]: usr_data.InsCod + row[10]: crs_usr.Role (only if Scope == Sco_SCOPE_CRS) + row[11]: crs_usr.Accepted (only if Scope == Sco_SCOPE_CRS) */ /***** Build query *****/ @@ -3995,7 +4112,8 @@ void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope) { case Sco_SCOPE_SYS: /* Get users in courses from the whole platform */ - sprintf (Query,"SELECT %s FROM usr_data,crs_usr" + sprintf (Query,"SELECT %s" + " FROM usr_data,crs_usr" " WHERE usr_data.UsrCod=crs_usr.UsrCod" " AND crs_usr.Role='%u'" " ORDER BY " @@ -4008,7 +4126,8 @@ void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope) break; case Sco_SCOPE_CTY: /* Get users in courses from the current country */ - sprintf (Query,"SELECT %s FROM usr_data,crs_usr,courses,degrees,centres,institutions" + sprintf (Query,"SELECT %s" + " FROM usr_data,crs_usr,courses,degrees,centres,institutions" " WHERE usr_data.UsrCod=crs_usr.UsrCod" " AND crs_usr.Role='%u'" " AND crs_usr.CrsCod=courses.CrsCod" @@ -4027,7 +4146,8 @@ void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope) break; case Sco_SCOPE_INS: /* Get users in courses from the current institution */ - sprintf (Query,"SELECT %s FROM usr_data,crs_usr,courses,degrees,centres" + sprintf (Query,"SELECT %s" + " FROM usr_data,crs_usr,courses,degrees,centres" " WHERE usr_data.UsrCod=crs_usr.UsrCod" " AND crs_usr.Role='%u'" " AND crs_usr.CrsCod=courses.CrsCod" @@ -4045,7 +4165,8 @@ void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope) break; case Sco_SCOPE_CTR: /* Get users in courses from the current centre */ - sprintf (Query,"SELECT %s FROM usr_data,crs_usr,courses,degrees" + sprintf (Query,"SELECT %s" + " FROM usr_data,crs_usr,courses,degrees" " WHERE usr_data.UsrCod=crs_usr.UsrCod" " AND crs_usr.Role='%u'" " AND crs_usr.CrsCod=courses.CrsCod" @@ -4062,7 +4183,8 @@ void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope) break; case Sco_SCOPE_DEG: /* Get users in courses from the current degree */ - sprintf (Query,"SELECT %s FROM usr_data,crs_usr,courses" + sprintf (Query,"SELECT %s" + " FROM usr_data,crs_usr,courses" " WHERE usr_data.UsrCod=crs_usr.UsrCod" " AND crs_usr.Role='%u'" " AND crs_usr.CrsCod=courses.CrsCod" @@ -4690,15 +4812,16 @@ static void Usr_GetListUsrsFromQuery (const char *Query,Rol_Role_t Role,Sco_Scop /* row[ 0]: usr_data.UsrCod row[ 1]: usr_data.EncryptedUsrCod - row[ 2]: usr_data.Surname1 - row[ 3]: usr_data.Surname2 - row[ 4]: usr_data.FirstName - row[ 5]: usr_data.Sex - row[ 6]: usr_data.Photo - row[ 7]: usr_data.PhotoVisibility - row[ 8]: usr_data.InsCod - row[ 9]: crs_usr.Role (only if Scope == Sco_SCOPE_CRS) - row[10]: crs_usr.Accepted (only if Scope == Sco_SCOPE_CRS) + row[ 2]: usr_data.Password (used to check if a teacher can edit user's data) + row[ 3]: usr_data.Surname1 + row[ 4]: usr_data.Surname2 + row[ 5]: usr_data.FirstName + row[ 6]: usr_data.Sex + row[ 7]: usr_data.Photo + row[ 8]: usr_data.PhotoVisibility + row[ 9]: usr_data.InsCod + row[10]: crs_usr.Role (only if Scope == Sco_SCOPE_CRS) + row[11]: crs_usr.Accepted (only if Scope == Sco_SCOPE_CRS) */ UsrInList = &Gbl.Usrs.LstUsrs[Role].Lst[NumUsr]; @@ -4709,33 +4832,37 @@ static void Usr_GetListUsrsFromQuery (const char *Query,Rol_Role_t Role,Sco_Scop Str_Copy (UsrInList->EncryptedUsrCod,row[1], Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64); - /* Get user's surname 1 (row[2]) */ - Str_Copy (UsrInList->Surname1,row[2], + /* Get encrypted password (row[2]) */ + Str_Copy (UsrInList->Password,row[2], + Cry_LENGTH_ENCRYPTED_STR_SHA512_BASE64); + + /* Get user's surname 1 (row[3]) */ + Str_Copy (UsrInList->Surname1,row[3], Usr_MAX_BYTES_NAME); - /* Get user's surname 2 (row[3]) */ - Str_Copy (UsrInList->Surname2,row[3], + /* Get user's surname 2 (row[4]) */ + Str_Copy (UsrInList->Surname2,row[4], Usr_MAX_BYTES_NAME); - /* Get user's first name (row[4]) */ - Str_Copy (UsrInList->FirstName,row[4], + /* Get user's first name (row[5]) */ + Str_Copy (UsrInList->FirstName,row[5], Usr_MAX_BYTES_NAME); - /* Get user's sex (row[5]) */ - UsrInList->Sex = Usr_GetSexFromStr (row[5]); + /* Get user's sex (row[6]) */ + UsrInList->Sex = Usr_GetSexFromStr (row[6]); - /* Get user's photo (row[6]) */ - Str_Copy (UsrInList->Photo,row[6], + /* Get user's photo (row[7]) */ + Str_Copy (UsrInList->Photo,row[7], Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64); - /* Get user's photo visibility (row[7]) */ - UsrInList->PhotoVisibility = Pri_GetVisibilityFromStr (row[7]); + /* Get user's photo visibility (row[8]) */ + UsrInList->PhotoVisibility = Pri_GetVisibilityFromStr (row[8]); - /* Get user's institution code (row[8]) */ - UsrInList->InsCod = Str_ConvertStrCodToLongCod (row[8]); + /* Get user's institution code (row[9]) */ + UsrInList->InsCod = Str_ConvertStrCodToLongCod (row[9]); /* Get user's role and acceptance of enrollment in course(s) - (row[9], row[10] if Scope == Sco_SCOPE_CRS) */ + (row[10], row[11] if Scope == Sco_SCOPE_CRS) */ switch (Role) { case Rol_UNKNOWN: // Here Rol_UNKNOWN means any user @@ -4762,8 +4889,8 @@ static void Usr_GetListUsrsFromQuery (const char *Query,Rol_Role_t Role,Sco_Scop break; case Sco_SCOPE_CRS: // Course // Query result has a column with the acceptation - UsrInList->RoleInCurrentCrsDB = Rol_ConvertUnsignedStrToRole (row[9]); - UsrInList->Accepted = (row[10][0] == 'Y'); + UsrInList->RoleInCurrentCrsDB = Rol_ConvertUnsignedStrToRole (row[10]); + UsrInList->Accepted = (row[11][0] == 'Y'); break; } break; @@ -4792,8 +4919,8 @@ static void Usr_GetListUsrsFromQuery (const char *Query,Rol_Role_t Role,Sco_Scop break; case Sco_SCOPE_CRS: // Course // Query result has a column with the acceptation - UsrInList->RoleInCurrentCrsDB = Rol_ConvertUnsignedStrToRole (row[9]); - UsrInList->Accepted = (row[10][0] == 'Y'); + UsrInList->RoleInCurrentCrsDB = Rol_ConvertUnsignedStrToRole (row[10]); + UsrInList->Accepted = (row[11][0] == 'Y'); break; } break; diff --git a/swad_user.h b/swad_user.h index 6edfbc84..19649915 100644 --- a/swad_user.h +++ b/swad_user.h @@ -184,12 +184,13 @@ struct UsrLast struct UsrInList { long UsrCod; - char EncryptedUsrCod [Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64+1]; + char EncryptedUsrCod[Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64+1]; + char Password[Cry_LENGTH_ENCRYPTED_STR_SHA512_BASE64 + 1]; char Surname1 [Usr_MAX_BYTES_NAME + 1]; char Surname2 [Usr_MAX_BYTES_NAME + 1]; char FirstName[Usr_MAX_BYTES_NAME + 1]; Usr_Sex_t Sex; - char Photo[Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64+1]; // Name of public link to photo + char Photo[Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64 + 1]; // Name of public link to photo Pri_Visibility_t PhotoVisibility; // Who can see user's photo long InsCod; // Institution Rol_Role_t RoleInCurrentCrsDB; // Role in current course in database @@ -233,6 +234,8 @@ void Usr_RestrictLengthAndWriteName (const struct UsrData *UsrDat,unsigned MaxCh bool Usr_CheckIfUsrIsAdm (long UsrCod,Sco_Scope_t Scope,long Cod); bool Usr_CheckIfUsrIsSuperuser (long UsrCod); +bool Usr_CheckIfIAsAdminCanEditOtherUsr (const struct UsrData *UsrDat); + unsigned Usr_GetNumCrssOfUsr (long UsrCod); unsigned Usr_GetNumCrssOfUsrNotAccepted (long UsrCod); unsigned Usr_GetNumCrssOfUsrWithARole (long UsrCod,Rol_Role_t Role); @@ -259,17 +262,10 @@ void Usr_FreeMyCentres (void); void Usr_FreeMyDegrees (void); void Usr_FreeMyCourses (void); -bool Usr_CheckIfUsrBelongsToIns (long UsrCod, - long InsCod, - bool CountOnlyAcceptedCourses); -bool Usr_CheckIfUsrBelongsToCtr (long UsrCod, - long CtrCod, - bool CountOnlyAcceptedCourses); -bool Usr_CheckIfUsrBelongsToDeg (long UsrCod, - long DegCod, - bool CountOnlyAcceptedCourses); -bool Usr_CheckIfUsrBelongsToCrs (long UsrCod, - long CrsCod, +bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod); +bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod); +bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod); +bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, bool CountOnlyAcceptedCourses); bool Usr_CheckIfIBelongToCty (long CtyCod); diff --git a/swad_web_service.c b/swad_web_service.c index cbf16309..327a6499 100644 --- a/swad_web_service.c +++ b/swad_web_service.c @@ -1590,10 +1590,7 @@ static void Svc_CopyListUsers (Rol_Role_t Role,struct swad__getUsersOutput *getU /* Get list of user's IDs */ ID_GetListIDsFromUsrCod (&UsrDat); - if (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat.UsrCod) // It's me - ICanSeeUsrID = true; - else // A user distinct than me - ICanSeeUsrID = ID_ICanSeeAnotherUsrID (&UsrDat); + ICanSeeUsrID = ID_ICanSeeOtherUsrIDs (&UsrDat); /* Get nickname */ Nck_GetNicknameFromUsrCod (UsrDat.UsrCod,UsrDat.Nickname);