Created File* backends
parent
57a2da32cb
commit
498e00b7d2
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
namespace SmsGateway\Auth;
|
||||
|
||||
use SmsGateway\AuthInterface;
|
||||
use SmsGateway\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Description of FileAuth
|
||||
*
|
||||
* @author Gergely Polonkai
|
||||
*/
|
||||
class FileAuth implements AuthInterface
|
||||
{
|
||||
private $logger;
|
||||
|
||||
private $sendersFile;
|
||||
|
||||
private $tokenFile;
|
||||
|
||||
public function __construct($sendersFile, $tokenFile) {
|
||||
if ($sendersFile == null) {
|
||||
throw new \InvalidArgumentException('A senders file path must be passed to the authenticator!');
|
||||
}
|
||||
|
||||
if (!is_readable($sendersFile)) {
|
||||
throw new \RuntimeException('senders file not readable!');
|
||||
}
|
||||
|
||||
if ($tokenFile == null) {
|
||||
throw new \InvalidArgumentException('A token file path must be passed to the authenticator!');
|
||||
}
|
||||
|
||||
if (
|
||||
(
|
||||
file_exists($tokenFile)
|
||||
&& !is_writable($tokenFile)
|
||||
)
|
||||
|| (
|
||||
!file_exists($tokenFile)
|
||||
&& !is_writable(dirname($tokenFile))
|
||||
)
|
||||
) {
|
||||
throw new \RuntimeException('Token file is not writable!');
|
||||
}
|
||||
|
||||
$this->sendersFile = $sendersFile;
|
||||
$this->tokenFile = $tokenFile;
|
||||
}
|
||||
|
||||
public function authenticate($username, $password, $ip, $sessionId)
|
||||
{
|
||||
$this->logger->auditLog(LoggerInterface::LOG_AUDIT_LOGIN, $username, "trying to authenticate");
|
||||
$lines = file($this->sendersFile);
|
||||
foreach ($lines as $line) {
|
||||
list($user, $cPassword) = explode(':', trim($line), 2);
|
||||
if ($user == $username) {
|
||||
if (crypt($password, $cPassword) == $cPassword) {
|
||||
$this->logger->auditLog(LoggerInterface::LOG_AUDIT_LOGIN, $username, "authenticated successfully");
|
||||
|
||||
return $this->getToken($username, $ip, $sessionId);
|
||||
} else {
|
||||
$this->logger->auditLog(LoggerInterface::LOG_AUDIT_LOGIN, $username, "authentication failed: bad password");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getTokenUsername($token, $ip, $sessionId)
|
||||
{
|
||||
$lines = file($this->tokenFile);
|
||||
foreach ($lines as $line) {
|
||||
list($tokenUser, $tokenIp, $tokenSession, $tokenToken) = explode(':', trim($line), 4);
|
||||
if (($tokenToken == $token) && ($tokenIp == $ip) && ($tokenSession == $sessionId)) {
|
||||
return $tokenUser;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isTokenValid($token, $ip, $sessionId)
|
||||
{
|
||||
$this->logger->auditLog(LoggerInterface::LOG_AUDIT_LOGIN, null, 'Checking token validity');
|
||||
|
||||
$lines = file($this->tokenFile);
|
||||
foreach ($lines as $line) {
|
||||
list($tokenUser, $tokenIp, $tokenSession, $tokenToken) = explode(':', trim($line), 4);
|
||||
if (($tokenToken == $token) && ($tokenIp == $ip) && ($tokenSession == $sessionId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getToken($username, $ip, $sessionId) {
|
||||
$this->logger->auditLog(LoggerInterface::LOG_AUDIT_LOGIN, $username, "Getting token");
|
||||
|
||||
$lines = file($this->tokenFile);
|
||||
foreach ($lines as $line) {
|
||||
list($tokenUser, $tokenIp, $tokenSession, $tokenToken) = explode(':', trim($line), 4);
|
||||
if (($tokenUser == $username) && ($tokenIp == $ip) && ($tokenSession == $sessionId)) {
|
||||
return $tokenToken;
|
||||
}
|
||||
}
|
||||
|
||||
$token = str_replace(':', '', uniqid('', true));
|
||||
$fd = fopen($this->tokenFile, 'a');
|
||||
fwrite($fd, sprintf("%s:%s:%s:%s\n", $username, $ip, $sessionId, $token));
|
||||
fclose($fd);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function removeToken($token, $ip, $sessionId) {
|
||||
$username = $this->getTokenUsername($token, $ip, $sessionId);
|
||||
$this->logger->auditLog(LoggerInterface::LOG_AUDIT_LOGIN, $username, "Removing token");
|
||||
|
||||
$lines = file($this->tokenFile);
|
||||
$fd = fopen($this->tokenFile, 'w');
|
||||
foreach ($lines as $line) {
|
||||
list($tokenUser, $tokenIp, $tokenSession, $tokenToken) = explode(':', trim($line), 4);
|
||||
if (($tokenToken != $token) || ($tokenIp != $ip) || ($tokenSession != $sessionId)) {
|
||||
fwrite($fd, sprintf("%s:%s:%s:%s\n", $tokenUser, $tokenIp, $tokenSession, $tokenToken));
|
||||
}
|
||||
}
|
||||
fclose($fd);
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLogger() {
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
public function setLogger(LoggerInterface $logger) {
|
||||
$this->logger = $logger;
|
||||
}
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
namespace SmsGateway\Logger;
|
||||
|
||||
use SmsGateway\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Description of FileLogger
|
||||
*
|
||||
* @author Gergely Polonkai
|
||||
*/
|
||||
class FileLogger implements LoggerInterface
|
||||
{
|
||||
const PASSWORD_MASK = '[password]';
|
||||
|
||||
/**
|
||||
* The message log file
|
||||
*
|
||||
* @var resource $messageLogHandle
|
||||
*/
|
||||
private $messageLogHandle;
|
||||
|
||||
/**
|
||||
* The audit log file
|
||||
*
|
||||
* @var resource $auditLogHandle
|
||||
*/
|
||||
private $auditLogHandle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $messageLogFile Name of the message log file
|
||||
* @param string $auditLogFile Name of the audit log file
|
||||
* @throws \LogicException Upon file opening error
|
||||
*/
|
||||
public function __construct($messageLogFile, $auditLogFile)
|
||||
{
|
||||
if ($messageLogFile == null) {
|
||||
throw new \LogicException('Message log file can not be null!');
|
||||
}
|
||||
|
||||
if ($auditLogFile == null) {
|
||||
throw new \LogicException('Audit log file can not be null!');
|
||||
}
|
||||
|
||||
if (
|
||||
(
|
||||
file_exists($messageLogFile)
|
||||
&& !is_writable($messageLogFile)
|
||||
)
|
||||
|| (
|
||||
!file_exists($messageLogFile)
|
||||
&& !is_writable(dirname($messageLogFile))
|
||||
)
|
||||
) {
|
||||
throw new \LogicException('Message log file is not writable!');
|
||||
}
|
||||
|
||||
if (
|
||||
(
|
||||
file_exists($auditLogFile)
|
||||
&& !is_writable($auditLogFile)
|
||||
)
|
||||
|| (
|
||||
!file_exists($auditLogFile)
|
||||
&& !is_writable(dirname($auditLogFile))
|
||||
)
|
||||
) {
|
||||
throw new \LogicException('Audit log file is not writable!');
|
||||
}
|
||||
|
||||
if (($this->messageLogHandle = fopen($messageLogFile, 'a')) === false) {
|
||||
throw new \LogicException('Message log file could not be opened!');
|
||||
}
|
||||
|
||||
if (($this->auditLogHandle = fopen($auditLogFile, 'a')) === false) {
|
||||
throw new \LogicException('Audit log file could not be opened!');
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
fclose($this->messageLogHandle);
|
||||
fclose($this->auditLogHandle);
|
||||
}
|
||||
|
||||
private function orderPasswordLocations($a, $b)
|
||||
{
|
||||
if ($a[0] == $b[0]) {
|
||||
return 0;
|
||||
} elseif ($a[0] < $b[0]) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function messageLog($username, $recipient, $message, array $passwordLocations)
|
||||
{
|
||||
usort($passwordLocations, array($this, 'orderPasswordLocations'));
|
||||
|
||||
$encodedMessage = $message;
|
||||
$mod = 0;
|
||||
foreach ($passwordLocations as $loc) {
|
||||
list($pos, $length) = $loc;
|
||||
|
||||
$encodedMessage = substr_replace($encodedMessage, self::PASSWORD_MASK, $pos + $mod, $length);
|
||||
$mod += (strlen(self::PASSWORD_MASK) - $length);
|
||||
}
|
||||
|
||||
$logMessage = "From $username
|
||||
From: $username
|
||||
To: $recipient
|
||||
|
||||
$encodedMessage\n\n";
|
||||
|
||||
fwrite($this->messageLogHandle, $logMessage);
|
||||
fflush($this->messageLogHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function auditLog($type, $username, $message)
|
||||
{
|
||||
if ($username === null) {
|
||||
$logMessage = "$message\n";
|
||||
} else {
|
||||
$logMessage = "$username: $message\n";
|
||||
}
|
||||
fwrite($this->auditLogHandle, $logMessage);
|
||||
fflush($this->auditLogHandle);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
namespace SmsGateway\Sender;
|
||||
|
||||
use SmsGateway\SenderInterface;
|
||||
use SmsGateway\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Description of FileSender
|
||||
*
|
||||
* @author Gergely Polonkai
|
||||
*/
|
||||
class FileSender implements SenderInterface
|
||||
{
|
||||
private $messageDir;
|
||||
|
||||
/**
|
||||
* @var SmsGateway\LoggerInterface $logger
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
public function __construct($messageDir)
|
||||
{
|
||||
if (file_exists($messageDir) && !is_dir($messageDir)) {
|
||||
throw new \InvalidArgumentException('Message directory specified is not a directory!');
|
||||
}
|
||||
|
||||
if (!file_exists($messageDir) && !is_writable(dirname($messageDir))) {
|
||||
throw new \RuntimeException('Message directory cannot be created');
|
||||
}
|
||||
|
||||
if (!file_exists($messageDir)) {
|
||||
mkdir($messageDir, 0777, true);
|
||||
}
|
||||
|
||||
if (!is_writable($messageDir)) {
|
||||
throw new \RuntimeException('Message directory is not writable!');
|
||||
}
|
||||
|
||||
$this->messageDir = $messageDir;
|
||||
}
|
||||
|
||||
public function setLogger(LoggerInterface $logger) {
|
||||
if ($logger === null) {
|
||||
throw new \InvalidArgumentException('A logger must be passed to the authenticator!');
|
||||
}
|
||||
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function getLogger() {
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
public function send($username, $recipient, $message, $passwordLocations)
|
||||
{
|
||||
$rcptDir = $this->messageDir . '/' . $recipient;
|
||||
|
||||
if (file_exists($rcptDir) && (!is_writable($rcptDir) || !is_dir($rcptDir))) {
|
||||
throw new \RuntimeException('Message directory is not writable!');
|
||||
}
|
||||
if (!file_exists($rcptDir)) {
|
||||
mkdir($rcptDir);
|
||||
}
|
||||
|
||||
$messageFileName = date('YmdHis') . '-' . uniqid() . '.sms';
|
||||
$fd = fopen($rcptDir . '/' . $messageFileName, 'w');
|
||||
fwrite($fd, $message);
|
||||
fclose($fd);
|
||||
|
||||
$this->logger->messageLog($username, $recipient, $message, $passwordLocations);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue