From 1770339e5c60974499e73730a20da747e74cf39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Fri, 27 Jan 2017 15:21:01 +0100 Subject: [PATCH] Version 16.126.4 --- swad_ID.c | 29 ++++++++++++++++++----------- swad_action.c | 12 ++++++------ swad_changelog.h | 6 ++++-- swad_mail.c | 37 +++++++++++++++++++++++-------------- swad_mail.h | 2 +- swad_photo.c | 17 ++++++----------- swad_record.c | 18 +++++++++++++----- swad_user.c | 45 +++++++++++++++++++++++++++------------------ 8 files changed, 98 insertions(+), 68 deletions(-) diff --git a/swad_ID.c b/swad_ID.c index 637fd1d38..851095d99 100644 --- a/swad_ID.c +++ b/swad_ID.c @@ -414,17 +414,24 @@ bool ID_ICanSeeOtherUsrIDs (const struct UsrData *UsrDat) 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 && // 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) - ); + /* Check 1: I can see the IDs of users who do not exist in database */ + if (UsrDat->UsrCod <= 0) // User does not exist (when creating a new user) + return true; + + /* Check 2: I can see the IDs of confirmed students */ + if (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT && // A student + UsrDat->Accepted) // who accepted registration + return true; + + /* Check 3: I can see the IDs of users with user's data empty */ + if (!UsrDat->Password[0] && // User has no password (never logged) + !UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1) + !UsrDat->Surname2[0] && // and who has no surname 2 (nobody filled user's surname 2) + !UsrDat->FirstName[0]) // and who has no first name (nobody filled user's first name) + // Warning: I could view simultaneously ID and email (if filled) + return true; + + return false; case Rol_DEG_ADM: case Rol_CTR_ADM: case Rol_INS_ADM: diff --git a/swad_action.c b/swad_action.c index 49c110d0d..dfe448913 100644 --- a/swad_action.c +++ b/swad_action.c @@ -2470,13 +2470,13 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActCnfID_Std */{1569,-1,TabUnk,ActLstStd ,0x1F0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,ID_ConfirmOtherUsrID ,NULL}, /* 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}, + /* ActFrmIDsOth */{1447,-1,TabUnk,ActLstOth ,0x1F0,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_Oth */{1450,-1,TabUnk,ActLstOth ,0x1F0,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_Oth */{1453,-1,TabUnk,ActLstOth ,0x1F0,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}, @@ -2487,13 +2487,13 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActChgPwdStd */{1468,-1,TabUnk,ActLstStd ,0x1E0,0x1E0,0x1E0,Act_CONT_NORM,Act_THIS_WINDOW,Pwd_UpdateOtherPwd1 ,Pwd_UpdateOtherPwd2 ,NULL}, /* 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}, + /* ActFrmMaiOth */{1475,-1,TabUnk,ActLstOth ,0x1F0,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}, + /* ActRemMaiOth */{1478,-1,TabUnk,ActLstOth ,0x1F0,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}, + /* ActNewMaiOth */{1481,-1,TabUnk,ActLstOth ,0x1F0,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}, diff --git a/swad_changelog.h b/swad_changelog.h index 60094ea30..9119211e5 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -187,19 +187,21 @@ // 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: When creating a new user, the ID should be visible +// TODO: Warning: now a teacher can view ID and email of empty users (uswers without password and name). How to avoid this while allowing teacher editing empty users? /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.126.2 (2017-01-27)" +#define Log_PLATFORM_VERSION "SWAD 16.126.4 (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.126.4: Jan 27, 2017 Code refactoring related to permissions to view/change another user's data. (212105 lines) + Version 16.126.3: Jan 27, 2017 Fixed bug in search of user, reported by Javier Fernández Baldomero. (212086 lines) Version 16.126.2: Jan 27, 2017 When creating a new user, the record card don't have contextual icons. (212083 lines) Version 16.126.1: Jan 27, 2017 A teacher can create and register a new teacher directly in a course. (212080 lines) Version 16.126: Jan 27, 2017 Code refactoring related to permissions to view/change another user's data. (212086 lines) diff --git a/swad_mail.c b/swad_mail.c index 373a5923f..10618b962 100644 --- a/swad_mail.c +++ b/swad_mail.c @@ -1807,11 +1807,9 @@ void Mai_WriteFootNoteEMail (Txt_Language_t Language) /**************** Check if I can see another user's email ********************/ /*****************************************************************************/ -bool Mai_ICanSeeEmail (const struct UsrData *UsrDat) +bool Mai_ICanSeeOtherUsrEmail (const struct UsrData *UsrDat) { - bool ItsMe = (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod); - - if (ItsMe) + if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // It's me return true; /* Check if I have permission to see another user's email */ @@ -1820,17 +1818,28 @@ bool Mai_ICanSeeEmail (const struct UsrData *UsrDat) case Rol_STUDENT: /* If I am a student of current course, I only can see the user's email of teachers from current course */ - return (UsrDat->Accepted && - UsrDat->RoleInCurrentCrsDB == Rol_TEACHER); + return (UsrDat->RoleInCurrentCrsDB == Rol_TEACHER && + UsrDat->Accepted); 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->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 + /* Check 1: I can see the email of users who do not exist in database */ + if (UsrDat->UsrCod <= 0) // User does not exist (if in the future email is used to create a new user) + return true; + + /* Check 2: I can see the email of confirmed students and teachers */ + if ((UsrDat->RoleInCurrentCrsDB == Rol_STUDENT || // A student + UsrDat->RoleInCurrentCrsDB == Rol_TEACHER) && // or a teacher + UsrDat->Accepted) // who accepted registration + return true; + + /* Check 3: I can see the IDs of users with user's data empty */ + if (!UsrDat->Password[0] && // User has no password (never logged) + !UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1) + !UsrDat->Surname2[0] && // and who has no surname 2 (nobody filled user's surname 2) + !UsrDat->FirstName[0]) // and who has no first name (nobody filled user's first name) + // Warning: I could view simultaneously ID and email (if filled) + return true; + + return false; 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 */ diff --git a/swad_mail.h b/swad_mail.h index 6b566e0f1..80305d18c 100644 --- a/swad_mail.h +++ b/swad_mail.h @@ -95,6 +95,6 @@ void Mai_CreateFileNameMail (void); void Mai_WriteWelcomeNoteEMail (struct UsrData *UsrDat); void Mai_WriteFootNoteEMail (Txt_Language_t Language); -bool Mai_ICanSeeEmail (const struct UsrData *UsrDat); +bool Mai_ICanSeeOtherUsrEmail (const struct UsrData *UsrDat); #endif diff --git a/swad_photo.c b/swad_photo.c index e5062d791..3f3869978 100644 --- a/swad_photo.c +++ b/swad_photo.c @@ -140,17 +140,12 @@ bool Pho_ICanChangeOtherUsrPhoto (const struct UsrData *UsrDat) 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 && // 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) - ); + /* Check 1: I can change the photo of confirmed students */ + if (UsrDat->RoleInCurrentCrsDB == Rol_STUDENT && // A student + UsrDat->Accepted) // who accepted registration + return true; + + return false; case Rol_DEG_ADM: case Rol_CTR_ADM: case Rol_INS_ADM: diff --git a/swad_record.c b/swad_record.c index 412ae276a..dd79f6f8b 100644 --- a/swad_record.c +++ b/swad_record.c @@ -2701,7 +2701,7 @@ static void Rec_ShowEmail (struct UsrData *UsrDat,const char *ClassForm) ClassForm,Txt_Email); if (UsrDat->Email[0]) { - if (Mai_ICanSeeEmail (UsrDat)) + if (Mai_ICanSeeOtherUsrEmail (UsrDat)) { fprintf (Gbl.F.Out,"Email); @@ -2961,13 +2961,17 @@ static void Rec_ShowSurname1 (struct UsrData *UsrDat, "" ""); if (ICanEdit) + { fprintf (Gbl.F.Out,"", + " class=\"REC_C2_BOT_INPUT\"", Usr_MAX_LENGTH_USR_NAME_OR_SURNAME, UsrDat->Surname1); + if (TypeOfView == Rec_SHA_MY_RECORD_FORM) + fprintf (Gbl.F.Out," required=\"required\""); + fprintf (Gbl.F.Out," />"); + } else if (UsrDat->Surname1[0]) fprintf (Gbl.F.Out,"%s",UsrDat->Surname1); fprintf (Gbl.F.Out,"" @@ -3030,13 +3034,17 @@ static void Rec_ShowFirstName (struct UsrData *UsrDat, ""); if (ICanEdit) + { fprintf (Gbl.F.Out,"", + " class=\"REC_C2_BOT_INPUT\"", Usr_MAX_LENGTH_USR_NAME_OR_SURNAME, UsrDat->FirstName); + if (TypeOfView == Rec_SHA_MY_RECORD_FORM) + fprintf (Gbl.F.Out," required=\"required\""); + fprintf (Gbl.F.Out," />"); + } else if (UsrDat->FirstName[0]) fprintf (Gbl.F.Out,"%s",UsrDat->FirstName); fprintf (Gbl.F.Out,"" diff --git a/swad_user.c b/swad_user.c index f7fb52e8b..301a76008 100644 --- a/swad_user.c +++ b/swad_user.c @@ -834,13 +834,19 @@ bool Usr_ICanChangeOtherUsrData (const struct UsrData *UsrDat) switch (Gbl.Usrs.Me.LoggedRole) { case Rol_TEACHER: - /* If I am a teacher of current course, - I only can change the user's data 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) + /* Check 1: I can change data of users who do not exist in database */ + if (UsrDat->UsrCod <= 0) // User does not exist (when creating a new user) + return true; + + /* Check 2: I change data of users with user's data empty */ + if (!UsrDat->Password[0] && // User has no password (never logged) + !UsrDat->Surname1[0] && // and who has no surname 1 (nobody filled user's surname 1) + !UsrDat->Surname2[0] && // and who has no surname 2 (nobody filled user's surname 2) + !UsrDat->FirstName[0]) // and who has no first name (nobody filled user's first name) + // Warning: I could view simultaneously ID and email (if filled) + return true; + + return false; case Rol_DEG_ADM: case Rol_CTR_ADM: case Rol_INS_ADM: @@ -3609,8 +3615,9 @@ static void Usr_WriteEmail (struct UsrData *UsrDat,const char *BgColor) if (UsrDat->Email[0]) { - ShowEmail = Mai_ICanSeeEmail (UsrDat); - sprintf (MailLink,"mailto:%s",UsrDat->Email); + ShowEmail = Mai_ICanSeeOtherUsrEmail (UsrDat); + if (ShowEmail) + sprintf (MailLink,"mailto:%s",UsrDat->Email); } else ShowEmail = false; @@ -4254,6 +4261,7 @@ void Usr_SearchListUsrs (Rol_Role_t Role) const char *QueryFields = "DISTINCT usr_data.UsrCod," "usr_data.EncryptedUsrCod," + "usr_data.Password," "usr_data.Surname1," "usr_data.Surname2," "usr_data.FirstName," @@ -4264,15 +4272,16 @@ void Usr_SearchListUsrs (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) */ const char *OrderQuery = "candidate_users.UsrCod=usr_data.UsrCod" " ORDER BY "