Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions Classes/Domain/Model/Identity/AdministratorToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);

namespace PhpList\PhpList4\Domain\Model\Identity;

/**
* This class represents an API authentication token for an administrator.
*
* @author Oliver Klee <oliver@phplist.com>
*/
class AdministratorToken
{
/**
* @var string
*/
const DEFAULT_EXPIRY = '+1 hour';

/**
* @var int
*/
private $id = 0;

/**
* @var \DateTime
*/
private $expiry = null;

/**
* @var string
*/
private $key = '';

/**
* The Constructor.
*/
public function __construct()
{
$this->setExpiry(new \DateTime());
}

/**
* @return int
*/
public function getId(): int
{
return $this->id;
}

/**
* @return \DateTime
*/
public function getExpiry(): \DateTime
{
return $this->expiry;
}

/**
* @param \DateTime $expiry
*
* @return void
*/
public function setExpiry(\DateTime $expiry)
{
$this->expiry = $expiry;
}

/**
* @return string
*/
public function getKey(): string
{
return $this->key;
}

/**
* @param string $key
*
* @return void
*/
public function setKey(string $key)
{
$this->key = $key;
}

/**
* Generates a new, random key.
*
* @return void
*/
public function generateKey()
{
$key = md5(random_bytes(256));
$this->setKey($key);
}

/**
* Generates and sets an expiry one hour in the future.
*
* @return void
*/
public function generateExpiry()
{
$this->setExpiry(new \DateTime(self::DEFAULT_EXPIRY));
}
}
136 changes: 136 additions & 0 deletions Tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php
declare(strict_types=1);

namespace PhpList\PhpList4\Tests\Unit\Domain\Model\Identity;

use PhpList\PhpList4\Domain\Model\Identity\AdministratorToken;
use PHPUnit\Framework\TestCase;

/**
* Testcase.
*
* @author Oliver Klee <oliver@phplist.com>
*/
class AdministratorTokenTest extends TestCase
{
/**
* @var AdministratorToken
*/
private $subject = null;

protected function setUp()
{
$this->subject = new AdministratorToken();
}

/**
* @test
*/
public function getIdInitiallyReturnsZero()
{
self::assertSame(0, $this->subject->getId());
}

/**
* @test
*/
public function getIdReturnsId()
{
$id = 123456;
$this->setSubjectId($id);

self::assertSame($id, $this->subject->getId());
}

/**
* Sets the (private) ID of $this->subject.
*
* @param int $id
* @return void
* @internal param AdministratorToken $subject
*/
private function setSubjectId(int $id)
{
$reflectionObject = new \ReflectionObject($this->subject);
$reflectionProperty = $reflectionObject->getProperty('id');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($this->subject, $id);
}

/**
* @test
*/
public function getKeyInitiallyReturnsEmptyString()
{
self::assertSame('', $this->subject->getKey());
}

/**
* @test
*/
public function setKeySetsKey()
{
$value = 'Club-Mate';
$this->subject->setKey($value);

self::assertSame($value, $this->subject->getKey());
}

/**
* @test
*/
public function getExpiryInitiallyReturnsDateTime()
{
self::assertInstanceOf(\DateTime::class, $this->subject->getExpiry());
}

/**
* @test
*/
public function setExpirySetsExpiry()
{
$expiry = new \DateTime();
$this->subject->setExpiry($expiry);

self::assertSame($expiry, $this->subject->getExpiry());
}

/**
* @test
*/
public function generateExpirySetsExpiryOneHourInTheFuture()
{
$expectedExpiry = new \DateTime('+1 hour');

$this->subject->generateExpiry();

$actualExpiry = $this->subject->getExpiry();
$difference = $actualExpiry->diff($expectedExpiry, true);
$differenceInSeconds = $difference->s + $difference->i * 60 + $difference->h * 3600;
self::assertLessThan(2, $differenceInSeconds);
}

/**
* @test
*/
public function generateKeyCreates32CharacterKey()
{
$this->subject->generateKey();

self::assertRegExp('/^[a-z0-9]{32}$/', $this->subject->getKey());
}

/**
* @test
*/
public function generateKeyCreatesDifferentKeysForEachCall()
{
$this->subject->generateKey();
$firstKey = $this->subject->getKey();

$this->subject->generateKey();
$secondKey = $this->subject->getKey();

self::assertNotSame($firstKey, $secondKey);
}
}