<commit_before>/*
	Flexisip, a flexible SIP proxy server with media capabilities.
	Copyright (C) 2010  Belledonne Communications SARL.

	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/>.
*/

#ifndef _AUTHDB_HH_
#define _AUTHDB_HH_

#include <string>
#include <mutex>

#include "common.hh"
#include "agent.hh"

#include <vector>
#include <stdio.h>

#if ENABLE_ODBC
#include <sql.h>
#include <sqlext.h>
#endif

#include <map>
#include <set>
#include <thread>

#include "sofia-sip/auth_module.h"
#include "sofia-sip/auth_plugin.h"

enum AuthDbResult { PENDING, PASSWORD_FOUND, PASSWORD_NOT_FOUND, AUTH_ERROR };

// Fw declaration
struct AuthDbTimings;

class AuthDbListener : public StatFinishListener {
  public:
	virtual void onResult(AuthDbResult result, const std::string &passwd) = 0;
	virtual void onResults(std::list<std::string> &phones, set<std::string> &users);
	virtual ~AuthDbListener();
};

class AuthDbBackend {
	static AuthDbBackend *sUnique;

	struct CachedPassword {
		std::string pass;
		time_t expire_date;
		CachedPassword(const std::string &ipass, time_t idate) : pass(<PASSWORD>), expire_date(idate) {
		}
	};

	private:
	std::map<std::string, std::map<std::string, CachedPassword>> mCachedPasswords;
	std::mutex mCachedPasswordMutex;
	std::mutex mCachedUserWithPhoneMutex;
	std::map<std::string, std::string> mPhone2User;

  protected:
	AuthDbBackend();
	enum CacheResult { VALID_PASS_FOUND, EXPIRED_PASS_FOUND, NO_PASS_FOUND };
	std::string createPasswordKey(const std::string &user, const std::string &auth);
	bool cachePassword(const std::string &key, const std::string &domain, const std::string &pass, int expires);
	bool cacheUserWithPhone(const std::string &phone, const std::string &domain, const std::string &user);
	CacheResult getCachedPassword(const std::string &key, const std::string &domain, std::string &pass);
	CacheResult getCachedUserWithPhone(const string &phone, const string &domain, string &user);
	void createCachedAccount(const std::string & user, const std::string & domain, const std::string &auth_username, const std::string &password, int expires, const std::string & phone_alias = "");
	void clearCache();
	int mCacheExpire;
  public:
	virtual ~AuthDbBackend();
	// warning: listener may be invoked on authdb backend thread, so listener must be threadsafe somehow!
	void getPassword(const std::string & user, const std::string & domain, const std::string &auth_username, AuthDbListener *listener);
	void getUserWithPhone(const std::string &phone, const std::string &domain, AuthDbListener *listener);
	void getUsersWithPhone(std::list<std::tuple<std::string,std::string,AuthDbListener *>> & creds, AuthDbListener *listener);
	virtual void getUserWithPhoneFromBackend(const std::string &, const std::string &, AuthDbListener *listener) = 0;
	virtual void getUsersWithPhonesFromBackend(std::list<std::tuple<std::string,std::string,AuthDbListener*>> &creds, AuthDbListener *listener);

	virtual void createAccount(const std::string &user, const std::string & domain, const std::string &auth_username, const std::string &password, int expires, const std::string &phone_alias = "");

	virtual void getPasswordFromBackend(const std::string &id, const std::string &domain,
										const std::string &authid, AuthDbListener *listener) = 0;

	static AuthDbBackend *get();
	/* called by module_auth so that backends can declare their configuration to the ConfigurationManager */<commit_msg>keep stding<commit_after>/*
	Flexisip, a flexible SIP proxy server with media capabilities.
	Copyright (C) 2010  Belledonne Communications SARL.

	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/>.
*/

#ifndef _AUTHDB_HH_
#define _AUTHDB_HH_

#include <string>
#include <mutex>

#include "common.hh"
#include "agent.hh"

#include <vector>
#include <stdio.h>

#if ENABLE_ODBC
#include <sql.h>
#include <sqlext.h>
#endif

#include <map>
#include <set>
#include <thread>

#include "sofia-sip/auth_module.h"
#include "sofia-sip/auth_plugin.h"

enum AuthDbResult { PENDING, PASSWORD_FOUND, PASSWORD_NOT_FOUND, AUTH_ERROR };

// Fw declaration
struct AuthDbTimings;

class AuthDbListener : public StatFinishListener {
  public:
	virtual void onResult(AuthDbResult result, const std::string &passwd) = 0;
	virtual void onResults(std::list<std::string> &phones, set<std::string> &users);
	virtual ~AuthDbListener();
};

class AuthDbBackend {
	static AuthDbBackend *sUnique;

	struct CachedPassword {
		std::string pass;
		time_t expire_date;
		CachedPassword(const std::string &ipass, time_t idate) : pass(ipass), expire_date(idate) {
		}
	};

	private:
	std::map<std::string, std::map<std::string, CachedPassword>> mCachedPasswords;
	std::mutex mCachedPasswordMutex;
	std::mutex mCachedUserWithPhoneMutex;
	std::map<std::string, std::string> mPhone2User;

  protected:
	AuthDbBackend();
	enum CacheResult { VALID_PASS_FOUND, EXPIRED_PASS_FOUND, NO_PASS_FOUND };
	std::string createPasswordKey(const std::string &user, const std::string &auth);
	bool cachePassword(const std::string &key, const std::string &domain, const std::string &pass, int expires);
	bool cacheUserWithPhone(const std::string &phone, const std::string &domain, const std::string &user);
	CacheResult getCachedPassword(const std::string &key, const std::string &domain, std::string &pass);
	CacheResult getCachedUserWithPhone(const std::string &phone, const std::string &domain, std::string &user);
	void createCachedAccount(const std::string & user, const std::string & domain, const std::string &auth_username, const std::string &password, int expires, const std::string & phone_alias = "");
	void clearCache();
	int mCacheExpire;
  public:
	virtual ~AuthDbBackend();
	// warning: listener may be invoked on authdb backend thread, so listener must be threadsafe somehow!
	void getPassword(const std::string & user, const std::string & domain, const std::string &auth_username, AuthDbListener *listener);
	void getUserWithPhone(const std::string &phone, const std::string &domain, AuthDbListener *listener);
	void getUsersWithPhone(std::list<std::tuple<std::string,std::string,AuthDbListener *>> & creds, AuthDbListener *listener);
	virtual void getUserWithPhoneFromBackend(const std::string &, const std::string &, AuthDbListener *listener) = 0;
	virtual void getUsersWithPhonesFromBackend(std::list<std::tuple<std::string,std::string,AuthDbListener*>> &creds, AuthDbListener *listener);

	virtual void createAccount(const std::string &user, const std::string & domain, const std::string &auth_username, const std::string &password, int expires, const std::string &phone_alias = "");

	virtual void getPasswordFromBackend(const std::string &id, const std::string &domain,
										const std::string &authid, AuthDbListener *listener) = 0;

	static AuthDbBackend *get();
	/* called by module_auth so that backends can declare their configuration to the ConfigurationManager */
{'fraction_non_alphanumeric': 0.10849056603773585, 'fraction_numerical': 0.0022343594836146973, 'mean_word_length': 6.258558558558558, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5235303', 'n_tokens_mistral': 2479, 'n_tokens_neox': 2419, 'n_words': 793}