mirror of https://github.com/acanas/swad-core.git
6781 lines
231 KiB
C
6781 lines
231 KiB
C
// swad_user.c: users
|
|
|
|
/*
|
|
SWAD (Shared Workspace At a Distance),
|
|
is a web platform developed at the University of Granada (Spain),
|
|
and used to support university teaching.
|
|
|
|
This file is part of SWAD core.
|
|
Copyright (C) 1999-2023 Antonio CaƱas Vargas
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General 3 License as
|
|
published by the Free Software Foundation, either version 3 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
/*****************************************************************************/
|
|
/*********************************** Headers *********************************/
|
|
/*****************************************************************************/
|
|
|
|
#define _GNU_SOURCE // For asprintf
|
|
#include <ctype.h> // For isalnum, isdigit, etc.
|
|
#include <limits.h> // For maximum values
|
|
#include <linux/limits.h> // For PATH_MAX
|
|
#include <stddef.h> // For NULL
|
|
#include <stdio.h> // For asprintf
|
|
#include <stdlib.h> // For exit, system, malloc, free, rand, etc.
|
|
#include <string.h> // For string functions
|
|
#include <sys/wait.h> // For the macro WEXITSTATUS
|
|
#include <unistd.h> // For access, lstat, getpid, chdir, symlink, unlink
|
|
|
|
#include "swad_account.h"
|
|
#include "swad_action_list.h"
|
|
#include "swad_admin.h"
|
|
#include "swad_admin_database.h"
|
|
#include "swad_agenda.h"
|
|
#include "swad_announcement.h"
|
|
#include "swad_box.h"
|
|
#include "swad_calendar.h"
|
|
#include "swad_center_database.h"
|
|
#include "swad_config.h"
|
|
#include "swad_constant.h"
|
|
#include "swad_connected_database.h"
|
|
#include "swad_country_database.h"
|
|
#include "swad_course.h"
|
|
#include "swad_database.h"
|
|
#include "swad_degree_database.h"
|
|
#include "swad_department.h"
|
|
#include "swad_duplicate.h"
|
|
#include "swad_enrolment.h"
|
|
#include "swad_enrolment_database.h"
|
|
#include "swad_error.h"
|
|
#include "swad_figure.h"
|
|
#include "swad_figure_cache.h"
|
|
#include "swad_follow.h"
|
|
#include "swad_form.h"
|
|
#include "swad_global.h"
|
|
#include "swad_group.h"
|
|
#include "swad_help.h"
|
|
#include "swad_hidden_visible.h"
|
|
#include "swad_hierarchy.h"
|
|
#include "swad_hierarchy_level.h"
|
|
#include "swad_HTML.h"
|
|
#include "swad_ID.h"
|
|
#include "swad_institution_database.h"
|
|
#include "swad_language.h"
|
|
#include "swad_mail_database.h"
|
|
#include "swad_message.h"
|
|
#include "swad_MFU.h"
|
|
#include "swad_nickname.h"
|
|
#include "swad_nickname_database.h"
|
|
#include "swad_notification.h"
|
|
#include "swad_parameter.h"
|
|
#include "swad_password.h"
|
|
#include "swad_photo.h"
|
|
#include "swad_privacy.h"
|
|
#include "swad_profile.h"
|
|
#include "swad_QR.h"
|
|
#include "swad_record.h"
|
|
#include "swad_record_database.h"
|
|
#include "swad_role.h"
|
|
#include "swad_session.h"
|
|
#include "swad_session_database.h"
|
|
#include "swad_setting.h"
|
|
#include "swad_tab.h"
|
|
#include "swad_user.h"
|
|
#include "swad_user_database.h"
|
|
|
|
/*****************************************************************************/
|
|
/****************************** Public constants *****************************/
|
|
/*****************************************************************************/
|
|
|
|
const char *Usr_StringsSexIcons[Usr_NUM_SEXS] =
|
|
{
|
|
[Usr_SEX_UNKNOWN] = "?",
|
|
[Usr_SEX_FEMALE ] = "♀",
|
|
[Usr_SEX_MALE ] = "♂",
|
|
[Usr_SEX_ALL ] = "*",
|
|
};
|
|
|
|
const char *Usr_StringsSexDB[Usr_NUM_SEXS] =
|
|
{
|
|
[Usr_SEX_UNKNOWN] = "unknown",
|
|
[Usr_SEX_FEMALE ] = "female",
|
|
[Usr_SEX_MALE ] = "male",
|
|
[Usr_SEX_ALL ] = "all",
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
/***************************** Private constants *****************************/
|
|
/*****************************************************************************/
|
|
|
|
static const char *Usr_IconsClassPhotoOrList[Set_NUM_USR_LIST_TYPES] =
|
|
{
|
|
[Set_USR_LIST_UNKNOWN ] = "",
|
|
[Set_USR_LIST_AS_CLASS_PHOTO] = "th.svg",
|
|
[Set_USR_LIST_AS_LISTING ] = "list-ol.svg",
|
|
};
|
|
|
|
static const char *Usr_NameSelUnsel[Rol_NUM_ROLES] =
|
|
{
|
|
[Rol_GST] = "SEL_UNSEL_GSTS",
|
|
[Rol_STD] = "SEL_UNSEL_STDS",
|
|
[Rol_NET] = "SEL_UNSEL_NETS",
|
|
[Rol_TCH] = "SEL_UNSEL_TCHS",
|
|
};
|
|
static const char *Usr_ParUsrCod[Rol_NUM_ROLES] =
|
|
{
|
|
[Rol_UNK] = "UsrCodAll", // here means all users
|
|
[Rol_GST] = "UsrCodGst",
|
|
[Rol_STD] = "UsrCodStd",
|
|
[Rol_NET] = "UsrCodNET",
|
|
[Rol_TCH] = "UsrCodTch",
|
|
};
|
|
|
|
#define Usr_NUM_MAIN_FIELDS_DATA_ADM 7
|
|
#define Usr_NUM_ALL_FIELDS_DATA_GST 14
|
|
#define Usr_NUM_ALL_FIELDS_DATA_STD 10
|
|
#define Usr_NUM_ALL_FIELDS_DATA_TCH 11
|
|
const char *Usr_UsrDatMainFieldNames[Usr_NUM_MAIN_FIELDS_DATA_USR];
|
|
|
|
/*****************************************************************************/
|
|
/************** External global variables from others modules ****************/
|
|
/*****************************************************************************/
|
|
|
|
extern struct Globals Gbl;
|
|
|
|
/*****************************************************************************/
|
|
/****************************** Private variables ****************************/
|
|
/*****************************************************************************/
|
|
|
|
static void (*Usr_FuncParsBigList) (void *Args); // Used to pass pointer to function
|
|
|
|
/*****************************************************************************/
|
|
/***************************** Private prototypes ****************************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_GetMyLastData (void);
|
|
static void Usr_GetUsrCommentsFromString (char *Str,struct Usr_Data *UsrDat);
|
|
static Usr_Sex_t Usr_GetSexFromStr (const char *Str);
|
|
|
|
static void Usr_GetParOtherUsrIDNickOrEMail (void);
|
|
|
|
static bool Usr_ChkUsrAndGetUsrDataFromDirectLogin (void);
|
|
static bool Usr_ChkUsrAndGetUsrDataFromSession (void);
|
|
static void Usr_ShowAlertUsrDoesNotExistsOrWrongPassword (void);
|
|
static void Usr_ShowAlertThereAreMoreThanOneUsr (void);
|
|
|
|
static void Usr_SetMyPrefsAndRoles (void);
|
|
|
|
static void Usr_PutLinkToLogOut (__attribute__((unused)) void *Args);
|
|
|
|
static void Usr_WriteRowGstAllData (struct Usr_Data *UsrDat);
|
|
static void Usr_WriteRowStdAllData (struct Usr_Data *UsrDat,char *GroupNames);
|
|
static void Usr_WriteRowTchAllData (struct Usr_Data *UsrDat);
|
|
static void Usr_WriteRowAdmData (unsigned NumUsr,struct Usr_Data *UsrDat);
|
|
static void Usr_WriteMainUsrDataExceptUsrID (struct Usr_Data *UsrDat,
|
|
const char *BgColor);
|
|
static void Usr_WriteEmail (struct Usr_Data *UsrDat,const char *BgColor);
|
|
static void Usr_WriteUsrData (const char *BgColor,
|
|
const char *Data,const char *Link,
|
|
bool NonBreak,bool Accepted);
|
|
|
|
static void Usr_GetGstsLst (HieLvl_Level_t Scope);
|
|
static void Usr_AllocateUsrsList (Rol_Role_t Role);
|
|
|
|
static void Usr_PutButtonToConfirmIWantToSeeBigList (unsigned NumUsrs,
|
|
void (*FuncPars) (void *Args),void *Args,
|
|
const char *OnSubmit);
|
|
static void Usr_PutParsConfirmIWantToSeeBigList (void *Args);
|
|
|
|
static void Usr_BuildParName (char **ParName,
|
|
const char *ParRoot,
|
|
const char *ParSuffix);
|
|
|
|
static void Usr_AllocateListSelectedEncryptedUsrCods (struct Usr_SelectedUsrs *SelectedUsrs,
|
|
Rol_Role_t Role);
|
|
static void Usr_AllocateListOtherRecipients (void);
|
|
|
|
static void Set_FormToSelectUsrListType (void (*FuncPars) (void *Args),void *Args,
|
|
Set_ShowUsrsType_t ListType);
|
|
static void Usr_PutCheckboxToSelectAllUsers (Rol_Role_t Role,
|
|
struct Usr_SelectedUsrs *SelectedUsrs);
|
|
static Usr_Sex_t Usr_GetSexOfUsrsLst (Rol_Role_t Role);
|
|
static void Usr_PutCheckboxToSelectUser (Rol_Role_t Role,
|
|
const char *EncryptedUsrCod,
|
|
bool UsrIsTheMsgSender,
|
|
struct Usr_SelectedUsrs *SelectedUsrs);
|
|
static void Usr_PutCheckboxListWithPhotos (void);
|
|
|
|
static void Usr_ListMainDataGsts (bool PutCheckBoxToSelectUsr);
|
|
static void Usr_ListMainDataStds (bool PutCheckBoxToSelectUsr);
|
|
static void Usr_ListMainDataTchs (Rol_Role_t Role,
|
|
bool PutCheckBoxToSelectUsr);
|
|
static void Usr_ListUsrsForSelection (Rol_Role_t Role,
|
|
struct Usr_SelectedUsrs *SelectedUsrs);
|
|
static void Usr_ListRowsAllDataTchs (Rol_Role_t Role,
|
|
const char *FieldNames[Usr_NUM_ALL_FIELDS_DATA_TCH],
|
|
unsigned NumColumns);
|
|
|
|
static void Usr_PutLinkToSeeAdmins (void);
|
|
static void Usr_PutLinkToSeeGuests (void);
|
|
|
|
static bool Usr_SetOptionsListUsrsAllowed (Rol_Role_t UsrsRole,
|
|
bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS]);
|
|
static void Usr_PutOptionsListUsrs (const bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS]);
|
|
static void Usr_ShowOneListUsrsOption (Usr_ListUsrsOption_t ListUsrsAction,
|
|
const char *Label);
|
|
static Usr_ListUsrsOption_t Usr_GetListUsrsOption (Usr_ListUsrsOption_t DefaultAction);
|
|
|
|
static void Usr_PutIconsListGsts (__attribute__((unused)) void *Args);
|
|
static void Usr_PutIconsListStds (__attribute__((unused)) void *Args);
|
|
static void Usr_PutIconsListTchs (__attribute__((unused)) void *Args);
|
|
|
|
static void Usr_PutIconToPrintGsts (void);
|
|
static void Usr_PutIconToPrintStds (void);
|
|
static void Usr_PutIconToPrintTchs (void);
|
|
static void Usr_PutIconToShowGstsAllData (void);
|
|
static void Usr_PutIconToShowStdsAllData (void);
|
|
static void Usr_PutIconToShowTchsAllData (void);
|
|
static void Usr_ShowGstsAllDataPars (__attribute__((unused)) void *Args);
|
|
static void Usr_ShowStdsAllDataPars (__attribute__((unused)) void *Args);
|
|
static void Usr_ShowTchsAllDataPars (__attribute__((unused)) void *Args);
|
|
|
|
static void Usr_DrawClassPhoto (Usr_ClassPhotoType_t ClassPhotoType,
|
|
Rol_Role_t Role,
|
|
struct Usr_SelectedUsrs *SelectedUsrs,
|
|
bool PutCheckBoxToSelectUsr);
|
|
|
|
static void Usr_GetAndShowNumUsrsInCrss (Rol_Role_t Role);
|
|
static void Usr_GetAndShowNumUsrsNotBelongingToAnyCrs (void);
|
|
|
|
/*****************************************************************************/
|
|
/**** Show alert about number of clicks remaining before sending my photo ****/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_InformAboutNumClicksBeforePhoto (void)
|
|
{
|
|
extern const char *Txt_You_must_send_your_photo_because_;
|
|
extern const char *Txt_You_can_only_perform_X_further_actions_;
|
|
extern const char *Txt_Upload_photo;
|
|
|
|
if (Gbl.Usrs.Me.NumAccWithoutPhoto)
|
|
{
|
|
if (Gbl.Usrs.Me.NumAccWithoutPhoto >= Pho_MAX_CLICKS_WITHOUT_PHOTO)
|
|
Ale_ShowAlert (Ale_WARNING,Txt_You_must_send_your_photo_because_);
|
|
else if (Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB)
|
|
Ale_ShowAlertAndButton (ActReqMyPho,NULL,NULL,
|
|
NULL,NULL,
|
|
Btn_CONFIRM_BUTTON,Txt_Upload_photo,
|
|
Ale_WARNING,Txt_You_can_only_perform_X_further_actions_,
|
|
Pho_MAX_CLICKS_WITHOUT_PHOTO - Gbl.Usrs.Me.NumAccWithoutPhoto);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************** Create data for a user ***************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_UsrDataConstructor (struct Usr_Data *UsrDat)
|
|
{
|
|
/***** Allocate memory for the comments *****/
|
|
if ((UsrDat->Comments = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL)
|
|
Err_NotEnoughMemoryExit ();
|
|
|
|
/***** Initialize to zero the data of the user *****/
|
|
Usr_ResetUsrDataExceptUsrCodAndIDs (UsrDat);
|
|
UsrDat->IDs.Num = 0;
|
|
UsrDat->IDs.List = NULL;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/****************** Reset user's data except UsrCod and ID *******************/
|
|
/*****************************************************************************/
|
|
// UsrCod and ID are not changed
|
|
|
|
void Usr_ResetUsrDataExceptUsrCodAndIDs (struct Usr_Data *UsrDat)
|
|
{
|
|
UsrDat->EnUsrCod[0] = '\0';
|
|
UsrDat->Nickname[0] = '\0';
|
|
UsrDat->Password[0] = '\0';
|
|
UsrDat->Roles.InCurrentCrs = Rol_UNK;// not yet got from database
|
|
UsrDat->Roles.InCrss = -1; // not yet got from database
|
|
UsrDat->Accepted = false;
|
|
|
|
UsrDat->Sex = Usr_SEX_UNKNOWN;
|
|
UsrDat->Surname1[0] = '\0';
|
|
UsrDat->Surname2[0] = '\0';
|
|
UsrDat->FrstName[0] = '\0';
|
|
UsrDat->FullName[0] = '\0';
|
|
|
|
UsrDat->Email[0] = '\0';
|
|
UsrDat->EmailConfirmed = false;
|
|
|
|
UsrDat->Photo[0] = '\0';
|
|
UsrDat->PhotoVisibility = Pri_PHOTO_VIS_DEFAULT;
|
|
UsrDat->BaPrfVisibility = Pri_BASIC_PROFILE_VIS_DEFAULT;
|
|
UsrDat->ExPrfVisibility = Pri_EXTENDED_PROFILE_VIS_DEFAULT;
|
|
|
|
UsrDat->CtyCod = -1L;
|
|
UsrDat->StrBirthday[0] = '\0';
|
|
UsrDat->Birthday.Day = 0;
|
|
UsrDat->Birthday.Month = 0;
|
|
UsrDat->Birthday.Year = 0;
|
|
UsrDat->Phone[0][0] =
|
|
UsrDat->Phone[1][0] = '\0';
|
|
if (UsrDat->Comments)
|
|
UsrDat->Comments[0] = '\0';
|
|
|
|
UsrDat->InsCtyCod = -1L;
|
|
UsrDat->InsCod = -1L;
|
|
UsrDat->Tch.CtrCod = -1L;
|
|
UsrDat->Tch.DptCod = -1L;
|
|
UsrDat->Tch.Office[0] = '\0';
|
|
UsrDat->Tch.OfficePhone[0] = '\0';
|
|
|
|
UsrDat->Prefs.Language = Lan_LANGUAGE_UNKNOWN; // Language unknown
|
|
UsrDat->Prefs.FirstDayOfWeek = Cal_FIRST_DAY_OF_WEEK_DEFAULT; // Default first day of week
|
|
UsrDat->Prefs.DateFormat = Dat_FORMAT_DEFAULT ; // Default date format
|
|
UsrDat->Prefs.Theme = The_THEME_DEFAULT;
|
|
UsrDat->Prefs.IconSet = Ico_ICON_SET_DEFAULT;
|
|
UsrDat->Prefs.Menu = Mnu_MENU_DEFAULT;
|
|
UsrDat->Prefs.SideCols = Cfg_DEFAULT_COLUMNS;
|
|
UsrDat->Prefs.PhotoShape = PhoSha_SHAPE_DEFAULT;
|
|
UsrDat->Prefs.RefuseAcceptCookies = Coo_REFUSE; // By default, don't accept third party cookies
|
|
UsrDat->NtfEvents.SendEmail = 0; // By default, don't notify anything
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**************************** Reset my last data *****************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_ResetMyLastData (void)
|
|
{
|
|
Gbl.Usrs.Me.UsrLast.WhatToSearch = Sch_WHAT_TO_SEARCH_DEFAULT;
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Scope = HieLvl_UNK;
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Cod = -1L;
|
|
Gbl.Usrs.Me.UsrLast.LastAct = ActUnk;
|
|
Gbl.Usrs.Me.UsrLast.LastRole = Rol_UNK;
|
|
Gbl.Usrs.Me.UsrLast.LastTime = 0;
|
|
Gbl.Usrs.Me.UsrLast.LastAccNotif = 0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**************** Free memory used to store the data of a user ***************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_UsrDataDestructor (struct Usr_Data *UsrDat)
|
|
{
|
|
/***** Free memory allocated for comments *****/
|
|
if (UsrDat->Comments)
|
|
{
|
|
free (UsrDat->Comments);
|
|
UsrDat->Comments = NULL;
|
|
}
|
|
|
|
/***** Free memory allocated for list of IDs *****/
|
|
ID_FreeListIDs (UsrDat);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*************** Get all user's data from a given user's code ****************/
|
|
/*****************************************************************************/
|
|
// Input: UsrDat->UsrCod must hold user's code
|
|
|
|
void Usr_GetAllUsrDataFromUsrCod (struct Usr_Data *UsrDat,
|
|
Usr_GetPrefs_t GetPrefs,
|
|
Usr_GetRoleInCurrentCrs_t GetRoleInCurrentCrs)
|
|
{
|
|
ID_GetListIDsFromUsrCod (UsrDat);
|
|
Usr_GetUsrDataFromUsrCod (UsrDat,GetPrefs,GetRoleInCurrentCrs);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**************** Allocate memory for the list of users' codes ***************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_AllocateListUsrCods (struct Usr_ListUsrCods *ListUsrCods)
|
|
{
|
|
if ((ListUsrCods->Lst = malloc (ListUsrCods->NumUsrs *
|
|
sizeof (*ListUsrCods->Lst))) == NULL)
|
|
Err_NotEnoughMemoryExit ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/****************** Free memory for the list of users' codes *****************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_FreeListUsrCods (struct Usr_ListUsrCods *ListUsrCods)
|
|
{
|
|
if (ListUsrCods->NumUsrs && ListUsrCods->Lst)
|
|
{
|
|
free (ListUsrCods->Lst);
|
|
ListUsrCods->Lst = NULL;
|
|
ListUsrCods->NumUsrs = 0;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************ Check if I am a given user *************************/
|
|
/*****************************************************************************/
|
|
|
|
Usr_MeOrOther_t Usr_ItsMe (long UsrCod)
|
|
{
|
|
return (Gbl.Usrs.Me.Logged &&
|
|
UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) ? Usr_ME :
|
|
Usr_OTHER;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******** Get user's code from database using encrypted user's code **********/
|
|
/*****************************************************************************/
|
|
// Input: UsrDat->EncryptedUsrCod must hold user's encrypted code
|
|
|
|
void Usr_GetUsrCodFromEncryptedUsrCod (struct Usr_Data *UsrDat)
|
|
{
|
|
if (UsrDat->EnUsrCod[0])
|
|
/***** Get user's code from database *****/
|
|
UsrDat->UsrCod = Usr_DB_GetUsrCodFromEncryptedUsrCod (UsrDat->EnUsrCod);
|
|
else
|
|
UsrDat->UsrCod = -1L;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************ Get user's data from database giving a user's code *************/
|
|
/*****************************************************************************/
|
|
// UsrDat->UsrCod must contain an existing user's code
|
|
|
|
void Usr_GetUsrDataFromUsrCod (struct Usr_Data *UsrDat,
|
|
Usr_GetPrefs_t GetPrefs,
|
|
Usr_GetRoleInCurrentCrs_t GetRoleInCurrentCrs)
|
|
{
|
|
MYSQL_RES *mysql_res;
|
|
MYSQL_ROW row;
|
|
|
|
/***** Get user's data from database *****/
|
|
if (Usr_DB_GetUsrDataFromUsrCod (&mysql_res,UsrDat->UsrCod,GetPrefs))
|
|
{
|
|
/***** Read user's data *****/
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
/* Get encrypted user's code (row[0])
|
|
and encrypted password (row[1]) */
|
|
Str_Copy (UsrDat->EnUsrCod,row[0],sizeof (UsrDat->EnUsrCod) - 1);
|
|
Str_Copy (UsrDat->Password,row[1],sizeof (UsrDat->Password) - 1);
|
|
|
|
/* Get roles */
|
|
switch (GetRoleInCurrentCrs)
|
|
{
|
|
case Usr_DONT_GET_ROLE_IN_CURRENT_CRS:
|
|
UsrDat->Roles.InCurrentCrs = Rol_UNK;
|
|
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
|
|
break;
|
|
case Usr_GET_ROLE_IN_CURRENT_CRS:
|
|
UsrDat->Roles.InCurrentCrs = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
|
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
|
|
break;
|
|
}
|
|
|
|
/* Get name (row[2], row[3], row[4]) */
|
|
Str_Copy (UsrDat->Surname1,row[2],sizeof (UsrDat->Surname1) - 1);
|
|
Str_Copy (UsrDat->Surname2,row[3],sizeof (UsrDat->Surname2) - 1);
|
|
Str_Copy (UsrDat->FrstName,row[4],sizeof (UsrDat->FrstName) - 1);
|
|
Str_ConvertToTitleType (UsrDat->Surname1 );
|
|
Str_ConvertToTitleType (UsrDat->Surname2 );
|
|
Str_ConvertToTitleType (UsrDat->FrstName);
|
|
Usr_BuildFullName (UsrDat); // Create full name using FirstName, Surname1 and Surname2
|
|
|
|
/* Get sex (row[5]) */
|
|
UsrDat->Sex = Usr_GetSexFromStr (row[5]);
|
|
|
|
/* Get photo (row[6]) */
|
|
Str_Copy (UsrDat->Photo,row[6],sizeof (UsrDat->Photo) - 1);
|
|
|
|
/* Get photo visibility (row[7]) */
|
|
UsrDat->PhotoVisibility = Pri_GetVisibilityFromStr (row[7]);
|
|
|
|
/* Get profile visibility (row[8], row[9]) */
|
|
UsrDat->BaPrfVisibility = Pri_GetVisibilityFromStr (row[8]);
|
|
UsrDat->ExPrfVisibility = Pri_GetVisibilityFromStr (row[9]);
|
|
|
|
/* Get country (row[10]), institution country (row[11]),
|
|
institution (row[12]), department (row[13]) and center (row[14]) */
|
|
UsrDat->CtyCod = Str_ConvertStrCodToLongCod (row[10]);
|
|
UsrDat->InsCtyCod = Str_ConvertStrCodToLongCod (row[11]);
|
|
UsrDat->InsCod = Str_ConvertStrCodToLongCod (row[12]);
|
|
UsrDat->Tch.DptCod = Str_ConvertStrCodToLongCod (row[13]);
|
|
UsrDat->Tch.CtrCod = Str_ConvertStrCodToLongCod (row[14]);
|
|
|
|
/* Get office (row[15]) and office phone (row[16]) */
|
|
Str_Copy (UsrDat->Tch.Office ,row[15],sizeof (UsrDat->Tch.Office ) - 1);
|
|
Str_Copy (UsrDat->Tch.OfficePhone,row[16],sizeof (UsrDat->Tch.OfficePhone) - 1);
|
|
|
|
/* Get phones (row[17]) and row[18] */
|
|
Str_Copy (UsrDat->Phone[0],row[17],sizeof (UsrDat->Phone[0]) - 1);
|
|
Str_Copy (UsrDat->Phone[1],row[18],sizeof (UsrDat->Phone[1]) - 1);
|
|
|
|
/* Get birthday (row[19]) */
|
|
Dat_GetDateFromYYYYMMDD (&(UsrDat->Birthday),row[19]);
|
|
Dat_ConvDateToDateStr (&(UsrDat->Birthday),UsrDat->StrBirthday);
|
|
|
|
/* Get comments (row[20]) */
|
|
Usr_GetUsrCommentsFromString (row[20] ? row[20] :
|
|
"",
|
|
UsrDat);
|
|
|
|
/* Get on which events the user wants to be notified inside the platform (row[21]) */
|
|
if (sscanf (row[21],"%u",&UsrDat->NtfEvents.CreateNotif) != 1)
|
|
UsrDat->NtfEvents.CreateNotif = (unsigned) -1; // 0xFF..FF
|
|
|
|
/* Get on which events the user wants to be notified by email (row[22]) */
|
|
if (sscanf (row[22],"%u",&UsrDat->NtfEvents.SendEmail) != 1)
|
|
UsrDat->NtfEvents.SendEmail = 0;
|
|
if (UsrDat->NtfEvents.SendEmail >= (1 << Ntf_NUM_NOTIFY_EVENTS)) // Maximum binary value for NotifyEvents is 000...0011...11
|
|
UsrDat->NtfEvents.SendEmail = 0;
|
|
|
|
/***** Get user's settings *****/
|
|
if (GetPrefs == Usr_GET_PREFS)
|
|
{
|
|
/* Get language (row[23]),
|
|
first day of week (row[24]),
|
|
date format (row[25]),
|
|
theme (row[26]),
|
|
icon set (row[27]),
|
|
menu (row[28]),
|
|
if user wants to show side columns (row[29]),
|
|
user settings on user photo shape (row[30]),
|
|
and if user accepts third party cookies (row[31]) */
|
|
UsrDat->Prefs.Language = Lan_GetLanguageFromStr (row[23]);
|
|
UsrDat->Prefs.FirstDayOfWeek = Cal_GetFirstDayOfWeekFromStr (row[24]);
|
|
UsrDat->Prefs.DateFormat = Dat_GetDateFormatFromStr (row[25]);
|
|
UsrDat->Prefs.Theme = The_GetThemeFromStr (row[26]);
|
|
UsrDat->Prefs.IconSet = Ico_GetIconSetFromStr (row[27]);
|
|
UsrDat->Prefs.Menu = Mnu_GetMenuFromStr (row[28]);
|
|
UsrDat->Prefs.SideCols = Set_GetSideColsFromStr (row[29]);
|
|
UsrDat->Prefs.PhotoShape = PhoSha_GetShapeFromStr (row[30]);
|
|
UsrDat->Prefs.RefuseAcceptCookies = (row[31][0] == 'Y') ? Coo_ACCEPT :
|
|
Coo_REFUSE;
|
|
}
|
|
}
|
|
else
|
|
Err_WrongUserExit ();
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
/***** Get nickname and email *****/
|
|
Nck_DB_GetNicknameFromUsrCod (UsrDat->UsrCod,UsrDat->Nickname);
|
|
Mai_GetEmailFromUsrCod (UsrDat);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********* Get the comments in the record of a user from a string ************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_GetUsrCommentsFromString (char *Str,struct Usr_Data *UsrDat)
|
|
{
|
|
/***** Check that memory for comments is allocated *****/
|
|
if (UsrDat->Comments)
|
|
/***** Copy comments from Str to Comments *****/
|
|
Str_Copy (UsrDat->Comments,Str,Cns_MAX_BYTES_TEXT - 1);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********** Get user's last data from database giving a user's code **********/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_GetMyLastData (void)
|
|
{
|
|
MYSQL_RES *mysql_res;
|
|
MYSQL_ROW row;
|
|
unsigned UnsignedNum;
|
|
long ActCod;
|
|
|
|
/***** Get user's last data from database *****/
|
|
if (Usr_DB_GetMyLastData (&mysql_res))
|
|
{
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
/* Get last type of search (row[0]) */
|
|
Gbl.Usrs.Me.UsrLast.WhatToSearch = Sch_SEARCH_UNKNOWN;
|
|
if (sscanf (row[0],"%u",&UnsignedNum) == 1)
|
|
if (UnsignedNum < Sch_NUM_WHAT_TO_SEARCH)
|
|
Gbl.Usrs.Me.UsrLast.WhatToSearch = (Sch_WhatToSearch_t) UnsignedNum;
|
|
if (Gbl.Usrs.Me.UsrLast.WhatToSearch == Sch_SEARCH_UNKNOWN)
|
|
Gbl.Usrs.Me.UsrLast.WhatToSearch = Sch_WHAT_TO_SEARCH_DEFAULT;
|
|
|
|
/* Get last hierarchy: scope (row[1]) and code (row[2]) */
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Scope = Sco_GetScopeFromDBStr (row[1]);
|
|
switch (Gbl.Usrs.Me.UsrLast.LastHie.Scope)
|
|
{
|
|
case HieLvl_SYS: // System
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Cod = -1L;
|
|
break;
|
|
case HieLvl_CTY: // Country
|
|
case HieLvl_INS: // Institution
|
|
case HieLvl_CTR: // Center
|
|
case HieLvl_DEG: // Degree
|
|
case HieLvl_CRS: // Course
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Cod = Str_ConvertStrCodToLongCod (row[2]);
|
|
if (Gbl.Usrs.Me.UsrLast.LastHie.Cod <= 0)
|
|
{
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Scope = HieLvl_UNK;
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Cod = -1L;
|
|
}
|
|
break;
|
|
default:
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Scope = HieLvl_UNK;
|
|
Gbl.Usrs.Me.UsrLast.LastHie.Cod = -1L;
|
|
break;
|
|
}
|
|
|
|
/* Get last action (row[3]) */
|
|
ActCod = Str_ConvertStrCodToLongCod (row[3]);
|
|
Gbl.Usrs.Me.UsrLast.LastAct = Act_GetActionFromActCod (ActCod);
|
|
|
|
/* Get last role (row[4]) */
|
|
Gbl.Usrs.Me.UsrLast.LastRole = Rol_ConvertUnsignedStrToRole (row[4]);
|
|
|
|
/* Get last access to platform (row[5]) */
|
|
Gbl.Usrs.Me.UsrLast.LastTime = 0L;
|
|
if (row[5])
|
|
sscanf (row[5],"%ld",&(Gbl.Usrs.Me.UsrLast.LastTime));
|
|
|
|
/* Get last access to notifications (row[6]) */
|
|
Gbl.Usrs.Me.UsrLast.LastAccNotif = 0L;
|
|
if (row[6])
|
|
sscanf (row[6],"%ld",&(Gbl.Usrs.Me.UsrLast.LastAccNotif));
|
|
}
|
|
else // No user's last data found
|
|
{
|
|
/***** Create entry for me in table of user's last data *****/
|
|
Usr_ResetMyLastData ();
|
|
Usr_DB_InsertMyLastData ();
|
|
}
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/****************************** Get sex from string **************************/
|
|
/*****************************************************************************/
|
|
|
|
static Usr_Sex_t Usr_GetSexFromStr (const char *Str)
|
|
{
|
|
Usr_Sex_t Sex;
|
|
|
|
for (Sex = (Usr_Sex_t) 0;
|
|
Sex <= (Usr_Sex_t) (Usr_NUM_SEXS - 1);
|
|
Sex++)
|
|
if (!strcasecmp (Str,Usr_StringsSexDB[Sex]))
|
|
return Sex;
|
|
|
|
return Usr_SEX_UNKNOWN;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********** Build full name using FirstName, Surname1 and Surname2 ***********/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_BuildFullName (struct Usr_Data *UsrDat)
|
|
{
|
|
Str_Copy (UsrDat->FullName,UsrDat->FrstName,sizeof (UsrDat->FullName) - 1);
|
|
if (UsrDat->Surname1[0])
|
|
{
|
|
Str_Concat (UsrDat->FullName," " ,sizeof (UsrDat->FullName) - 1);
|
|
Str_Concat (UsrDat->FullName,UsrDat->Surname1,sizeof (UsrDat->FullName) - 1);
|
|
}
|
|
if (UsrDat->Surname2[0])
|
|
{
|
|
Str_Concat (UsrDat->FullName," " ,sizeof (UsrDat->FullName) - 1);
|
|
Str_Concat (UsrDat->FullName,UsrDat->Surname2,sizeof (UsrDat->FullName) - 1);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********* Write user name in two lines. 1: first name, 2: surnames **********/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_WriteFirstNameBRSurnames (const struct Usr_Data *UsrDat)
|
|
{
|
|
/***** Write first name and surname 1 *****/
|
|
HTM_Txt (UsrDat->FrstName);
|
|
HTM_BR ();
|
|
HTM_Txt (UsrDat->Surname1);
|
|
|
|
/***** Write surname2 if exists *****/
|
|
if (UsrDat->Surname2[0])
|
|
HTM_TxtF (" %s",UsrDat->Surname2);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************* Flush all caches related to users *********************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_FlushCachesUsr (void)
|
|
{
|
|
Ins_FlushCacheUsrBelongsToIns ();
|
|
Ctr_FlushCacheUsrBelongsToCtr ();
|
|
Deg_FlushCacheUsrBelongsToDeg ();
|
|
Enr_FlushCacheUsrBelongsToCrs ();
|
|
Enr_FlushCacheUsrBelongsToCurrentCrs ();
|
|
Enr_FlushCacheUsrHasAcceptedInCurrentCrs ();
|
|
Enr_FlushCacheUsrSharesAnyOfMyCrs ();
|
|
Rol_FlushCacheMyRoleInCurrentCrs ();
|
|
Rol_FlushCacheRoleUsrInCrs ();
|
|
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
|
|
Grp_FlushCacheIBelongToGrp ();
|
|
Fol_FlushCacheFollow ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************* Check if a user is a superuser ************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_FlushCacheUsrIsSuperuser (void)
|
|
{
|
|
Gbl.Cache.UsrIsSuperuser.UsrCod = -1L;
|
|
Gbl.Cache.UsrIsSuperuser.IsSuperuser = false;
|
|
}
|
|
|
|
bool Usr_CheckIfUsrIsSuperuser (long UsrCod)
|
|
{
|
|
/***** 1. Fast check: Trivial case *****/
|
|
if (UsrCod <= 0)
|
|
return false;
|
|
|
|
/***** 2. Fast check: If cached... *****/
|
|
if (UsrCod == Gbl.Cache.UsrIsSuperuser.UsrCod)
|
|
return Gbl.Cache.UsrIsSuperuser.IsSuperuser;
|
|
|
|
/***** 3. Slow check: If not cached, get if a user is superuser from database *****/
|
|
Gbl.Cache.UsrIsSuperuser.UsrCod = UsrCod;
|
|
Gbl.Cache.UsrIsSuperuser.IsSuperuser = Adm_DB_CheckIfUsrIsSuperuser (UsrCod);
|
|
return Gbl.Cache.UsrIsSuperuser.IsSuperuser;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**************** Check if I can change another user's data ******************/
|
|
/*****************************************************************************/
|
|
|
|
bool Usr_ICanChangeOtherUsrData (const struct Usr_Data *UsrDat)
|
|
{
|
|
/***** I can change my data *****/
|
|
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
|
|
return true;
|
|
|
|
/***** Check if I have permission to see another user's IDs *****/
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
{
|
|
case Rol_TCH:
|
|
/* 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 without password */
|
|
if (!UsrDat->Password[0]) // User has no password (never logged)
|
|
return true;
|
|
|
|
return false;
|
|
case Rol_DEG_ADM:
|
|
case Rol_CTR_ADM:
|
|
case Rol_INS_ADM:
|
|
case Rol_SYS_ADM:
|
|
return Usr_ICanEditOtherUsr (UsrDat);
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/***************** Check if I can edit another user's data *******************/
|
|
/*****************************************************************************/
|
|
|
|
bool Usr_ICanEditOtherUsr (const struct Usr_Data *UsrDat)
|
|
{
|
|
/***** I can edit me *****/
|
|
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
|
|
return true;
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
{
|
|
case Rol_DEG_ADM:
|
|
/* If I am an administrator of current degree,
|
|
I only can edit users from current degree who have accepted */
|
|
if (Deg_CheckIfUsrBelongsToDeg (UsrDat->UsrCod,Gbl.Hierarchy.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 center,
|
|
I only can edit from current center who have accepted */
|
|
if (Ctr_CheckIfUsrBelongsToCtr (UsrDat->UsrCod,Gbl.Hierarchy.Ctr.CtrCod))
|
|
// Center 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 (Ins_CheckIfUsrBelongsToIns (UsrDat->UsrCod,Gbl.Hierarchy.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;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************ Check if I can view the record card of a student ***************/
|
|
/*****************************************************************************/
|
|
|
|
bool Usr_CheckIfICanViewRecordStd (const struct Usr_Data *UsrDat)
|
|
{
|
|
/***** 1. Fast check: Am I logged? *****/
|
|
if (!Gbl.Usrs.Me.Logged)
|
|
return false;
|
|
|
|
/***** 2. Fast check: Is it a valid user code? *****/
|
|
if (UsrDat->UsrCod <= 0)
|
|
return false;
|
|
|
|
/***** 3. Fast check: Is it a course selected? *****/
|
|
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
|
|
return false;
|
|
|
|
/***** 4. Fast check: Is he/she a student? *****/
|
|
if (UsrDat->Roles.InCurrentCrs != Rol_STD)
|
|
return false;
|
|
|
|
/***** 5. Fast check: Am I a system admin? *****/
|
|
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
|
|
return true;
|
|
|
|
/***** 6. Fast check: Do I belong to the current course? *****/
|
|
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
|
|
return false;
|
|
|
|
/***** 7. Fast check: It's me? *****/
|
|
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
|
|
return true;
|
|
|
|
/***** 8. Fast / slow check: Does he/she belong to the current course? *****/
|
|
if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
|
|
return false;
|
|
|
|
/***** 9. Fast / slow check depending on roles *****/
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
{
|
|
case Rol_STD:
|
|
case Rol_NET:
|
|
return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat);
|
|
case Rol_TCH:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************ Check if I can view the record card of a teacher ***************/
|
|
/*****************************************************************************/
|
|
// Teacher here is intended as:
|
|
// - a non-editing teacher
|
|
// - or a teacher
|
|
|
|
bool Usr_CheckIfICanViewRecordTch (struct Usr_Data *UsrDat)
|
|
{
|
|
/***** 1. Fast check: Am I logged? *****/
|
|
if (!Gbl.Usrs.Me.Logged)
|
|
return false;
|
|
|
|
/***** 2. Fast check: Is it a valid user code? *****/
|
|
if (UsrDat->UsrCod <= 0)
|
|
return false;
|
|
|
|
/***** 3. Fast check: Is it a course selected? *****/
|
|
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
|
|
return false;
|
|
|
|
/***** 4. Fast check: Is he/she a non-editing teacher or a teacher? *****/
|
|
return (UsrDat->Roles.InCurrentCrs == Rol_NET ||
|
|
UsrDat->Roles.InCurrentCrs == Rol_TCH);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********* Check if I can view test/exam/match result of another user ********/
|
|
/*****************************************************************************/
|
|
|
|
bool Usr_CheckIfICanViewTstExaMchResult (const struct Usr_Data *UsrDat)
|
|
{
|
|
/***** 1. Fast check: Am I logged? *****/
|
|
if (!Gbl.Usrs.Me.Logged)
|
|
return false;
|
|
|
|
/***** 2. Fast check: Is it a valid user code? *****/
|
|
if (UsrDat->UsrCod <= 0)
|
|
return false;
|
|
|
|
/***** 3. Fast check: Is it a course selected? *****/
|
|
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
|
|
return false;
|
|
|
|
/***** 4. Fast check: Am I a system admin? *****/
|
|
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
|
|
return true;
|
|
|
|
/***** 5. Fast check: Do I belong to the current course? *****/
|
|
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
|
|
return false;
|
|
|
|
/***** 6. Fast check: It's me? *****/
|
|
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
|
|
return true;
|
|
|
|
/***** 7. Fast check: Does he/she belong to the current course? *****/
|
|
if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
|
|
return false;
|
|
|
|
/***** 8. Fast / slow check depending on roles *****/
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
{
|
|
case Rol_NET:
|
|
return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat);
|
|
case Rol_TCH:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********** Check if I can view assigments / works of another user ***********/
|
|
/*****************************************************************************/
|
|
|
|
bool Usr_CheckIfICanViewAsgWrk (const struct Usr_Data *UsrDat)
|
|
{
|
|
/***** 1. Fast check: Am I logged? *****/
|
|
if (!Gbl.Usrs.Me.Logged)
|
|
return false;
|
|
|
|
/***** 2. Fast check: Is it a valid user code? *****/
|
|
if (UsrDat->UsrCod <= 0)
|
|
return false;
|
|
|
|
/***** 3. Fast check: Is it a course selected? *****/
|
|
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
|
|
return false;
|
|
|
|
/***** 4. Fast check: Does he/she belong to the current course? *****/
|
|
// Only users beloging to course can have files in assignments/works
|
|
if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
|
|
return false;
|
|
|
|
/***** 5. Fast check: Am I a system admin? *****/
|
|
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
|
|
return true;
|
|
|
|
/***** 6. Fast check: Do I belong to the current course? *****/
|
|
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
|
|
return false;
|
|
|
|
/***** 7. Fast check: It's me? *****/
|
|
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
|
|
return true;
|
|
|
|
/***** 8. Fast / slow check depending on roles *****/
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
{
|
|
case Rol_NET:
|
|
return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat);
|
|
case Rol_TCH:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************** Check if I can view attendance of another user ***************/
|
|
/*****************************************************************************/
|
|
|
|
bool Usr_CheckIfICanViewAtt (const struct Usr_Data *UsrDat)
|
|
{
|
|
/***** 1. Fast check: Am I logged? *****/
|
|
if (!Gbl.Usrs.Me.Logged)
|
|
return false;
|
|
|
|
/***** 2. Fast check: Is it a valid user code? *****/
|
|
if (UsrDat->UsrCod <= 0)
|
|
return false;
|
|
|
|
/***** 3. Fast check: Is it a course selected? *****/
|
|
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
|
|
return false;
|
|
|
|
/***** 4. Fast check: Am I a system admin? *****/
|
|
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
|
|
return true;
|
|
|
|
/***** 5. Fast check: Do I belong to the current course? *****/
|
|
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
|
|
return false;
|
|
|
|
/***** 6. Fast check: It's me? *****/
|
|
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
|
|
return true;
|
|
|
|
/***** 7. Fast / slow check depending on roles *****/
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
{
|
|
case Rol_NET:
|
|
return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat);
|
|
case Rol_TCH:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******************* Check if I can view a user's agenda *********************/
|
|
/*****************************************************************************/
|
|
|
|
bool Usr_CheckIfICanViewUsrAgenda (struct Usr_Data *UsrDat)
|
|
{
|
|
/***** 1. Fast check: Am I logged? *****/
|
|
if (!Gbl.Usrs.Me.Logged)
|
|
return false;
|
|
|
|
/***** 2. Fast check: It's me? *****/
|
|
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
|
|
return true;
|
|
|
|
/***** 3. Fast check: Am I logged as system admin? *****/
|
|
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
|
|
return true;
|
|
|
|
/***** 4. Slow check: Get if user shares any course with me from database *****/
|
|
return Enr_CheckIfUsrSharesAnyOfMyCrs (UsrDat);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/***************************** Write landing page ****************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_WriteLandingPage (void)
|
|
{
|
|
/***** Form to log in *****/
|
|
Usr_WriteFormLogin (ActLogIn,NULL);
|
|
|
|
/***** Form to go to request the creation of a new account *****/
|
|
Acc_ShowFormGoToRequestNewAccount ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************ Write form for user log out ************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_WriteFormLogout (void)
|
|
{
|
|
/***** Form to change my role *****/
|
|
Usr_ShowFormsLogoutAndRole ();
|
|
|
|
/***** Show help to enrol me *****/
|
|
Hlp_ShowHelpWhatWouldYouLikeToDo ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************* Message and form shown after log out ******************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_Logout (void)
|
|
{
|
|
// extern const char *Txt_The_session_has_been_closed;
|
|
|
|
/***** Confirmation message *****/
|
|
// Ale_ShowFixedAlert (Ale_INFO,Txt_The_session_has_been_closed);
|
|
|
|
/***** Form to log in *****/
|
|
Usr_WriteFormLogin (ActLogIn,NULL);
|
|
|
|
/***** Advertisement about mobile app *****/
|
|
Lay_AdvertisementMobile ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*************************** Put link to log in ******************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_PutLinkToLogin (void)
|
|
{
|
|
extern const char *Txt_Log_in;
|
|
|
|
Lay_PutContextualLinkIconText (ActFrmLogIn,NULL,
|
|
NULL,NULL,
|
|
"sign-in-alt.svg",Ico_GREEN,
|
|
Txt_Log_in,NULL);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************ Write form for user log in *************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_WriteFormLogin (Act_Action_t NextAction,void (*FuncPars) (void))
|
|
{
|
|
extern const char *Hlp_PROFILE_LogIn;
|
|
extern const char *Txt_Log_in;
|
|
extern const char *Txt_User[Usr_NUM_SEXS];
|
|
extern const char *Txt_nick_email_or_ID;
|
|
extern const char *Txt_Password;
|
|
extern const char *Txt_password;
|
|
|
|
/***** Contextual menu *****/
|
|
Mnu_ContextMenuBegin ();
|
|
Acc_PutLinkToCreateAccount (); // Create account
|
|
Pwd_PutLinkToSendNewPasswd (); // Send new password
|
|
Lan_PutLinkToChangeLanguage (); // Change language
|
|
Mnu_ContextMenuEnd ();
|
|
|
|
HTM_DIV_Begin ("class=\"CM\"");
|
|
|
|
/***** Begin form *****/
|
|
Frm_BeginForm (NextAction);
|
|
if (FuncPars)
|
|
FuncPars ();
|
|
|
|
/***** Begin box and table *****/
|
|
Box_BoxTableBegin (NULL,Txt_Log_in,
|
|
NULL,NULL,
|
|
Hlp_PROFILE_LogIn,Box_NOT_CLOSABLE,2);
|
|
|
|
/***** User's ID/nickname *****/
|
|
HTM_DIV_Begin ("class=\"LM\"");
|
|
HTM_LABEL_Begin ("for=\"UsrId\"");
|
|
Ico_PutIcon ("user.svg",Ico_BLACK,
|
|
Txt_User[Usr_SEX_UNKNOWN],"CONTEXT_ICO16x16");
|
|
HTM_LABEL_End ();
|
|
HTM_INPUT_TEXT ("UsrId",Cns_MAX_CHARS_EMAIL_ADDRESS,Gbl.Usrs.Me.UsrIdLogin,
|
|
HTM_DONT_SUBMIT_ON_CHANGE,
|
|
"id=\"UsrId\" size=\"18\" placeholder=\"%s\""
|
|
" class=\"INPUT_%s\" autofocus=\"autofocus\""
|
|
" required=\"required\"",
|
|
Txt_nick_email_or_ID,
|
|
The_GetSuffix ());
|
|
HTM_DIV_End ();
|
|
|
|
/***** User's password *****/
|
|
HTM_DIV_Begin ("class=\"LM\"");
|
|
HTM_LABEL_Begin ("for=\"UsrPwd\"");
|
|
Ico_PutIcon ("key.svg",Ico_BLACK,
|
|
Txt_Password,"CONTEXT_ICO16x16");
|
|
HTM_LABEL_End ();
|
|
HTM_INPUT_PASSWORD ("UsrPwd",Txt_password,NULL,false,
|
|
"id=\"UsrPwd\" class=\"INPUT_%s\"",
|
|
The_GetSuffix ());
|
|
HTM_DIV_End ();
|
|
|
|
/***** End table, send button and end box *****/
|
|
Box_BoxTableWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Log_in);
|
|
|
|
/***** End form *****/
|
|
Frm_EndForm ();
|
|
|
|
HTM_DIV_End ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******************* Write type and name of logged user **********************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_WelcomeUsr (void)
|
|
{
|
|
extern const char *Ico_IconSetId[Ico_NUM_ICON_SETS];
|
|
extern const unsigned Txt_Current_CGI_SWAD_Language;
|
|
extern const char *Txt_NEW_YEAR_GREETING;
|
|
extern const char *Txt_Happy_birthday_X;
|
|
extern const char *Txt_Please_check_your_email_address;
|
|
extern const char *Txt_Check;
|
|
extern const char *Txt_Switching_to_LANGUAGE[1 + Lan_NUM_LANGUAGES];
|
|
char URLIconSet[PATH_MAX + 1];
|
|
unsigned CurrentDay = Dat_GetCurrentDay ();
|
|
unsigned CurrentMonth = Dat_GetCurrentMonth ();
|
|
unsigned CurrentYear = Dat_GetCurrentYear ();
|
|
|
|
if (Gbl.Usrs.Me.Logged)
|
|
{
|
|
if (Gbl.Usrs.Me.UsrDat.Prefs.Language == Txt_Current_CGI_SWAD_Language)
|
|
{
|
|
if (Gbl.Usrs.Me.UsrDat.FrstName[0])
|
|
{
|
|
/***** New year greeting *****/
|
|
if (CurrentDay == 1 && CurrentMonth == 1)
|
|
Ale_ShowAlert (Ale_INFO,Txt_NEW_YEAR_GREETING,
|
|
CurrentYear);
|
|
|
|
/***** Birthday congratulation *****/
|
|
if (Gbl.Usrs.Me.UsrDat.Birthday.Day == CurrentDay &&
|
|
Gbl.Usrs.Me.UsrDat.Birthday.Month == CurrentMonth)
|
|
if (Usr_DB_CheckIfMyBirthdayHasNotBeenCongratulated ())
|
|
{
|
|
/* Mark my birthday as already congratulated */
|
|
Usr_DB_DeleteOldBirthdays ();
|
|
Usr_DB_MarkMyBirthdayAsCongratulated ();
|
|
|
|
/* Begin alert */
|
|
Ale_ShowAlertAndButton1 (Ale_INFO,Txt_Happy_birthday_X,
|
|
Gbl.Usrs.Me.UsrDat.FrstName);
|
|
|
|
/* Show cake icon */
|
|
snprintf (URLIconSet,sizeof (URLIconSet),"%s/%s",
|
|
Cfg_URL_ICON_SETS_PUBLIC,Ico_IconSetId[Gbl.Prefs.IconSet]);
|
|
HTM_IMG (URLIconSet,"birthday-cake.svg",NULL,
|
|
"class=\"ICO160x160\"");
|
|
|
|
/* End alert */
|
|
Ale_ShowAlertAndButton2 (ActUnk,NULL,NULL,
|
|
NULL,NULL,
|
|
Btn_NO_BUTTON,NULL);
|
|
}
|
|
|
|
/***** Alert with button to check email address *****/
|
|
if ( Gbl.Usrs.Me.UsrDat.Email[0] &&
|
|
!Gbl.Usrs.Me.UsrDat.EmailConfirmed) // Email needs to be confirmed
|
|
Ale_ShowAlertAndButton (ActFrmMyAcc,NULL,NULL,
|
|
NULL,NULL,
|
|
Btn_CONFIRM_BUTTON,Txt_Check,
|
|
Ale_WARNING,Txt_Please_check_your_email_address);
|
|
}
|
|
|
|
/***** Games tool *****/
|
|
/*
|
|
Ale_ShowAlert (Ale_INFO,
|
|
"Herramienta <a href=\"https://github.com/acanas/swad-core/wiki/ASSESSMENT.Games.es\" target=\"_blank\">"
|
|
"Evaluación > Juegos</a><br />"
|
|
"<br />"
|
|
"Imagen de la izquierda: pantalla proyectada en el aula por el profesor.<br />"
|
|
"Imagen de la derecha: pantalla del estudiante en su móvil."
|
|
"<br />"
|
|
"<br />"
|
|
"<img src=\"/img/juego.png\" alt=\"Juegos\" style=\"width:100%%\">");
|
|
*/
|
|
|
|
/***** Institutional video *****/
|
|
/*
|
|
Ale_ShowAlert (Ale_INFO,
|
|
"<a href=\"https://abierta.ugr.es/creative_commons/\" target=\"_blank\">"
|
|
"Curso MOOC LICENCIAS CREATIVE COMMONS Y OER</a><br />"
|
|
"Reconocimiento de 1 crédito por actividades universitarias<br />"
|
|
"¡Últimos días!<br />"
|
|
"<br />"
|
|
"<video style=\"width:480px; height:270px;\""
|
|
" poster=\"/img/abierta-ugr-creative-commons1280x720.jpg\""
|
|
" controls>"
|
|
"<source src=\"https://abierta.ugr.es/creative_commons/promo_cc.mp4\""
|
|
" type=\"video/mp4\">"
|
|
"<img src=\"/img/abierta-ugr-creative-commons1280x720.jpg\""
|
|
" class=\"img-responsive\""
|
|
" alt=\"Responsive image\">"
|
|
"</video>");
|
|
*/
|
|
|
|
/***** Show the global announcements I have not seen *****/
|
|
Ann_ShowMyAnnouncementsNotMarkedAsSeen ();
|
|
}
|
|
else
|
|
/* The current language is not my preferred language
|
|
==> change automatically to my language */
|
|
Ale_ShowAlert (Ale_INFO,Txt_Switching_to_LANGUAGE[Gbl.Usrs.Me.UsrDat.Prefs.Language]);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************ Write birthday string to insert or update database *************/
|
|
/*****************************************************************************/
|
|
// It can include start and ending apostrophes
|
|
|
|
void Usr_CreateBirthdayStrDB (const struct Usr_Data *UsrDat,
|
|
char BirthdayStrDB[Usr_BIRTHDAY_STR_DB_LENGTH + 1])
|
|
{
|
|
char BirthdayStrTmp[1 + Cns_MAX_DECIMAL_DIGITS_UINT +
|
|
1 + Cns_MAX_DECIMAL_DIGITS_UINT +
|
|
1 + Cns_MAX_DECIMAL_DIGITS_UINT +
|
|
1 + 1];
|
|
|
|
if (UsrDat->Birthday.Year == 0 ||
|
|
UsrDat->Birthday.Month == 0 ||
|
|
UsrDat->Birthday.Day == 0)
|
|
Str_Copy (BirthdayStrDB,"NULL",Usr_BIRTHDAY_STR_DB_LENGTH); // Without apostrophes
|
|
else
|
|
{
|
|
sprintf (BirthdayStrTmp,"'%04u-%02u-%02u'", // With apostrophes
|
|
UsrDat->Birthday.Year,
|
|
UsrDat->Birthday.Month,
|
|
UsrDat->Birthday.Day);
|
|
Str_Copy (BirthdayStrDB,BirthdayStrTmp,Usr_BIRTHDAY_STR_DB_LENGTH);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************* Filter some user's data ***************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_FilterUsrBirthday (struct Dat_Date *Birthday)
|
|
{
|
|
unsigned CurrentYear = Dat_GetCurrentYear ();
|
|
|
|
/***** Fix birthday *****/
|
|
if (Birthday->Year < CurrentYear - 99 ||
|
|
Birthday->Year > CurrentYear - 16)
|
|
Birthday->Year =
|
|
Birthday->Month =
|
|
Birthday->Day = 0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************ Write form for user log in *************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_PutFormLogIn (void)
|
|
{
|
|
Frm_BeginForm (ActFrmLogIn);
|
|
Ico_PutIconLink ("sign-in-alt.svg",Ico_WHITE,ActFrmLogIn);
|
|
Frm_EndForm ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******************* Write type and name of logged user **********************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_WriteLoggedUsrHead (void)
|
|
{
|
|
extern const char *Txt_Role;
|
|
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
|
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
|
|
{
|
|
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC18x24",
|
|
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE18x24",
|
|
[PhoSha_SHAPE_OVAL ] = "PHOTOO18x24",
|
|
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR18x24",
|
|
};
|
|
unsigned NumAvailableRoles = Rol_GetNumAvailableRoles ();
|
|
char *ClassSelect;
|
|
|
|
HTM_DIV_Begin ("class=\"HEAD_USR USR_%s\"",The_GetSuffix ());
|
|
|
|
/***** User's role *****/
|
|
if (NumAvailableRoles == 1)
|
|
{
|
|
Frm_BeginForm (ActFrmRolSes);
|
|
HTM_BUTTON_Submit_Begin (Txt_Role,"class=\"BT_LINK\"");
|
|
HTM_Txt (Txt_ROLES_SINGUL_Abc[Gbl.Usrs.Me.Role.Logged][Gbl.Usrs.Me.UsrDat.Sex]);
|
|
HTM_BUTTON_End ();
|
|
Frm_EndForm ();
|
|
|
|
HTM_Colon ();
|
|
}
|
|
else
|
|
{
|
|
if (asprintf (&ClassSelect,"SEL_ROLE INPUT_%s",
|
|
The_GetSuffix ()) < 0)
|
|
Err_NotEnoughMemoryExit ();
|
|
Rol_PutFormToChangeMyRole (ClassSelect);
|
|
free (ClassSelect);
|
|
}
|
|
HTM_NBSP ();
|
|
|
|
/***** Show my photo *****/
|
|
Pho_ShowUsrPhotoIfAllowed (&Gbl.Usrs.Me.UsrDat,
|
|
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
|
|
|
|
/***** User's name *****/
|
|
if (Gbl.Usrs.Me.UsrDat.FrstName[0])
|
|
HTM_TxtF (" %s",Gbl.Usrs.Me.UsrDat.FrstName);
|
|
|
|
HTM_DIV_End ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*************** Put a form to close current session (log out) ***************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_PutFormLogOut (void)
|
|
{
|
|
Frm_BeginForm (ActLogOut);
|
|
Ico_PutIconLink ("sign-out-alt.svg",Ico_WHITE,ActLogOut);
|
|
Frm_EndForm ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******* Get parameter with my plain user's ID or nickname from a form *******/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_GetParUsrIdLogin (void)
|
|
{
|
|
Par_GetParText ("UsrId",Gbl.Usrs.Me.UsrIdLogin,sizeof (Gbl.Usrs.Me.UsrIdLogin) - 1);
|
|
// Users' IDs are always stored internally without leading zeros
|
|
Str_RemoveLeadingZeros (Gbl.Usrs.Me.UsrIdLogin);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******* Get parameter user's identificator of other user from a form ********/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_GetParOtherUsrIDNickOrEMail (void)
|
|
{
|
|
/***** Get parameter with the plain user's ID, @nick or email of another user *****/
|
|
Par_GetParText ("OtherUsrIDNickOrEMail",
|
|
Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail,
|
|
sizeof (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail) - 1);
|
|
|
|
// If it's a user's ID (if does not contain '@')
|
|
if (strchr (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail,(int) '@') != NULL) // '@' not found
|
|
{
|
|
// Users' IDs are always stored internally in capitals and without leading zeros
|
|
Str_RemoveLeadingZeros (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
|
|
// Str_ConvertToUpperText (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******* Get parameter user's identificator of other user from a form ********/
|
|
/******* and get user's data ********/
|
|
/*****************************************************************************/
|
|
// Returns the number of users for a given ID, @nick or email
|
|
|
|
unsigned Usr_GetParOtherUsrIDNickOrEMailAndGetUsrCods (struct Usr_ListUsrCods *ListUsrCods)
|
|
{
|
|
extern const char *Txt_The_ID_nickname_or_email_X_is_not_valid;
|
|
bool Wrong = false;
|
|
|
|
/***** Reset default list of users' codes *****/
|
|
ListUsrCods->NumUsrs = 0;
|
|
ListUsrCods->Lst = NULL;
|
|
|
|
/***** Get parameter with the plain user's ID, @nick or email of another user *****/
|
|
Usr_GetParOtherUsrIDNickOrEMail ();
|
|
|
|
/***** Check if it's an ID, a nickname or an email address *****/
|
|
if (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail[0])
|
|
{
|
|
if (Nck_CheckIfNickWithArrIsValid (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail)) // 1: It's a nickname
|
|
{
|
|
if ((Gbl.Usrs.Other.UsrDat.UsrCod = Nck_GetUsrCodFromNickname (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail)) > 0)
|
|
{
|
|
ListUsrCods->NumUsrs = 1; // One user found
|
|
Usr_AllocateListUsrCods (ListUsrCods);
|
|
ListUsrCods->Lst[0] = Gbl.Usrs.Other.UsrDat.UsrCod;
|
|
}
|
|
}
|
|
else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail)) // 2: It's an email
|
|
{
|
|
if ((Gbl.Usrs.Other.UsrDat.UsrCod = Mai_DB_GetUsrCodFromEmail (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail)) > 0)
|
|
{
|
|
ListUsrCods->NumUsrs = 1; // One user found
|
|
Usr_AllocateListUsrCods (ListUsrCods);
|
|
ListUsrCods->Lst[0] = Gbl.Usrs.Other.UsrDat.UsrCod;
|
|
}
|
|
}
|
|
else // 3: It's not a nickname nor email
|
|
{
|
|
// Users' IDs are always stored internally in capitals and without leading zeros
|
|
Str_RemoveLeadingZeros (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
|
|
if (ID_CheckIfUsrIDIsValid (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail))
|
|
{
|
|
/* Allocate space for the list */
|
|
ID_ReallocateListIDs (&Gbl.Usrs.Other.UsrDat,1);
|
|
|
|
Str_Copy (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID,
|
|
Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail,
|
|
sizeof (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID) - 1);
|
|
Str_ConvertToUpperText (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID);
|
|
|
|
/* Check if user's ID exists in database */
|
|
ID_GetListUsrCodsFromUsrID (&Gbl.Usrs.Other.UsrDat,NULL,ListUsrCods,false);
|
|
}
|
|
else // Not a valid user's nickname, email or ID
|
|
Wrong = true;
|
|
}
|
|
}
|
|
else // Empty string
|
|
Wrong = true;
|
|
|
|
if (Wrong)
|
|
/***** String is not a valid user's nickname, email or ID *****/
|
|
Ale_ShowAlert (Ale_WARNING,Txt_The_ID_nickname_or_email_X_is_not_valid,
|
|
Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
|
|
|
|
return ListUsrCods->NumUsrs;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********* Put hidden parameter encrypted user's code of other user **********/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_PutParMyUsrCodEncrypted (void *EncryptedUsrCod)
|
|
{
|
|
Usr_PutParUsrCodEncrypted ((const char *) EncryptedUsrCod);
|
|
}
|
|
|
|
void Usr_PutParOtherUsrCodEncrypted (void *EncryptedUsrCod)
|
|
{
|
|
Usr_PutParUsrCodEncrypted ((const char *) EncryptedUsrCod);
|
|
}
|
|
|
|
void Usr_PutParUsrCodEncrypted (const char EncryptedUsrCod[Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64 + 1])
|
|
{
|
|
Par_PutParString (NULL,"OtherUsrCod",EncryptedUsrCod);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********* Get hidden parameter encrypted user's code of other user **********/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_GetParOtherUsrCodEncrypted (struct Usr_Data *UsrDat)
|
|
{
|
|
Par_GetParText ("OtherUsrCod",UsrDat->EnUsrCod,
|
|
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
|
|
if (UsrDat->EnUsrCod[0]) // If parameter exists...
|
|
{
|
|
Usr_GetUsrCodFromEncryptedUsrCod (UsrDat);
|
|
if (UsrDat->UsrCod <= 0) // Check is user's code is valid
|
|
Err_WrongUserExit ();
|
|
}
|
|
else
|
|
UsrDat->UsrCod = -1L;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********* Get hidden parameter encrypted user's code of other user **********/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_GetParOtherUsrCodEncryptedAndGetListIDs (void)
|
|
{
|
|
Usr_GetParOtherUsrCodEncrypted (&Gbl.Usrs.Other.UsrDat);
|
|
if (Gbl.Usrs.Other.UsrDat.UsrCod > 0) // If parameter exists...
|
|
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Other.UsrDat);
|
|
else // Parameter does not exist
|
|
{
|
|
Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail[0] = '\0';
|
|
Gbl.Usrs.Other.UsrDat.IDs.Num = 0;
|
|
Gbl.Usrs.Other.UsrDat.IDs.List = NULL;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*** Get parameter encrypted user's code of other user and get user's data ***/
|
|
/*****************************************************************************/
|
|
// Return true if user exists
|
|
|
|
bool Usr_GetParOtherUsrCodEncryptedAndGetUsrData (void)
|
|
{
|
|
/***** Get parameter with encrypted user's code *****/
|
|
Usr_GetParOtherUsrCodEncryptedAndGetListIDs ();
|
|
|
|
/***** Check if user exists and get her/his data *****/
|
|
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,
|
|
Usr_DONT_GET_PREFS,
|
|
Usr_GET_ROLE_IN_CURRENT_CRS))
|
|
// Existing user
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/** Check and get user data from session, from internal or external login... */
|
|
/*****************************************************************************/
|
|
|
|
void Usr_ChkUsrAndGetUsrData (void)
|
|
{
|
|
extern const char *Txt_The_session_has_expired;
|
|
struct
|
|
{
|
|
bool PutForm;
|
|
Act_Action_t Action;
|
|
void (*FuncPars) (void);
|
|
} FormLogin =
|
|
{
|
|
false,
|
|
ActLogIn,
|
|
NULL
|
|
};
|
|
Act_Action_t Action;
|
|
|
|
if (Gbl.Session.HasBeenDisconnected)
|
|
{
|
|
if (!Gbl.Action.UsesAJAX)
|
|
{
|
|
Gbl.Action.Act = ActLogOut;
|
|
Tab_SetCurrentTab ();
|
|
Ale_ShowAlert (Ale_WARNING,Txt_The_session_has_expired);
|
|
FormLogin.PutForm = true;
|
|
}
|
|
}
|
|
else // !Gbl.Session.HasBeenDisconnected
|
|
{
|
|
/***** Check user and get user's data *****/
|
|
if (Gbl.Action.Act == ActCreUsrAcc)
|
|
{
|
|
/***** Create my new account and login *****/
|
|
if (Acc_CreateMyNewAccountAndLogIn ()) // User logged in
|
|
{
|
|
Gbl.Usrs.Me.Logged = true;
|
|
Usr_SetMyPrefsAndRoles ();
|
|
|
|
Act_AdjustCurrentAction ();
|
|
Ses_CreateSession ();
|
|
|
|
/* Set settings from current IP */
|
|
Set_SetSettingsFromIP ();
|
|
|
|
/* Send message via email to confirm the new email address */
|
|
Mai_SendMailMsgToConfirmEmail ();
|
|
Ale_ShowAlerts (NULL); // Show alert after sending email confirmation
|
|
}
|
|
}
|
|
else // Gbl.Action.Act != ActCreUsrAcc
|
|
{
|
|
/***** Check user and get user's data *****/
|
|
if (Gbl.Session.IsOpen)
|
|
{
|
|
if (Usr_ChkUsrAndGetUsrDataFromSession ()) // User logged in
|
|
{
|
|
Gbl.Usrs.Me.Logged = true;
|
|
|
|
Usr_SetMyPrefsAndRoles ();
|
|
|
|
if (Gbl.Action.IsAJAXAutoRefresh) // If refreshing ==> don't refresh LastTime in session
|
|
Ses_DB_UpdateSessionLastRefresh ();
|
|
else
|
|
{
|
|
Act_AdjustCurrentAction ();
|
|
Ses_DB_UpdateSession ();
|
|
Con_DB_UpdateMeInConnectedList ();
|
|
}
|
|
}
|
|
else
|
|
FormLogin.PutForm = true;
|
|
}
|
|
else if (Gbl.Action.Act == ActLogIn ||
|
|
Gbl.Action.Act == ActLogInUsrAgd) // Login using @nickname, email or ID from form
|
|
{
|
|
if (Usr_ChkUsrAndGetUsrDataFromDirectLogin ()) // User logged in
|
|
{
|
|
Gbl.Usrs.Me.Logged = true;
|
|
Usr_SetMyPrefsAndRoles ();
|
|
|
|
Act_AdjustCurrentAction ();
|
|
Ses_CreateSession ();
|
|
|
|
Set_SetSettingsFromIP (); // Set settings from current IP
|
|
}
|
|
else
|
|
{
|
|
FormLogin.PutForm = true;
|
|
if (Gbl.Action.Act == ActLogInUsrAgd)
|
|
{
|
|
FormLogin.Action = ActLogInUsrAgd;
|
|
FormLogin.FuncPars = Agd_PutParAgd;
|
|
}
|
|
}
|
|
}
|
|
else if (Gbl.Action.Act == ActLogInNew) // Empty account without password, login using encrypted user's code
|
|
{
|
|
/***** Get user's data *****/
|
|
Usr_GetParOtherUsrCodEncrypted (&Gbl.Usrs.Me.UsrDat);
|
|
Usr_GetUsrCodFromEncryptedUsrCod (&Gbl.Usrs.Me.UsrDat);
|
|
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,
|
|
Usr_GET_PREFS,
|
|
Usr_GET_ROLE_IN_CURRENT_CRS))
|
|
{
|
|
// User logged in
|
|
Gbl.Usrs.Me.Logged = true;
|
|
Usr_SetMyPrefsAndRoles ();
|
|
|
|
Act_AdjustCurrentAction ();
|
|
Ses_CreateSession ();
|
|
|
|
Set_SetSettingsFromIP (); // Set settings from current IP
|
|
}
|
|
else
|
|
FormLogin.PutForm = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***** If session disconnected or error in login, show form to login *****/
|
|
if (FormLogin.PutForm)
|
|
{
|
|
Usr_WriteFormLogin (FormLogin.Action,FormLogin.FuncPars);
|
|
Err_ShowErrorAndExit (NULL);
|
|
}
|
|
|
|
/***** Adjust tab and action *****/
|
|
if (!Gbl.Action.UsesAJAX)
|
|
{
|
|
if (!Gbl.Usrs.Me.Logged && // No user logged...
|
|
Gbl.Action.Act == ActUnk) // ...and unknown action
|
|
Act_AdjustActionWhenNoUsrLogged ();
|
|
|
|
/***** When I change to another tab, go to:
|
|
- my last action in that tab if it is known, or
|
|
- the first option allowed *****/
|
|
if (Gbl.Action.Act == ActMnu)
|
|
{
|
|
/* Get my last action in current tab */
|
|
Action = (Gbl.Usrs.Me.Logged) ? MFU_GetMyLastActionInCurrentTab () :
|
|
ActUnk;
|
|
if (Action == ActUnk)
|
|
/* Get the first option allowed */
|
|
Action = Mnu_GetFirstActionAvailableInCurrentTab ();
|
|
|
|
Gbl.Action.Act = (Action == ActUnk) ? ((Gbl.Usrs.Me.Logged) ? ActSeeGblTL : // Default action if logged
|
|
ActFrmLogIn) : // Default action if not logged
|
|
Action;
|
|
Tab_SetCurrentTab ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************** Check user and get user's data when direct login *************/
|
|
/*****************************************************************************/
|
|
// Returns true if user logged in successfully
|
|
// Returns false if user not logged in
|
|
|
|
static bool Usr_ChkUsrAndGetUsrDataFromDirectLogin (void)
|
|
{
|
|
struct Usr_ListUsrCods ListUsrCods;
|
|
bool PasswordCorrect = false;
|
|
|
|
/***** Check if user typed anything *****/
|
|
if (!Gbl.Usrs.Me.UsrIdLogin)
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
if (!Gbl.Usrs.Me.UsrIdLogin[0])
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
|
|
/***** Check if user has typed his user's ID, his nickname or his email address *****/
|
|
if (Nck_CheckIfNickWithArrIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 1: It's a nickname
|
|
{
|
|
// User is trying to log using his/her nickname
|
|
if ((Gbl.Usrs.Me.UsrDat.UsrCod = Nck_GetUsrCodFromNickname (Gbl.Usrs.Me.UsrIdLogin)) <= 0)
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
}
|
|
else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 2: It's an email
|
|
{
|
|
// User is trying to log using his/her email
|
|
if ((Gbl.Usrs.Me.UsrDat.UsrCod = Mai_DB_GetUsrCodFromEmail (Gbl.Usrs.Me.UsrIdLogin)) <= 0)
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
}
|
|
else // 3: It's not a nickname nor email
|
|
{
|
|
// Users' IDs are always stored internally in capitals and without leading zeros
|
|
Str_RemoveLeadingZeros (Gbl.Usrs.Me.UsrIdLogin);
|
|
if (ID_CheckIfUsrIDIsValid (Gbl.Usrs.Me.UsrIdLogin))
|
|
{
|
|
/***** Allocate space for the list *****/
|
|
ID_ReallocateListIDs (&Gbl.Usrs.Me.UsrDat,1);
|
|
|
|
Str_Copy (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID,Gbl.Usrs.Me.UsrIdLogin,
|
|
sizeof (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID) - 1);
|
|
Str_ConvertToUpperText (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID);
|
|
|
|
/* Check if user's ID exists in database, and get user's data */
|
|
if (ID_GetListUsrCodsFromUsrID (&Gbl.Usrs.Me.UsrDat,
|
|
Gbl.Usrs.Me.LoginEncryptedPassword, // Check password
|
|
&ListUsrCods,false))
|
|
{
|
|
if (ListUsrCods.NumUsrs == 1)
|
|
{
|
|
/* Free memory used for list of users' codes found for this ID */
|
|
Usr_FreeListUsrCods (&ListUsrCods);
|
|
|
|
PasswordCorrect = true;
|
|
}
|
|
else // ListUsrCods.NumUsrs > 1
|
|
{
|
|
/* Free memory used for list of users' codes found for this ID */
|
|
Usr_FreeListUsrCods (&ListUsrCods);
|
|
|
|
Usr_ShowAlertThereAreMoreThanOneUsr ();
|
|
return false;
|
|
}
|
|
}
|
|
else if (ID_GetListUsrCodsFromUsrID (&Gbl.Usrs.Me.UsrDat,
|
|
NULL, // Don't check password
|
|
&ListUsrCods,false))
|
|
{
|
|
if (ListUsrCods.NumUsrs == 1)
|
|
{
|
|
/* Free memory used for list of users' codes found for this ID */
|
|
Usr_FreeListUsrCods (&ListUsrCods);
|
|
|
|
if (Pwd_CheckPendingPassword ())
|
|
{
|
|
Pwd_AssignMyPendingPasswordToMyCurrentPassword ();
|
|
PasswordCorrect = true;
|
|
}
|
|
else
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
}
|
|
else // ListUsrCods.NumUsrs > 1
|
|
{
|
|
/* Free memory used for list of users' codes found for this ID */
|
|
Usr_FreeListUsrCods (&ListUsrCods);
|
|
|
|
Usr_ShowAlertThereAreMoreThanOneUsr ();
|
|
return false;
|
|
}
|
|
}
|
|
else // No users found for this ID
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
}
|
|
else // String is not a valid user's nickname, email or ID
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/***** Get user's data *****/
|
|
Usr_GetAllUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,
|
|
Usr_GET_PREFS,
|
|
Usr_GET_ROLE_IN_CURRENT_CRS);
|
|
|
|
/***** Check password *****/
|
|
/* Check user's password:
|
|
is the encrypted password typed by user or coming from the session
|
|
the same as that stored in database? */
|
|
if (!PasswordCorrect)
|
|
PasswordCorrect = Pwd_CheckCurrentPassword ();
|
|
|
|
if (!PasswordCorrect) // If my password is not correct...
|
|
{
|
|
if (Pwd_CheckPendingPassword ())
|
|
Pwd_AssignMyPendingPasswordToMyCurrentPassword ();
|
|
else
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******** Check user and get user's data when the session is open ************/
|
|
/*****************************************************************************/
|
|
|
|
static bool Usr_ChkUsrAndGetUsrDataFromSession (void)
|
|
{
|
|
/***** Session is open and user's code is get from session *****/
|
|
Gbl.Usrs.Me.UsrDat.UsrCod = Gbl.Session.UsrCod;
|
|
|
|
/* Check if user exists in database, and get his/her data */
|
|
if (!Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,
|
|
Usr_GET_PREFS,
|
|
Usr_GET_ROLE_IN_CURRENT_CRS))
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
|
|
/* Check user's password:
|
|
the encrypted password typed by user or coming from the session
|
|
is the same as the stored in database? */
|
|
if (!Pwd_CheckCurrentPassword ()) // If my password is not correct...
|
|
{
|
|
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/** Show alert indicating that user does not exists or password is incorrect */
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_ShowAlertUsrDoesNotExistsOrWrongPassword (void)
|
|
{
|
|
extern const char *Txt_The_user_does_not_exist_or_password_is_incorrect;
|
|
|
|
Ale_ShowAlert (Ale_WARNING,Txt_The_user_does_not_exist_or_password_is_incorrect);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/****** Show alert indicating that more than one user share the same ID ******/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_ShowAlertThereAreMoreThanOneUsr (void)
|
|
{
|
|
extern const char *Txt_There_are_more_than_one_user_with_the_ID_X_Please_type_a_nick_or_email;
|
|
|
|
Gbl.Action.Act = ActFrmLogIn;
|
|
Tab_SetCurrentTab ();
|
|
Ale_ShowAlert (Ale_WARNING,Txt_There_are_more_than_one_user_with_the_ID_X_Please_type_a_nick_or_email,
|
|
Gbl.Usrs.Me.UsrIdLogin);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************** Set my settings and my roles *************************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_SetMyPrefsAndRoles (void)
|
|
{
|
|
extern const char *Ico_IconSetId[Ico_NUM_ICON_SETS];
|
|
struct Sch_Search *Search;
|
|
bool GetRoleAndActionFromLastData;
|
|
Act_Action_t LastSuperAction;
|
|
bool JustAfterLogin = Gbl.Action.Act == ActLogIn ||
|
|
Gbl.Action.Act == ActLogInLan ||
|
|
Gbl.Action.Act == ActLogInNew ||
|
|
Gbl.Action.Act == ActAnnSee;
|
|
|
|
// In this point I am logged
|
|
|
|
/***** Set my language if unknown *****/
|
|
if (Gbl.Usrs.Me.UsrDat.Prefs.Language == Lan_LANGUAGE_UNKNOWN) // I have not chosen language
|
|
Lan_UpdateMyLanguageToCurrentLanguage (); // Update my language in database
|
|
|
|
/***** Set settings from my settings *****/
|
|
Gbl.Prefs.FirstDayOfWeek = Gbl.Usrs.Me.UsrDat.Prefs.FirstDayOfWeek;
|
|
Gbl.Prefs.DateFormat = Gbl.Usrs.Me.UsrDat.Prefs.DateFormat;
|
|
Gbl.Prefs.IconSet = Gbl.Usrs.Me.UsrDat.Prefs.IconSet;
|
|
Gbl.Prefs.Menu = Gbl.Usrs.Me.UsrDat.Prefs.Menu;
|
|
Gbl.Prefs.Theme = Gbl.Usrs.Me.UsrDat.Prefs.Theme;
|
|
Gbl.Prefs.SideCols = Gbl.Usrs.Me.UsrDat.Prefs.SideCols;
|
|
Gbl.Prefs.PhotoShape = Gbl.Usrs.Me.UsrDat.Prefs.PhotoShape;
|
|
|
|
/***** Construct the path to my directory *****/
|
|
Usr_ConstructPathUsr (Gbl.Usrs.Me.UsrDat.UsrCod,Gbl.Usrs.Me.PathDir);
|
|
|
|
/***** Check if my photo exists and create a link to it ****/
|
|
Gbl.Usrs.Me.MyPhotoExists = Pho_BuildLinkToPhoto (&Gbl.Usrs.Me.UsrDat,Gbl.Usrs.Me.PhotoURL);
|
|
|
|
/***** Get my last data *****/
|
|
Usr_GetMyLastData ();
|
|
if (JustAfterLogin) // If I just logged in...
|
|
{
|
|
/***** WhatToSearch is stored in session,
|
|
but in login it is got from user's last data *****/
|
|
Search = Sch_GetSearch ();
|
|
Search->WhatToSearch = Gbl.Usrs.Me.UsrLast.WhatToSearch;
|
|
|
|
/***** Location in hierarchy and role are stored in session,
|
|
but in login the are got from user's last data *****/
|
|
if (Gbl.Hierarchy.Level == HieLvl_SYS) // No country selected
|
|
{
|
|
/***** Copy last hierarchy to current hierarchy *****/
|
|
Hie_SetHierarchyFromUsrLastHierarchy ();
|
|
|
|
/* Course may have changed ==> get my role in current course again */
|
|
if (Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected
|
|
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs = Rol_GetMyRoleInCrs (Gbl.Hierarchy.Crs.CrsCod);
|
|
|
|
// role and action will be got from last data
|
|
GetRoleAndActionFromLastData = true;
|
|
}
|
|
else // Country (and may be institution, center, degree or course) selected
|
|
// Role and action will be got from last data
|
|
// only if I am in the same hierarchy location that the stored one
|
|
GetRoleAndActionFromLastData =
|
|
(Gbl.Hierarchy.Level == Gbl.Usrs.Me.UsrLast.LastHie.Scope && // The same scope...
|
|
Gbl.Hierarchy.Cod == Gbl.Usrs.Me.UsrLast.LastHie.Cod); // ...and code in hierarchy
|
|
|
|
/***** Get role and action from last data *****/
|
|
if (GetRoleAndActionFromLastData)
|
|
{
|
|
/* Get role from last data */
|
|
Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrLast.LastRole;
|
|
|
|
/* Last action is really got only if last access is recent */
|
|
if (Gbl.Usrs.Me.UsrLast.LastTime >= Dat_GetStartExecutionTimeUTC () -
|
|
Cfg_MAX_TIME_TO_REMEMBER_LAST_ACTION_ON_LOGIN)
|
|
{
|
|
/* Get action from last data */
|
|
LastSuperAction = Act_GetSuperAction (Gbl.Usrs.Me.UsrLast.LastAct);
|
|
if (LastSuperAction != ActUnk)
|
|
{
|
|
Gbl.Action.Act = LastSuperAction;
|
|
Tab_SetCurrentTab ();
|
|
}
|
|
}
|
|
/* If action is not set to last action,
|
|
it will be set later to a default action */
|
|
}
|
|
}
|
|
|
|
/***** Set my roles *****/
|
|
Rol_SetMyRoles ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************** Show forms to log out and to change my role ******************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_ShowFormsLogoutAndRole (void)
|
|
{
|
|
extern const char *Hlp_PROFILE_Session_role;
|
|
extern const char *Txt_Session;
|
|
extern const char *Txt_Role;
|
|
extern const char *Txt_You_are_now_LOGGED_IN_as_X;
|
|
extern const char *Txt_logged[Usr_NUM_SEXS];
|
|
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
|
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
|
char *ClassSelect;
|
|
|
|
/***** Write message with my new logged role *****/
|
|
if (Gbl.Usrs.Me.Role.HasChanged)
|
|
Ale_ShowAlert (Ale_SUCCESS,Txt_You_are_now_LOGGED_IN_as_X,
|
|
Txt_logged[Gbl.Usrs.Me.UsrDat.Sex],
|
|
Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.Role.Logged][Gbl.Usrs.Me.UsrDat.Sex]);
|
|
|
|
/***** Begin box *****/
|
|
Box_BoxBegin (NULL,Txt_Session,
|
|
Usr_PutLinkToLogOut,NULL,
|
|
Hlp_PROFILE_Session_role,Box_NOT_CLOSABLE);
|
|
|
|
/***** Put a form to change my role *****/
|
|
if (Rol_GetNumAvailableRoles () == 1)
|
|
{
|
|
HTM_SPAN_Begin ("class=\"DAT_%s\"",The_GetSuffix ());
|
|
HTM_TxtColonNBSP (Txt_Role);
|
|
HTM_SPAN_End ();
|
|
|
|
HTM_SPAN_Begin ("class=\"DAT_STRONG_%s BOLD\"",
|
|
The_GetSuffix ());
|
|
HTM_Txt (Txt_ROLES_SINGUL_Abc[Gbl.Usrs.Me.Role.Logged][Gbl.Usrs.Me.UsrDat.Sex]);
|
|
HTM_SPAN_End ();
|
|
}
|
|
else
|
|
{
|
|
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
|
|
HTM_TxtColonNBSP (Txt_Role);
|
|
if (asprintf (&ClassSelect,"INPUT_%s",
|
|
The_GetSuffix ()) < 0)
|
|
Err_NotEnoughMemoryExit ();
|
|
Rol_PutFormToChangeMyRole (ClassSelect);
|
|
free (ClassSelect);
|
|
HTM_LABEL_End ();
|
|
}
|
|
|
|
/***** End box *****/
|
|
Box_BoxEnd ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************** Put an icon (form) to close the current session **************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_PutLinkToLogOut (__attribute__((unused)) void *Args)
|
|
{
|
|
Lay_PutContextualLinkOnlyIcon (ActLogOut,NULL,
|
|
NULL,NULL,
|
|
"sign-out-alt.svg",Ico_RED);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******* Check a user's code and get all user's data from user's code ********/
|
|
/*****************************************************************************/
|
|
// Input: UsrDat->UsrCod must hold a valid user code
|
|
// Output: When true ==> UsrDat will hold all user's data
|
|
// When false ==> UsrDat is reset, except user's code
|
|
|
|
bool Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (struct Usr_Data *UsrDat,
|
|
Usr_GetPrefs_t GetPrefs,
|
|
Usr_GetRoleInCurrentCrs_t GetRoleInCurrentCrs)
|
|
{
|
|
/***** Check if a user exists having this user's code *****/
|
|
if (Usr_DB_ChkIfUsrCodExists (UsrDat->UsrCod))
|
|
{
|
|
/* Get user's data */
|
|
Usr_GetAllUsrDataFromUsrCod (UsrDat,GetPrefs,GetRoleInCurrentCrs);
|
|
return true;
|
|
}
|
|
|
|
/***** No user's code found *****/
|
|
UsrDat->UsrIDNickOrEmail[0] = '\0';
|
|
Usr_ResetUsrDataExceptUsrCodAndIDs (UsrDat);
|
|
return false;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********* Update my last accessed course, tab and time in database **********/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_UpdateMyLastData (void)
|
|
{
|
|
/***** Check if it exists an entry for me *****/
|
|
if (Usr_DB_CheckMyLastData ())
|
|
/***** Update my last accessed course, tab and time of click in database *****/
|
|
// WhatToSearch, LastAccNotif remain unchanged
|
|
Usr_DB_UpdateMyLastData ();
|
|
else
|
|
Usr_DB_InsertMyLastData ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*********** Write a row of a table with the main data of a user *************/
|
|
/*****************************************************************************/
|
|
|
|
#define Usr_MAX_BYTES_BG_COLOR (16 - 1)
|
|
|
|
void Usr_WriteRowUsrMainData (unsigned NumUsr,struct Usr_Data *UsrDat,
|
|
bool PutCheckBoxToSelectUsr,Rol_Role_t Role,
|
|
struct Usr_SelectedUsrs *SelectedUsrs)
|
|
{
|
|
extern const char *Txt_Enrolment_confirmed;
|
|
extern const char *Txt_Enrolment_not_confirmed;
|
|
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
|
|
{
|
|
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
|
|
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
|
|
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
|
|
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
|
|
};
|
|
char BgColor[Usr_MAX_BYTES_BG_COLOR + 1];
|
|
bool UsrIsTheMsgSender = PutCheckBoxToSelectUsr &&
|
|
(UsrDat->UsrCod == Gbl.Usrs.Other.UsrDat.UsrCod);
|
|
struct Ins_Instit Ins;
|
|
|
|
/***** Begin row *****/
|
|
HTM_TR_Begin (NULL);
|
|
|
|
/***** Checkbox to select user *****/
|
|
// Two colors are used alternatively to better distinguish the rows
|
|
if (UsrIsTheMsgSender)
|
|
Str_Copy (BgColor,"LIGHT_GREEN",sizeof (BgColor) - 1);
|
|
else
|
|
snprintf (BgColor,sizeof (BgColor),"%s",The_GetColorRows ());
|
|
|
|
if (PutCheckBoxToSelectUsr)
|
|
{
|
|
HTM_TD_Begin ("class=\"CM %s\"",BgColor);
|
|
Usr_PutCheckboxToSelectUser (Role,UsrDat->EnUsrCod,UsrIsTheMsgSender,
|
|
SelectedUsrs);
|
|
HTM_TD_End ();
|
|
}
|
|
|
|
/***** User has accepted enrolment? *****/
|
|
if (UsrIsTheMsgSender)
|
|
HTM_TD_Begin ("class=\"BM_SEL %s_%s\" title=\"%s\"",
|
|
UsrDat->Accepted ? "USR_LIST_NUM_N" :
|
|
"USR_LIST_NUM",
|
|
The_GetSuffix (),
|
|
UsrDat->Accepted ? Txt_Enrolment_confirmed :
|
|
Txt_Enrolment_not_confirmed);
|
|
else
|
|
HTM_TD_Begin ("class=\"BM %s_%s %s\" title=\"%s\"",
|
|
UsrDat->Accepted ? "USR_LIST_NUM_N" :
|
|
"USR_LIST_NUM",
|
|
The_GetSuffix (),
|
|
BgColor,
|
|
UsrDat->Accepted ? Txt_Enrolment_confirmed :
|
|
Txt_Enrolment_not_confirmed);
|
|
HTM_Txt (UsrDat->Accepted ? "✓" :
|
|
"✗");
|
|
HTM_TD_End ();
|
|
|
|
/***** Write number of user in the list *****/
|
|
HTM_TD_Begin ("class=\"%s_%s RM %s\"",
|
|
UsrDat->Accepted ? "USR_LIST_NUM_N" :
|
|
"USR_LIST_NUM",
|
|
The_GetSuffix (),
|
|
BgColor);
|
|
HTM_Unsigned (NumUsr);
|
|
HTM_TD_End ();
|
|
|
|
if (Gbl.Usrs.Listing.WithPhotos)
|
|
{
|
|
/***** Show user's photo *****/
|
|
HTM_TD_Begin ("class=\"CM %s\"",BgColor);
|
|
Pho_ShowUsrPhotoIfAllowed (UsrDat,
|
|
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
|
|
HTM_TD_End ();
|
|
}
|
|
|
|
/****** Write user's IDs ******/
|
|
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
|
|
UsrDat->Accepted ? "DAT_SMALL_STRONG" :
|
|
"DAT_SMALL",
|
|
The_GetSuffix (),
|
|
BgColor);
|
|
ID_WriteUsrIDs (UsrDat,NULL);
|
|
HTM_TD_End ();
|
|
|
|
/***** Write rest of main user's data *****/
|
|
Ins.InsCod = UsrDat->InsCod;
|
|
Ins_GetInstitDataByCod (&Ins);
|
|
Usr_WriteMainUsrDataExceptUsrID (UsrDat,BgColor);
|
|
|
|
HTM_TD_Begin ("class=\"LM %s\"",BgColor);
|
|
Ins_DrawInstitutionLogoWithLink (&Ins,25);
|
|
HTM_TD_End ();
|
|
|
|
/***** End row *****/
|
|
HTM_TR_End ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*************** Write a row of a table with the data of a guest *************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_WriteRowGstAllData (struct Usr_Data *UsrDat)
|
|
{
|
|
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
|
|
{
|
|
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
|
|
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
|
|
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
|
|
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
|
|
};
|
|
struct Ins_Instit Ins;
|
|
struct Ctr_Center Ctr;
|
|
struct Dpt_Department Dpt;
|
|
|
|
/***** Begin row *****/
|
|
HTM_TR_Begin (NULL);
|
|
|
|
if (Gbl.Usrs.Listing.WithPhotos)
|
|
{
|
|
/***** Show guest's photo *****/
|
|
HTM_TD_Begin ("class=\"%s LM\"",The_GetColorRows ());
|
|
Pho_ShowUsrPhotoIfAllowed (UsrDat,
|
|
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_NO_ZOOM);
|
|
HTM_TD_End ();
|
|
}
|
|
|
|
/****** Write user's ID ******/
|
|
HTM_TD_Begin ("class=\"LM DAT_SMALL_%s %s\"",
|
|
The_GetSuffix (),
|
|
The_GetColorRows ());
|
|
ID_WriteUsrIDs (UsrDat,NULL);
|
|
HTM_NBSP ();
|
|
HTM_TD_End ();
|
|
|
|
/***** Write rest of guest's main data *****/
|
|
Ins.InsCod = UsrDat->InsCod;
|
|
Ins_GetInstitDataByCod (&Ins);
|
|
Usr_WriteMainUsrDataExceptUsrID (UsrDat,The_GetColorRows ());
|
|
Usr_WriteEmail (UsrDat,The_GetColorRows ());
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
Ins.FullName,
|
|
NULL,true,false);
|
|
|
|
/***** Write the rest of the data of the guest *****/
|
|
if (UsrDat->Tch.CtrCod > 0)
|
|
{
|
|
Ctr.CtrCod = UsrDat->Tch.CtrCod;
|
|
Ctr_GetCenterDataByCod (&Ctr);
|
|
}
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->Tch.CtrCod > 0 ? Ctr.FullName :
|
|
" ",
|
|
NULL,true,false);
|
|
if (UsrDat->Tch.DptCod > 0)
|
|
{
|
|
Dpt.DptCod = UsrDat->Tch.DptCod;
|
|
Dpt_GetDepartmentDataByCod (&Dpt);
|
|
}
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->Tch.DptCod > 0 ? Dpt.FullName :
|
|
" ",
|
|
NULL,true,false);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->Tch.Office[0] ? UsrDat->Tch.Office :
|
|
" ",
|
|
NULL,true,false);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->Tch.OfficePhone[0] ? UsrDat->Tch.OfficePhone :
|
|
" ",
|
|
NULL,true,false);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->Phone[0][0] ? UsrDat->Phone[0] :
|
|
" ",
|
|
NULL,true,false);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->Phone[1][0] ? UsrDat->Phone[1] :
|
|
" ",
|
|
NULL,true,false);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->StrBirthday[0] ? UsrDat->StrBirthday :
|
|
" ",
|
|
NULL,true,false);
|
|
|
|
/***** End row *****/
|
|
HTM_TR_End ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************ Write a row of a table with the data of a student **************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_WriteRowStdAllData (struct Usr_Data *UsrDat,char *GroupNames)
|
|
{
|
|
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
|
|
{
|
|
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
|
|
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
|
|
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
|
|
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
|
|
};
|
|
unsigned NumGrpTyp,NumField;
|
|
MYSQL_RES *mysql_res;
|
|
MYSQL_ROW row;
|
|
char Text[Cns_MAX_BYTES_TEXT + 1];
|
|
struct Ins_Instit Ins;
|
|
bool ShowData = (Gbl.Usrs.Me.Role.Logged == Rol_TCH && UsrDat->Accepted) ||
|
|
Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM;
|
|
|
|
/***** Begin row *****/
|
|
HTM_TR_Begin (NULL);
|
|
|
|
if (Gbl.Usrs.Listing.WithPhotos)
|
|
{
|
|
/***** Show student's photo *****/
|
|
HTM_TD_Begin ("class=\"LM %s\"",The_GetColorRows ());
|
|
Pho_ShowUsrPhotoIfAllowed (UsrDat,
|
|
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_NO_ZOOM);
|
|
HTM_TD_End ();
|
|
}
|
|
|
|
/****** Write user's ID ******/
|
|
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
|
|
UsrDat->Accepted ? "DAT_SMALL_STRONG" :
|
|
"DAT_SMALL",
|
|
The_GetSuffix (),
|
|
The_GetColorRows ());
|
|
ID_WriteUsrIDs (UsrDat,NULL);
|
|
HTM_NBSP ();
|
|
HTM_TD_End ();
|
|
|
|
/***** Write rest of main student's data *****/
|
|
Ins.InsCod = UsrDat->InsCod;
|
|
Ins_GetInstitDataByCod (&Ins);
|
|
Usr_WriteMainUsrDataExceptUsrID (UsrDat,The_GetColorRows ());
|
|
Usr_WriteEmail (UsrDat,The_GetColorRows ());
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
Ins.FullName,
|
|
NULL,true,UsrDat->Accepted);
|
|
|
|
/***** Write the rest of the data of the student *****/
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->Phone[0][0] ? (ShowData ? UsrDat->Phone[0] :
|
|
"********") :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->Phone[1][0] ? (ShowData ? UsrDat->Phone[1] :
|
|
"********") :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
UsrDat->StrBirthday[0] ? (ShowData ? UsrDat->StrBirthday :
|
|
"********") :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
|
|
if (Gbl.Scope.Current == HieLvl_CRS)
|
|
{
|
|
/***** Write the groups a the que pertenece the student *****/
|
|
for (NumGrpTyp = 0;
|
|
NumGrpTyp < Gbl.Crs.Grps.GrpTypes.NumGrpTypes;
|
|
NumGrpTyp++)
|
|
if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) // If current course tiene groups of este type
|
|
{
|
|
Grp_GetNamesGrpsUsrBelongsTo (UsrDat->UsrCod,
|
|
Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod,
|
|
GroupNames);
|
|
Usr_WriteUsrData (The_GetColorRows (),GroupNames,NULL,true,UsrDat->Accepted);
|
|
}
|
|
|
|
/***** Fields of the record dependientes of the course *****/
|
|
for (NumField = 0;
|
|
NumField < Gbl.Crs.Records.LstFields.Num;
|
|
NumField++)
|
|
{
|
|
/* Get the text of the field */
|
|
if (Rec_DB_GetFieldTxtFromUsrRecord (&mysql_res,
|
|
Gbl.Crs.Records.LstFields.Lst[NumField].FieldCod,
|
|
UsrDat->UsrCod))
|
|
{
|
|
row = mysql_fetch_row (mysql_res);
|
|
Str_Copy (Text,row[0],sizeof (Text) - 1);
|
|
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
|
Text,Cns_MAX_BYTES_TEXT,Str_DONT_REMOVE_SPACES);
|
|
}
|
|
else
|
|
Text[0] = '\0';
|
|
Usr_WriteUsrData (The_GetColorRows (),Text,NULL,false,UsrDat->Accepted);
|
|
|
|
/* Free structure that stores the query result */
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
}
|
|
}
|
|
|
|
/***** End row *****/
|
|
HTM_TR_End ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*** Write a row of a table with the data of a teacher or an administrator ***/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_WriteRowTchAllData (struct Usr_Data *UsrDat)
|
|
{
|
|
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
|
|
{
|
|
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
|
|
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
|
|
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
|
|
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
|
|
};
|
|
struct Ins_Instit Ins;
|
|
struct Ctr_Center Ctr;
|
|
struct Dpt_Department Dpt;
|
|
bool ShowData = (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME || UsrDat->Accepted ||
|
|
Gbl.Usrs.Me.Role.Logged == Rol_DEG_ADM ||
|
|
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM);
|
|
|
|
/***** Begin row *****/
|
|
HTM_TR_Begin (NULL);
|
|
if (Gbl.Usrs.Listing.WithPhotos)
|
|
{
|
|
/***** Show teacher's photo *****/
|
|
HTM_TD_Begin ("class=\"LM %s\"",The_GetColorRows ());
|
|
Pho_ShowUsrPhotoIfAllowed (UsrDat,
|
|
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_NO_ZOOM);
|
|
HTM_TD_End ();
|
|
}
|
|
|
|
/****** Write the user's ID ******/
|
|
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
|
|
UsrDat->Accepted ? "DAT_SMALL_STRONG" :
|
|
"DAT_SMALL",
|
|
The_GetSuffix (),
|
|
The_GetColorRows ());
|
|
ID_WriteUsrIDs (UsrDat,NULL);
|
|
HTM_NBSP ();
|
|
HTM_TD_End ();
|
|
|
|
/***** Write rest of main teacher's data *****/
|
|
Ins.InsCod = UsrDat->InsCod;
|
|
Ins_GetInstitDataByCod (&Ins);
|
|
Usr_WriteMainUsrDataExceptUsrID (UsrDat,The_GetColorRows ());
|
|
Usr_WriteEmail (UsrDat,The_GetColorRows ());
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
Ins.FullName,
|
|
NULL,true,UsrDat->Accepted);
|
|
|
|
/***** Write the rest of teacher's data *****/
|
|
if (ShowData && UsrDat->Tch.CtrCod > 0)
|
|
{
|
|
Ctr.CtrCod = UsrDat->Tch.CtrCod;
|
|
Ctr_GetCenterDataByCod (&Ctr);
|
|
}
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
(ShowData && UsrDat->Tch.CtrCod > 0) ? Ctr.FullName :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
if (ShowData && UsrDat->Tch.DptCod > 0)
|
|
{
|
|
Dpt.DptCod = UsrDat->Tch.DptCod;
|
|
Dpt_GetDepartmentDataByCod (&Dpt);
|
|
}
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
(ShowData && UsrDat->Tch.DptCod > 0) ? Dpt.FullName :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
(ShowData && UsrDat->Tch.Office[0]) ? UsrDat->Tch.Office :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
Usr_WriteUsrData (The_GetColorRows (),
|
|
(ShowData && UsrDat->Tch.OfficePhone[0]) ? UsrDat->Tch.OfficePhone :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
|
|
HTM_TR_End ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********** Write a row of a table with the data of an administrator *********/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_WriteRowAdmData (unsigned NumUsr,struct Usr_Data *UsrDat)
|
|
{
|
|
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
|
|
{
|
|
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
|
|
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
|
|
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
|
|
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
|
|
};
|
|
struct Ins_Instit Ins;
|
|
|
|
/***** Begin row *****/
|
|
HTM_TR_Begin (NULL);
|
|
|
|
/***** Write number of user *****/
|
|
HTM_TD_Begin ("class=\"CM USR_LIST_NUM_N_%s %s\"",
|
|
The_GetSuffix (),
|
|
The_GetColorRows ());
|
|
HTM_Unsigned (NumUsr);
|
|
HTM_TD_End ();
|
|
|
|
if (Gbl.Usrs.Listing.WithPhotos)
|
|
{
|
|
/***** Show administrator's photo *****/
|
|
HTM_TD_Begin ("class=\"LM %s\"",The_GetColorRows ());
|
|
Pho_ShowUsrPhotoIfAllowed (UsrDat,
|
|
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
|
|
HTM_TD_End ();
|
|
}
|
|
|
|
/****** Write the user's ID ******/
|
|
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
|
|
UsrDat->Accepted ? "DAT_SMALL_STRONG" :
|
|
"DAT_SMALL",
|
|
The_GetSuffix (),
|
|
The_GetColorRows ());
|
|
ID_WriteUsrIDs (UsrDat,NULL);
|
|
HTM_NBSP ();
|
|
HTM_TD_End ();
|
|
|
|
/***** Write rest of main administrator's data *****/
|
|
Ins.InsCod = UsrDat->InsCod;
|
|
Ins_GetInstitDataByCod (&Ins);
|
|
Usr_WriteMainUsrDataExceptUsrID (UsrDat,The_GetColorRows ());
|
|
|
|
HTM_TD_Begin ("class=\"LM %s\"",The_GetColorRows ());
|
|
Ins_DrawInstitutionLogoWithLink (&Ins,25);
|
|
HTM_TD_End ();
|
|
|
|
HTM_TR_End ();
|
|
|
|
/***** Write degrees which are administrated by this administrator *****/
|
|
Hie_GetAndWriteInsCtrDegAdminBy (UsrDat->UsrCod,
|
|
Gbl.Usrs.Listing.WithPhotos ? Usr_NUM_MAIN_FIELDS_DATA_ADM :
|
|
Usr_NUM_MAIN_FIELDS_DATA_ADM-1);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************* Write main data of a user *************************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_WriteMainUsrDataExceptUsrID (struct Usr_Data *UsrDat,
|
|
const char *BgColor)
|
|
{
|
|
Usr_WriteUsrData (BgColor,
|
|
UsrDat->Surname1[0] ? UsrDat->Surname1 :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
Usr_WriteUsrData (BgColor,
|
|
UsrDat->Surname2[0] ? UsrDat->Surname2 :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
Usr_WriteUsrData (BgColor,
|
|
UsrDat->FrstName[0] ? UsrDat->FrstName :
|
|
" ",
|
|
NULL,true,UsrDat->Accepted);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**************************** Write user's email *****************************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_WriteEmail (struct Usr_Data *UsrDat,const char *BgColor)
|
|
{
|
|
bool ShowEmail;
|
|
char MailLink[7 + Cns_MAX_BYTES_EMAIL_ADDRESS + 1]; // mailto:mail_address
|
|
|
|
if (UsrDat->Email[0])
|
|
{
|
|
ShowEmail = Mai_ICanSeeOtherUsrEmail (UsrDat);
|
|
if (ShowEmail)
|
|
snprintf (MailLink,sizeof (MailLink),"mailto:%s",UsrDat->Email);
|
|
}
|
|
else
|
|
ShowEmail = false;
|
|
Usr_WriteUsrData (BgColor,
|
|
UsrDat->Email[0] ? (ShowEmail ? UsrDat->Email :
|
|
"********") :
|
|
" ",
|
|
ShowEmail ? MailLink :
|
|
NULL,
|
|
true,UsrDat->Accepted);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************* Write a cell with data of a user **********************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_WriteUsrData (const char *BgColor,
|
|
const char *Data,const char *Link,
|
|
bool NonBreak,bool Accepted)
|
|
{
|
|
/***** Begin table cell *****/
|
|
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
|
|
Accepted ? (NonBreak ? "DAT_SMALL_NOBR_STRONG" :
|
|
"DAT_SMALL_STRONG") :
|
|
(NonBreak ? "DAT_SMALL_NOBR" :
|
|
"DAT_SMALL"),
|
|
The_GetSuffix (),
|
|
BgColor);
|
|
|
|
/***** Container to limit length *****/
|
|
HTM_DIV_Begin ("class=\"USR_DAT\"");
|
|
|
|
/***** Begin link *****/
|
|
if (Link)
|
|
HTM_A_Begin ("href=\"%s\" class=\"%s_%s\" target=\"_blank\"",
|
|
Link,Accepted ? "DAT_SMALL_NOBR_STRONG" :
|
|
"DAT_SMALL_NOBR",
|
|
The_GetSuffix ());
|
|
|
|
/***** Write data *****/
|
|
HTM_Txt (Data);
|
|
if (NonBreak)
|
|
HTM_NBSP ();
|
|
|
|
/***** End link *****/
|
|
if (Link)
|
|
HTM_A_End ();
|
|
|
|
/***** End container *****/
|
|
HTM_DIV_End ();
|
|
|
|
/***** End table cell *****/
|
|
HTM_TD_End ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*********** Get list of users with a given role in a given scope ************/
|
|
/*****************************************************************************/
|
|
// Role can be:
|
|
// - Rol_STD Student
|
|
// - Rol_NET Non-editing teacher
|
|
// - Rol_TCH Teacher
|
|
|
|
void Usr_GetListUsrs (HieLvl_Level_t Scope,Rol_Role_t Role)
|
|
{
|
|
char *Query = NULL;
|
|
|
|
/***** Build query *****/
|
|
Usr_DB_BuildQueryToGetUsrsLst (Scope,Role,&Query);
|
|
|
|
/***** Get list of users from database given a query *****/
|
|
Usr_GetListUsrsFromQuery (Query,Role,Scope);
|
|
|
|
/***** Free query string *****/
|
|
free (Query);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*********** Search for users with a given role in current scope *************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_SearchListUsrs (Rol_Role_t Role)
|
|
{
|
|
char *Query = NULL;
|
|
|
|
/***** Build query *****/
|
|
Usr_DB_BuildQueryToSearchListUsrs (Role,&Query);
|
|
|
|
/***** Get list of users from database given a query *****/
|
|
Usr_GetListUsrsFromQuery (Query,Role,Gbl.Scope.Current);
|
|
|
|
/***** Free query string *****/
|
|
free (Query);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************ Get list with data of guests ***********************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_GetGstsLst (HieLvl_Level_t Scope)
|
|
{
|
|
char *Query = NULL;
|
|
|
|
/***** Build query *****/
|
|
Usr_DB_BuildQueryToGetGstsLst (Scope,&Query);
|
|
|
|
/***** Get list of students from database *****/
|
|
Usr_GetListUsrsFromQuery (Query,Rol_GST,Scope);
|
|
|
|
/***** Free query string *****/
|
|
free (Query);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************** Get the user's codes of all students of a degree *************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_GetUnorderedStdsCodesInDeg (long DegCod)
|
|
{
|
|
char *Query = NULL;
|
|
|
|
/***** Build query string *****/
|
|
Usr_DB_BuildQueryToGetUnorderedStdsCodesInDeg (DegCod,&Query);
|
|
|
|
/***** Get list of students *****/
|
|
Usr_GetListUsrsFromQuery (Query,Rol_STD,HieLvl_DEG);
|
|
|
|
/***** Free query string *****/
|
|
free (Query);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************** Get list of users from database **********************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_GetListUsrsFromQuery (char *Query,Rol_Role_t Role,HieLvl_Level_t Scope)
|
|
{
|
|
extern const char *Txt_The_list_of_X_users_is_too_large_to_be_displayed;
|
|
MYSQL_RES *mysql_res;
|
|
MYSQL_ROW row;
|
|
unsigned NumUsr;
|
|
struct Usr_InList *UsrInList;
|
|
bool Abort = false;
|
|
|
|
if (Query == NULL)
|
|
{
|
|
Gbl.Usrs.LstUsrs[Role].NumUsrs = 0;
|
|
return;
|
|
}
|
|
|
|
if (!Query[0])
|
|
{
|
|
Gbl.Usrs.LstUsrs[Role].NumUsrs = 0;
|
|
return;
|
|
}
|
|
|
|
/***** Query database *****/
|
|
if ((Gbl.Usrs.LstUsrs[Role].NumUsrs = (unsigned)
|
|
DB_QuerySELECT (&mysql_res,"can not get list of users",
|
|
"%s",
|
|
Query)))
|
|
{
|
|
if (Gbl.Usrs.LstUsrs[Role].NumUsrs > Cfg_MAX_USRS_IN_LIST)
|
|
{
|
|
Ale_ShowAlert (Ale_WARNING,Txt_The_list_of_X_users_is_too_large_to_be_displayed,
|
|
Gbl.Usrs.LstUsrs[Role].NumUsrs);
|
|
Abort = true;
|
|
}
|
|
else
|
|
{
|
|
/***** Allocate memory for the list of users *****/
|
|
Usr_AllocateUsrsList (Role);
|
|
|
|
/***** Get list of users *****/
|
|
for (NumUsr = 0;
|
|
NumUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs;
|
|
NumUsr++)
|
|
{
|
|
/* Get next user */
|
|
row = mysql_fetch_row (mysql_res);
|
|
/*
|
|
row[ 0]: usr_data.UsrCod
|
|
row[ 1]: usr_data.EncryptedUsrCod
|
|
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.CtyCod
|
|
row[10]: usr_data.InsCod
|
|
row[11]: crs_users.Role (only if Scope == HieLvl_CRS)
|
|
row[12]: crs_users.Accepted (only if Scope == HieLvl_CRS)
|
|
*/
|
|
UsrInList = &Gbl.Usrs.LstUsrs[Role].Lst[NumUsr];
|
|
|
|
/* Get user's code (row[0]) */
|
|
UsrInList->UsrCod = Str_ConvertStrCodToLongCod (row[0]);
|
|
|
|
/* Get encrypted user's code (row[1]), encrypted password (row[2]),
|
|
surname 1 (row[3]), surname 2 (row[4]), first name (row[5]), */
|
|
Str_Copy (UsrInList->EnUsrCod,row[1],sizeof (UsrInList->EnUsrCod) - 1);
|
|
Str_Copy (UsrInList->Password,row[2],sizeof (UsrInList->Password) - 1);
|
|
Str_Copy (UsrInList->Surname1,row[3],sizeof (UsrInList->Surname1) - 1);
|
|
Str_Copy (UsrInList->Surname2,row[4],sizeof (UsrInList->Surname2) - 1);
|
|
Str_Copy (UsrInList->FrstName,row[5],sizeof (UsrInList->FrstName) - 1);
|
|
|
|
/* Get user's sex (row[6]) */
|
|
UsrInList->Sex = Usr_GetSexFromStr (row[6]);
|
|
|
|
/* Get user's photo (row[7]) */
|
|
Str_Copy (UsrInList->Photo ,row[7],sizeof (UsrInList->Photo ) - 1);
|
|
|
|
/* Get user's photo visibility (row[8]) */
|
|
UsrInList->PhotoVisibility = Pri_GetVisibilityFromStr (row[8]);
|
|
|
|
/* Get user's country code (row[9])
|
|
and user's institution code (row[10]) */
|
|
UsrInList->CtyCod = Str_ConvertStrCodToLongCod (row[ 9]);
|
|
UsrInList->InsCod = Str_ConvertStrCodToLongCod (row[10]);
|
|
|
|
/* Get user's role and acceptance of enrolment in course(s)
|
|
(row[11], row[12] if Scope == HieLvl_CRS) */
|
|
switch (Role)
|
|
{
|
|
case Rol_UNK: // Here Rol_UNK means any user
|
|
switch (Scope)
|
|
{
|
|
case HieLvl_UNK: // Unknown
|
|
Err_WrongScopeExit ();
|
|
break;
|
|
case HieLvl_SYS: // System
|
|
// Query result has not a column with the acceptation
|
|
UsrInList->RoleInCurrentCrsDB = Rol_UNK;
|
|
if (Enr_DB_GetNumCrssOfUsr (UsrInList->UsrCod))
|
|
UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrNotAccepted (UsrInList->UsrCod) == 0);
|
|
else
|
|
UsrInList->Accepted = false;
|
|
break;
|
|
case HieLvl_CTY: // Country
|
|
case HieLvl_INS: // Institution
|
|
case HieLvl_CTR: // Center
|
|
case HieLvl_DEG: // Degree
|
|
// Query result has not a column with the acceptation
|
|
UsrInList->RoleInCurrentCrsDB = Rol_UNK;
|
|
UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrNotAccepted (UsrInList->UsrCod) == 0);
|
|
break;
|
|
case HieLvl_CRS: // Course
|
|
// Query result has a column with the acceptation
|
|
UsrInList->RoleInCurrentCrsDB = Rol_ConvertUnsignedStrToRole (row[11]);
|
|
UsrInList->Accepted = (row[12][0] == 'Y');
|
|
break;
|
|
}
|
|
break;
|
|
case Rol_GST: // Guests have no courses,...
|
|
// ...so they have not accepted...
|
|
// ...inscription in any course
|
|
case Rol_DEG_ADM: // Any admin (degree, center, institution or system)
|
|
UsrInList->RoleInCurrentCrsDB = Rol_UNK;
|
|
UsrInList->Accepted = false;
|
|
break;
|
|
case Rol_STD:
|
|
case Rol_NET:
|
|
case Rol_TCH:
|
|
switch (Scope)
|
|
{
|
|
case HieLvl_UNK: // Unknown
|
|
Err_WrongScopeExit ();
|
|
break;
|
|
case HieLvl_SYS: // System
|
|
case HieLvl_CTY: // Country
|
|
case HieLvl_INS: // Institution
|
|
case HieLvl_CTR: // Center
|
|
case HieLvl_DEG: // Degree
|
|
// Query result has not a column with the acceptation
|
|
UsrInList->RoleInCurrentCrsDB = Rol_UNK;
|
|
UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrWithARoleNotAccepted (UsrInList->UsrCod,Role) == 0);
|
|
break;
|
|
case HieLvl_CRS: // Course
|
|
// Query result has a column with the acceptation
|
|
UsrInList->RoleInCurrentCrsDB = Rol_ConvertUnsignedStrToRole (row[11]);
|
|
UsrInList->Accepted = (row[12][0] == 'Y');
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
Err_WrongRoleExit ();
|
|
break;
|
|
}
|
|
|
|
/* By default, users are not removed */
|
|
UsrInList->Remove = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
if (Abort)
|
|
Err_ShowErrorAndExit (NULL);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************** Copy user's basic data from list *********************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_CopyBasicUsrDataFromList (struct Usr_Data *UsrDat,
|
|
const struct Usr_InList *UsrInList)
|
|
{
|
|
UsrDat->UsrCod = UsrInList->UsrCod;
|
|
Str_Copy (UsrDat->EnUsrCod,UsrInList->EnUsrCod,sizeof (UsrDat->EnUsrCod) - 1);
|
|
Str_Copy (UsrDat->Surname1,UsrInList->Surname1,sizeof (UsrDat->Surname1) - 1);
|
|
Str_Copy (UsrDat->Surname2,UsrInList->Surname2,sizeof (UsrDat->Surname2) - 1);
|
|
Str_Copy (UsrDat->FrstName,UsrInList->FrstName,sizeof (UsrDat->FrstName) - 1);
|
|
UsrDat->Sex = UsrInList->Sex;
|
|
Str_Copy (UsrDat->Photo ,UsrInList->Photo ,sizeof (UsrDat->Photo ) - 1);
|
|
UsrDat->PhotoVisibility = UsrInList->PhotoVisibility;
|
|
UsrDat->CtyCod = UsrInList->CtyCod;
|
|
UsrDat->InsCod = UsrInList->InsCod;
|
|
UsrDat->Roles.InCurrentCrs = UsrInList->RoleInCurrentCrsDB;
|
|
UsrDat->Accepted = UsrInList->Accepted;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************** Allocate space for list of users *********************/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_AllocateUsrsList (Rol_Role_t Role)
|
|
{
|
|
if (Gbl.Usrs.LstUsrs[Role].NumUsrs)
|
|
if ((Gbl.Usrs.LstUsrs[Role].Lst = calloc (Gbl.Usrs.LstUsrs[Role].NumUsrs,
|
|
sizeof (*Gbl.Usrs.LstUsrs[Role].Lst))) == NULL)
|
|
Err_NotEnoughMemoryExit ();
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/********************* Free space used for list of users *********************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_FreeUsrsList (Rol_Role_t Role)
|
|
{
|
|
if (Gbl.Usrs.LstUsrs[Role].NumUsrs)
|
|
{
|
|
/***** Free the list itself *****/
|
|
if (Gbl.Usrs.LstUsrs[Role].Lst)
|
|
{
|
|
free (Gbl.Usrs.LstUsrs[Role].Lst);
|
|
Gbl.Usrs.LstUsrs[Role].Lst = NULL;
|
|
}
|
|
|
|
/***** Reset number of users *****/
|
|
Gbl.Usrs.LstUsrs[Role].NumUsrs = 0;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******** Show form to confirm that I want to see a big list of users ********/
|
|
/*****************************************************************************/
|
|
|
|
bool Usr_GetIfShowBigList (unsigned NumUsrs,
|
|
void (*FuncPars) (void *Args),void *Args,
|
|
const char *OnSubmit)
|
|
{
|
|
bool ShowBigList;
|
|
|
|
/***** If list of users is too big... *****/
|
|
if (NumUsrs > Cfg_MIN_NUM_USERS_TO_CONFIRM_SHOW_BIG_LIST)
|
|
{
|
|
/***** Get parameter with user's confirmation
|
|
to see a big list of users *****/
|
|
if (!(ShowBigList = Par_GetParBool ("ShowBigList")))
|
|
Usr_PutButtonToConfirmIWantToSeeBigList (NumUsrs,
|
|
FuncPars,Args,
|
|
OnSubmit);
|
|
|
|
return ShowBigList;
|
|
}
|
|
else
|
|
return true; // List is not too big ==> show it
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/******** Show form to confirm that I want to see a big list of users ********/
|
|
/*****************************************************************************/
|
|
|
|
static void Usr_PutButtonToConfirmIWantToSeeBigList (unsigned NumUsrs,
|
|
void (*FuncPars) (void *Args),void *Args,
|
|
const char *OnSubmit)
|
|
{
|
|
extern const char *Txt_The_list_of_X_users_is_too_large_to_be_displayed;
|
|
extern const char *Txt_Show_anyway;
|
|
|
|
/***** Show alert and button to confirm that I want to see the big list *****/
|
|
Usr_FuncParsBigList = FuncPars; // Used to pass pointer to function
|
|
Ale_ShowAlertAndButton (Gbl.Action.Act,Usr_USER_LIST_SECTION_ID,OnSubmit,
|
|
Usr_PutParsConfirmIWantToSeeBigList,Args,
|
|
Btn_CONFIRM_BUTTON,Txt_Show_anyway,
|
|
Ale_WARNING,Txt_The_list_of_X_users_is_too_large_to_be_displayed,
|
|
NumUsrs);
|
|
}
|
|
|
|
static void Usr_PutParsConfirmIWantToSeeBigList (void *Args)
|
|
{
|
|
Grp_PutParsCodGrps ();
|
|
Set_PutParsPrefsAboutUsrList ();
|
|
if (Usr_FuncParsBigList)
|
|
Usr_FuncParsBigList (Args);
|
|
Par_PutParChar ("ShowBigList",'Y');
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************ Create list of selected users with one given user **************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_CreateListSelectedUsrsCodsAndFillWithOtherUsr (struct Usr_SelectedUsrs *SelectedUsrs)
|
|
{
|
|
/***** Create list of user codes and put encrypted user code in it *****/
|
|
if (!SelectedUsrs->List[Rol_UNK])
|
|
{
|
|
if ((SelectedUsrs->List[Rol_UNK] =
|
|
malloc (Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64 + 1)) == NULL)
|
|
Err_NotEnoughMemoryExit ();
|
|
Str_Copy (SelectedUsrs->List[Rol_UNK],Gbl.Usrs.Other.UsrDat.EnUsrCod,
|
|
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
|
|
SelectedUsrs->Filled = true;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************* Write parameter with the list of users selected ***************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_PutParSelectedUsrsCods (struct Usr_SelectedUsrs *SelectedUsrs)
|
|
{
|
|
char *ParName;
|
|
|
|
/***** Put a parameter indicating that a list of several users is present *****/
|
|
Par_PutParChar ("MultiUsrs",'Y');
|
|
|
|
/***** Put a parameter with the encrypted user codes of several users *****/
|
|
/* Build name of the parameter.
|
|
Sometimes a unique action needs several distinct lists of users,
|
|
so, it's necessary to use distinct names for the parameters. */
|
|
Usr_BuildParName (&ParName,Usr_ParUsrCod[Rol_UNK],SelectedUsrs->ParSuffix);
|
|
|
|
/* Put the parameter *****/
|
|
if (Gbl.Session.IsOpen)
|
|
Ses_InsertParInDB (ParName,SelectedUsrs->List[Rol_UNK]);
|
|
else
|
|
Par_PutParString (NULL,ParName,SelectedUsrs->List[Rol_UNK]);
|
|
|
|
/***** Free allocated memory for parameter name *****/
|
|
free (ParName);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/************************* Get list of selected users ************************/
|
|
/*****************************************************************************/
|
|
|
|
void Usr_GetListsSelectedEncryptedUsrsCods (struct Usr_SelectedUsrs *SelectedUsrs)
|
|
{
|
|
extern const char *Par_SEPARATOR_PARAM_MULTIPLE;
|
|
char *ParName;
|
|
unsigned Length;
|
|
Rol_Role_t Role;
|
|
|
|
if (!SelectedUsrs->Filled) // Get list only if not already got
|
|
{
|
|
/***** Build name of the parameter.
|
|
Sometimes a unique action needs several distinct lists of users,
|
|
so, it's necessary to use distinct names for the parameters. *****/
|
|
Usr_BuildParName (&ParName,Usr_ParUsrCod[Rol_UNK],SelectedUsrs->ParSuffix);
|
|
|
|
/***** Get possible list of all selected users *****/
|
|
Usr_AllocateListSelectedEncryptedUsrCods (SelectedUsrs,Rol_UNK);
|
|
if (Gbl.Session.IsOpen) // If the session is open, get parameter from DB
|
|
{
|
|
Ses_DB_GetPar (ParName,SelectedUsrs->List[Rol_UNK],
|
|
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
|
|
Str_ChangeFormat (Str_FROM_FORM,Str_TO_TEXT,SelectedUsrs->List[Rol_UNK],
|
|
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS,
|
|
Str_REMOVE_SPACES);
|
|
}
|
|
else
|
|
Par_GetParMultiToText (ParName,SelectedUsrs->List[Rol_UNK],
|
|
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
|
|
|
|
/***** Free allocated memory for parameter name *****/
|
|
free (ParName);
|
|
|
|
/***** Get list of selected users for each possible role *****/
|
|
for (Role = Rol_TCH; // From the highest possible role of selected users...
|
|
Role >= Rol_GST; // ...downto the lowest possible role of selected users
|
|
Role--)
|
|
if (Usr_ParUsrCod[Role])
|
|
{
|
|
/* Build name of the parameter */
|
|
Usr_BuildParName (&ParName,Usr_ParUsrCod[Role],SelectedUsrs->ParSuffix);
|
|
|
|
/* Get parameter with selected users with this role */
|
|
Usr_AllocateListSelectedEncryptedUsrCods (SelectedUsrs,Role);
|
|
Par_GetParMultiToText (ParName,SelectedUsrs->List[Role],
|
|
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
|
|
|
|
/* Free allocated memory for parameter name */
|
|
free (ParName);
|
|
|
|
/* Add selected users with this role
|
|
to the list with all selected users */
|
|
if (SelectedUsrs->List[Role][0])
|
|
{
|
|
if (SelectedUsrs->List[Rol_UNK][0])
|
|
if ((Length = strlen (SelectedUsrs->List[Rol_UNK])) <
|
|
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS)
|
|
{
|
|
SelectedUsrs->List[Rol_UNK][Length ] = Par_SEPARATOR_PARAM_MULTIPLE[0];
|
|
SelectedUsrs->List[Rol_UNK][Length + 1] = '\0';
|
|
}
|
|
Str_Concat (SelectedUsrs->List[Rol_UNK],SelectedUsrs->List[Role],
|
|
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
|
|
}
|
|
}
|
|
|
|
/***** List is filled *****/
|
|
SelectedUsrs->Filled = true;
|
|
}
|
|
}
|
|
|
|
static void Usr_BuildParName (char **ParName,
|
|
const char *ParRoot,
|
|
const char *ParSuffix)
|
|
{
|
|
/* Build name of the parameter.
|
|
Sometimes a unique action needs several distinct lists of users,
|
|
so, it's necessary to use distinct names for the parameters. */
|
|
if (ParSuffix)
|
|