Version 21.23: Oct 04, 2021 New module swad_password_database for database queries related to passwords.

This commit is contained in:
acanas 2021-10-04 17:16:06 +02:00
parent c529b1b8e8
commit 399fdea65a
10 changed files with 261 additions and 94 deletions

View File

@ -69,9 +69,9 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \
swad_network.o swad_network_database.o swad_nickname.o \
swad_nickname_database.o swad_notice.o swad_notice_database.o \
swad_notification.o swad_notification_database.o \
swad_pagination.o swad_parameter.o swad_password.o swad_photo.o \
swad_place.o swad_plugin.o swad_privacy.o swad_profile.o swad_program.o \
swad_project.o \
swad_pagination.o swad_parameter.o swad_password.o \
swad_password_database.o swad_photo.o swad_place.o swad_plugin.o \
swad_privacy.o swad_profile.o swad_program.o swad_project.o \
swad_QR.o \
swad_record.o swad_report.o swad_role.o swad_room.o swad_RSS.o \
swad_scope.o swad_search.o swad_session.o swad_setting.o \

View File

@ -121,6 +121,19 @@ bool ID_DB_CheckIfConfirmed (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1])
ID) != 0);
}
/*****************************************************************************/
/********************** Check if a string is a user's ID *********************/
/*****************************************************************************/
bool ID_DB_FindStrInUsrsIDs (const char *Str)
{
return (DB_QueryCOUNT ("can not check if a string matches any user's ID",
"SELECT COUNT(*)"
" FROM usr_ids"
" WHERE UsrID='%s'",
Str) != 0);
}
/*****************************************************************************/
/***************** Get list of user codes from user's IDs ********************/
/*****************************************************************************/

View File

