// swad_nickname.c: Users' nicknames /* 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-2019 Antonio Caņas Vargas This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ /*****************************************************************************/ /********************************* Headers ***********************************/ /*****************************************************************************/ #include // For string functions #include "swad_account.h" #include "swad_box.h" #include "swad_database.h" #include "swad_form.h" #include "swad_global.h" #include "swad_HTML.h" #include "swad_parameter.h" #include "swad_QR.h" #include "swad_user.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ /*****************************************************************************/ extern struct Globals Gbl; /*****************************************************************************/ /***************************** Private constants *****************************/ /*****************************************************************************/ /*****************************************************************************/ /******************************* Private types *******************************/ /*****************************************************************************/ /*****************************************************************************/ /***************************** Private variables *****************************/ /*****************************************************************************/ const char *Nck_NICKNAME_SECTION_ID = "nickname_section"; /*****************************************************************************/ /***************************** Private prototypes ****************************/ /*****************************************************************************/ static void Nck_ShowFormChangeUsrNickname (const struct UsrData *UsrDat,bool ItsMe, bool IMustFillNickname); static void Nck_RemoveNicknameFromDB (long UsrCod,const char *Nickname); static void Nck_UpdateUsrNick (struct UsrData *UsrDat); /*****************************************************************************/ /********* Check whether a nickname (with initial arroba) if valid ***********/ /*****************************************************************************/ bool Nck_CheckIfNickWithArrobaIsValid (const char *NicknameWithArroba) { char NicknameWithoutArroba[Nck_MAX_BYTES_NICKNAME_FROM_FORM + 1]; unsigned Length; const char *Ptr; /***** A nickname must start by '@' *****/ if (NicknameWithArroba[0] != '@') // It's not a nickname return false; /***** Make a copy of nickname *****/ Str_Copy (NicknameWithoutArroba,NicknameWithArroba, Nck_MAX_BYTES_NICKNAME_FROM_FORM); Str_RemoveLeadingArrobas (NicknameWithoutArroba); Length = strlen (NicknameWithoutArroba); /***** A nick (without arroba) must have a number of characters Nck_MIN_BYTES_NICKNAME_WITHOUT_ARROBA <= Length <= Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA *****/ if (Length < Nck_MIN_BYTES_NICKNAME_WITHOUT_ARROBA || Length > Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA) return false; /***** A nick can have digits, letters and '_' *****/ for (Ptr = NicknameWithoutArroba; *Ptr; Ptr++) if (!((*Ptr >= 'a' && *Ptr <= 'z') || (*Ptr >= 'A' && *Ptr <= 'Z') || (*Ptr >= '0' && *Ptr <= '9') || (*Ptr == '_'))) return false; return true; } /*****************************************************************************/ /************* Get nickname of a user from his/her user's code ***************/ /*****************************************************************************/ bool Nck_GetNicknameFromUsrCod (long UsrCod, char Nickname[Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA + 1]) { MYSQL_RES *mysql_res; MYSQL_ROW row; bool Found; /***** Get current (last updated) user's nickname from database *****/ if (DB_QuerySELECT (&mysql_res,"can not get nickname", "SELECT Nickname FROM usr_nicknames" " WHERE UsrCod=%ld ORDER BY CreatTime DESC LIMIT 1", UsrCod)) { /* Get nickname */ row = mysql_fetch_row (mysql_res); Str_Copy (Nickname,row[0], Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA); Found = true; } else { Nickname[0] = '\0'; Found = false; } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); return Found; } /*****************************************************************************/ /************** Get user's code of a user from his/her nickname **************/ /*****************************************************************************/ // Nickname may have leading '@' // Returns true if nickname found in database long Nck_GetUsrCodFromNickname (const char *Nickname) { char NicknameWithoutArroba[Nck_MAX_BYTES_NICKNAME_FROM_FORM + 1]; MYSQL_RES *mysql_res; MYSQL_ROW row; long UsrCod = -1L; if (Nickname) if (Nickname[0]) { /***** Make a copy without possible starting arrobas *****/ Str_Copy (NicknameWithoutArroba,Nickname, Nck_MAX_BYTES_NICKNAME_FROM_FORM); Str_RemoveLeadingArrobas (NicknameWithoutArroba); /***** Get user's code from database *****/ /* Check if user code from table usr_nicknames is also in table usr_data */ if (DB_QuerySELECT (&mysql_res,"can not get user's code", "SELECT usr_nicknames.UsrCod" " FROM usr_nicknames,usr_data" " WHERE usr_nicknames.Nickname='%s'" " AND usr_nicknames.UsrCod=usr_data.UsrCod", NicknameWithoutArroba)) { /* Get row */ row = mysql_fetch_row (mysql_res); /* Get user's code */ UsrCod = Str_ConvertStrCodToLongCod (row[0]); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } return UsrCod; } /*****************************************************************************/ /*********************** Show form to change my nickname *********************/ /*****************************************************************************/ void Nck_ShowFormChangeMyNickname (bool IMustFillNickname) { Nck_ShowFormChangeUsrNickname (&Gbl.Usrs.Me.UsrDat, true, // ItsMe IMustFillNickname); } /*****************************************************************************/ /*********************** Show form to change my nickname *********************/ /*****************************************************************************/ void Nck_ShowFormChangeOtherUsrNickname (void) { Nck_ShowFormChangeUsrNickname (&Gbl.Usrs.Other.UsrDat, false, // ItsMe false); // IMustFillNickname } /*****************************************************************************/ /*********************** Show form to change my nickname *********************/ /*****************************************************************************/ static void Nck_ShowFormChangeUsrNickname (const struct UsrData *UsrDat,bool ItsMe, bool IMustFillNickname) { extern const char *Hlp_PROFILE_Account; extern const char *The_ClassFormInBox[The_NUM_THEMES]; extern const char *Txt_Nickname; extern const char *Txt_Before_going_to_any_other_option_you_must_fill_your_nickname; extern const char *Txt_Current_nickname; extern const char *Txt_Other_nicknames; extern const char *Txt_Use_this_nickname; extern const char *Txt_New_nickname; extern const char *Txt_Change_nickname; extern const char *Txt_Save_changes; MYSQL_RES *mysql_res; MYSQL_ROW row; char StrRecordWidth[10 + 1]; unsigned NumNicks; unsigned NumNick; Act_Action_t NextAction; /***** Start section *****/ HTM_SECTION_Begin (Nck_NICKNAME_SECTION_ID); /***** Get my nicknames *****/ NumNicks = (unsigned) DB_QuerySELECT (&mysql_res,"can not get nicknames of a user", "SELECT Nickname FROM usr_nicknames" " WHERE UsrCod=%ld" " ORDER BY CreatTime DESC", UsrDat->UsrCod); /***** Begin box *****/ snprintf (StrRecordWidth,sizeof (StrRecordWidth), "%upx", Rec_RECORD_WIDTH); Box_BoxBegin (StrRecordWidth,Txt_Nickname,Acc_PutLinkToRemoveMyAccount, Hlp_PROFILE_Account,Box_NOT_CLOSABLE); /***** Show possible alerts *****/ Ale_ShowAlerts (Nck_NICKNAME_SECTION_ID); /***** Help message *****/ if (IMustFillNickname) Ale_ShowAlert (Ale_WARNING,Txt_Before_going_to_any_other_option_you_must_fill_your_nickname); /***** Begin table *****/ HTM_TABLE_BeginWidePadding (2); /***** List nicknames *****/ for (NumNick = 1; NumNick <= NumNicks; NumNick++) { /* Get nickname */ row = mysql_fetch_row (mysql_res); HTM_TR_Begin (NULL); if (NumNick == 1) { /* The first nickname is the current one */ HTM_TD_Begin ("class=\"REC_C1_BOT RT\""); fprintf (Gbl.F.Out,"