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,"
");
/***** 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);