@ -42,6 +42,7 @@ void ID_DB_ConfirmUsrID (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1]);
unsigned ID_DB_GetIDsFromUsrCod (MYSQL_RES **mysql_res,long UsrCod);
bool ID_DB_CheckIfConfirmed (long UsrCod,const char ID[ID_MAX_BYTES_USR_ID + 1]);
bool ID_DB_FindStrInUsrsIDs (const char *Str);
unsigned ID_DB_GetUsrCodsFromUsrID (MYSQL_RES **mysql_res,
const struct UsrData *UsrDat,
const char *EncryptedPassword,

View File

@ -602,14 +602,15 @@ TODO: FIX BUG, URGENT! En las fechas como par
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
*/
#define Log_PLATFORM_VERSION "SWAD 21.22 (2021-10-04)"
#define Log_PLATFORM_VERSION "SWAD 21.23 (2021-10-04)"
#define CSS_FILE "swad20.45.css"
#define JS_FILE "swad20.69.1.js"
/*
TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
Version 21.22: Oct 04, 2021 Queries related to notifications moved to other modules. (318058 lines)
Version 21.23: Oct 04, 2021 New module swad_password_database for database queries related to passwords. (318197 lines)
Version 21.22: Oct 04, 2021 Queries related to notifications moved to other modules. (318066 lines)
Version 21.21.2: Oct 01, 2021 Queries moved to module swad_notification_database. (317963 lines)
Version 21.21.1: Oct 01, 2021 Queries moved to module swad_notification_database. (317938 lines)
Version 21.21: Sep 30, 2021 New module swad_notice_database for database queries related to notices. (317901 lines)

View File

@ -34,7 +34,6 @@
/****************************** Public constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/******************************** Public types *******************************/
/*****************************************************************************/

View File

@ -40,8 +40,10 @@
#include "swad_global.h"
#include "swad_HTML.h"
#include "swad_ID.h"
#include "swad_ID_database.h"
#include "swad_mail_database.h"
#include "swad_password.h"
#include "swad_password_database.h"
#include "swad_parameter.h"
#include "swad_user.h"
@ -81,7 +83,6 @@ static void Pwd_PutLinkToSendNewPasswdParams (void *UsrIdLogin);
static void Pwd_CreateANewPassword (char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD + 1]);
static bool Pwd_CheckIfPasswdIsUsrIDorName (const char *PlainPassword);
static unsigned Pwd_GetNumOtherUsrsWhoUseThisPassword (const char *EncryptedPassword,long UsrCod);
/*****************************************************************************/
/************* Get parameter with my plain password from a form **************/
@ -118,13 +119,7 @@ bool Pwd_CheckCurrentPassword (void)
bool Pwd_CheckPendingPassword (void)
{
/***** Get pending password from database *****/
DB_QuerySELECTString (Gbl.Usrs.Me.PendingPassword,
sizeof (Gbl.Usrs.Me.PendingPassword) - 1,
"can not get pending password",
"SELECT PendingPassword" // row[0]
" FROM usr_pending_passwd"
" WHERE UsrCod=%ld",
Gbl.Usrs.Me.UsrDat.UsrCod);
Pwd_DB_GetPendingPassword ();
return (Gbl.Usrs.Me.PendingPassword[0] ?
!strcmp (Gbl.Usrs.Me.LoginEncryptedPassword,Gbl.Usrs.Me.PendingPassword) :
@ -138,12 +133,7 @@ bool Pwd_CheckPendingPassword (void)
void Pwd_AssignMyPendingPasswordToMyCurrentPassword (void)
{
/***** Update my current password in database *****/
DB_QueryUPDATE ("can not update your password",
"UPDATE usr_data"
" SET Password='%s'"
" WHERE UsrCod=%ld",
Gbl.Usrs.Me.PendingPassword,
Gbl.Usrs.Me.UsrDat.UsrCod);
Pwd_DB_AssignMyPendingPasswordToMyCurrentPassword ();
/***** Update my current password *****/
Str_Copy (Gbl.Usrs.Me.UsrDat.Password,Gbl.Usrs.Me.PendingPassword,
@ -151,10 +141,7 @@ void Pwd_AssignMyPendingPasswordToMyCurrentPassword (void)
/***** Remove my pending password from database
since it is not longer necessary *****/
DB_QueryDELETE ("can not remove pending password",
"DELETE FROM usr_pending_passwd"
" WHERE UsrCod=%ld",
Gbl.Usrs.Me.UsrDat.UsrCod);
Pwd_DB_RemoveMyPendingPassword ();
}
/*****************************************************************************/
@ -488,19 +475,10 @@ void Pwd_SetMyPendingPassword (char PlainPassword[Pwd_MAX_BYTES_PLAIN_PASSWORD +
Cry_EncryptSHA512Base64 (PlainPassword,Gbl.Usrs.Me.PendingPassword);
/***** Remove expired pending passwords from database *****/
DB_QueryDELETE ("can not remove expired pending passwords",
"DELETE LOW_PRIORITY FROM usr_pending_passwd"
" WHERE DateAndTime<FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
Cfg_TIME_TO_DELETE_OLD_PENDING_PASSWORDS);
Pwd_DB_RemoveExpiredPendingPassword ();
/***** Update my current password in database *****/
DB_QueryREPLACE ("can not create pending password",
"REPLACE INTO usr_pending_passwd"
" (UsrCod,PendingPassword,DateAndTime)"
" VALUES"
" (%ld,'%s',NOW())",
Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Usrs.Me.PendingPassword);
/***** Update my current pending password in database *****/
Pwd_DB_UpdateMyPendingPassword ();
}
/*****************************************************************************/
@ -526,7 +504,7 @@ bool Pwd_SlowCheckIfPasswordIsGood (const char PlainPassword[Pwd_MAX_BYTES_PLAIN
}
/***** Check if password is used by too many other users *****/
if (Pwd_GetNumOtherUsrsWhoUseThisPassword (EncryptedPassword,UsrCod) >
if (Pwd_DB_GetNumOtherUsrsWhoUseThisPassword (EncryptedPassword,UsrCod) >
Pwd_MAX_OTHER_USERS_USING_THE_SAME_PASSWORD)
{
Ale_CreateAlert (Ale_WARNING,Pwd_PASSWORD_SECTION_ID,
@ -543,64 +521,12 @@ bool Pwd_SlowCheckIfPasswordIsGood (const char PlainPassword[Pwd_MAX_BYTES_PLAIN
static bool Pwd_CheckIfPasswdIsUsrIDorName (const char *PlainPassword)
{
bool Found;
/***** Check if password is found in user's ID *****/
if (ID_DB_FindStrInUsrsIDs (PlainPassword))
return true; // Found
/***** Get if password is found in user's ID from database *****/
Found = (DB_QueryCOUNT ("can not check if a password matches a user's ID",
"SELECT COUNT(*)"
" FROM usr_ids"
" WHERE UsrID='%s'",
PlainPassword) != 0);
/***** Get if password is found in first name or surnames of anybody, from database *****/
if (!Found)
Found = (DB_QueryCOUNT ("can not check if a password matches"
" a first name or a surname",
"SELECT COUNT(*)"
" FROM usr_data"
" WHERE FirstName='%s'"
" OR Surname1='%s'"
" OR Surname2='%s'",
PlainPassword,
PlainPassword,
PlainPassword) != 0);
return Found;
}
/*****************************************************************************/
/************** Get the number of users who use yet a password ***************/
/*****************************************************************************/
static unsigned Pwd_GetNumOtherUsrsWhoUseThisPassword (const char *EncryptedPassword,long UsrCod)
{
unsigned NumUsrs;
char *SubQuery;
/***** Build subquery *****/
if (UsrCod > 0)
{
if (asprintf (&SubQuery," AND UsrCod<>%ld",UsrCod) < 0)
Err_NotEnoughMemoryExit ();
}
else
SubQuery = "";
/***** Get number of other users who use a password from database *****/
NumUsrs = (unsigned)
DB_QueryCOUNT ("can not check if a password is trivial",
"SELECT COUNT(*)"
" FROM usr_data"
" WHERE Password='%s'"
"%s",
EncryptedPassword,
SubQuery);
/***** Free subquery *****/
if (UsrCod > 0)
free (SubQuery);
return NumUsrs;
/***** Check if password is found in first name or surnames of anybody *****/
return Usr_DB_FindStrInUsrsNames (PlainPassword);
}
/*****************************************************************************/

160
swad_password_database.c Normal file
View File

@ -0,0 +1,160 @@
// swad_password_database.c: Users' passwords, operations with database
/*
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-2021 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 <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#define _GNU_SOURCE // For asprintf
#include <stdio.h> // For asprintf
#include "swad_config.h"
#include "swad_database.h"
#include "swad_error.h"
#include "swad_global.h"
#include "swad_password_database.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
/*****************************************************************************/
/************** Update my current pending password in database ***************/
/*****************************************************************************/
void Pwd_DB_UpdateMyPendingPassword (void)
{
DB_QueryREPLACE ("can not create pending password",
"REPLACE INTO usr_pending_passwd"
" (UsrCod,PendingPassword,DateAndTime)"
" VALUES"
" (%ld,'%s',NOW())",
Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Usrs.Me.PendingPassword);
}
/*****************************************************************************/
/******************* Update my current password in database ******************/
/*****************************************************************************/
void Pwd_DB_AssignMyPendingPasswordToMyCurrentPassword (void)
{
DB_QueryUPDATE ("can not update your password",
"UPDATE usr_data"
" SET Password='%s'"
" WHERE UsrCod=%ld",
Gbl.Usrs.Me.PendingPassword,
Gbl.Usrs.Me.UsrDat.UsrCod);
}
/*****************************************************************************/
/******************* Get pending password from database **********************/
/*****************************************************************************/
void Pwd_DB_GetPendingPassword (void)
{
DB_QuerySELECTString (Gbl.Usrs.Me.PendingPassword,
sizeof (Gbl.Usrs.Me.PendingPassword) - 1,
"can not get pending password",
"SELECT PendingPassword" // row[0]
" FROM usr_pending_passwd"
" WHERE UsrCod=%ld",
Gbl.Usrs.Me.UsrDat.UsrCod);
}
/*****************************************************************************/
/************** Get the number of users who use yet a password ***************/
/*****************************************************************************/
unsigned Pwd_DB_GetNumOtherUsrsWhoUseThisPassword (const char *EncryptedPassword,long UsrCod)
{
unsigned NumUsrs;
char *SubQuery;
/***** Build subquery *****/
if (UsrCod > 0)
{
if (asprintf (&SubQuery," AND UsrCod<>%ld",UsrCod) < 0)
Err_NotEnoughMemoryExit ();
}
else
SubQuery = "";
/***** Get number of other users who use a password from database *****/
NumUsrs = (unsigned)
DB_QueryCOUNT ("can not check if a password is trivial",
"SELECT COUNT(*)"
" FROM usr_data"
" WHERE Password='%s'"
"%s",
EncryptedPassword,
SubQuery);
/***** Free subquery *****/
if (UsrCod > 0)
free (SubQuery);
return NumUsrs;
}
/*****************************************************************************/
/***************** Remove my pending password from database ******************/
/*****************************************************************************/
void Pwd_DB_RemoveMyPendingPassword (void)
{
DB_QueryDELETE ("can not remove pending password",
"DELETE FROM usr_pending_passwd"
" WHERE UsrCod=%ld",
Gbl.Usrs.Me.UsrDat.UsrCod);
}
/*****************************************************************************/
/************* Remove expired pending passwords from database ****************/
/*****************************************************************************/
void Pwd_DB_RemoveExpiredPendingPassword (void)
{
DB_QueryDELETE ("can not remove expired pending passwords",
"DELETE LOW_PRIORITY FROM usr_pending_passwd"
" WHERE DateAndTime<FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
Cfg_TIME_TO_DELETE_OLD_PENDING_PASSWORDS);
}

47
swad_password_database.h Normal file
View File

@ -0,0 +1,47 @@
// swad_password_database.h: Users' passwords, operations with database
#ifndef _SWAD_PWD_DB
#define _SWAD_PWD_DB
/*
SWAD (Shared Workspace At a Distance in Spanish),
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-2021 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 <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
/*****************************************************************************/
/************************* Public types and constants ************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
void Pwd_DB_UpdateMyPendingPassword (void);
void Pwd_DB_AssignMyPendingPasswordToMyCurrentPassword (void);
void Pwd_DB_GetPendingPassword (void);
unsigned Pwd_DB_GetNumOtherUsrsWhoUseThisPassword (const char *EncryptedPassword,long UsrCod);
void Pwd_DB_RemoveMyPendingPassword (void);
void Pwd_DB_RemoveExpiredPendingPassword (void);
#endif

View File

@ -10488,3 +10488,21 @@ unsigned Usr_DB_GetNumUsrsWhoChoseAnOption (const char *SubQuery)
return 0; // Not reached
}
/*****************************************************************************/
/****** Check if a string is found in first name or surnames of anybody ******/
/*****************************************************************************/
bool Usr_DB_FindStrInUsrsNames (const char *Str)
{
return (DB_QueryCOUNT ("can not check if a string matches"
" a first name or a surname",
"SELECT COUNT(*)"
" FROM usr_data"
" WHERE FirstName='%s'"
" OR Surname1='%s'"
" OR Surname2='%s'",
Str,
Str,
Str) != 0);
}

View File

@ -556,4 +556,6 @@ unsigned Usr_DB_GetOldUsrs (MYSQL_RES **mysql_res,time_t SecondsWithoutAccess);
unsigned Usr_DB_GetNumUsrsWhoChoseAnOption (const char *SubQuery);
bool Usr_DB_FindStrInUsrsNames (const char *Str);
#endif