Commit e99f075c authored by Jacob Priddy's avatar Jacob Priddy 👌

Make saml update users and make login tokens be generated in one place

parent 7fa32703
Pipeline #10732 passed with stages
in 2 minutes and 51 seconds
......@@ -85,6 +85,7 @@ class TokensController extends ApiController
$presenter = new CreateTokenAPIPresenter();
// Not worried about throwing invalid argument exception as name is required in validation
$createToken->create($this->request->all(), $presenter);
return $this->respondWithData($presenter->getViewModel());
......
......@@ -15,8 +15,7 @@ class LocalSchedulesRepository extends InMemorySchedulesRepository
1,
LocalGroupsRepository::getEngineeringLabAccessGroup()->getId(),
Schedule::TYPE_USER_ACCESS,
// Allowed for a minute, not allowed for the next minute
'RRULE:FREQ=SECONDLY;INTERVAL=10',
'RRULE:FREQ=HOURLY;INTERVAL=10',
60,
'Engineering lab user access schedule, every other minute for a minute',
Carbon::now()
......@@ -26,8 +25,7 @@ class LocalSchedulesRepository extends InMemorySchedulesRepository
2,
LocalGroupsRepository::getComputerScienceMajorGroup()->getId(),
Schedule::TYPE_OPEN_MODE,
// Open mode for 10 mintes, not open mode for 10 minutes
'RRULE:FREQ=MINUTELY;INTERVAL=20',
'RRULE:FREQ=MINUTELY;INTERVAL=50',
60 * 10,
'Computer science lab open mode schedule, every 20 minutes for 10 minutes',
Carbon::now()
......
......@@ -29,15 +29,28 @@ class DatabaseTokensRepository implements TokensRepository
$dbToken = new \App\Token();
$dbToken->setAttribute('name', $token->getName());
$dbToken->setAttribute('user_id', $token->getUserId());
$dbToken->setAttribute('api_token', $token->getTokenString());
$dbToken->setAttribute('expires_at', $token->getExpiresAt());
/** @var \App\Token $dbToken */
$dbToken = $user->tokens()->save($dbToken);
$dbToken->save();
return self::dbTokenToToken($dbToken);
}
/**
* @inheritDoc
*/
public function createLoginToken(string $userId): Token
{
return $this->create(new Token(
0,
$userId,
self::generateTokenString(),
null,
Carbon::now()->addDay()
));
}
/**
* @inheritDoc
*/
......
......@@ -28,6 +28,22 @@ class InMemoryTokensRepository implements TokensRepository
return $token;
}
/**
* @inheritDoc
*/
public function createLoginToken(string $userId): Token
{
$token = new Token(
static::$idCounter++,
$userId,
self::generateTokenString(),
null,
Carbon::now()->addDay()
);
$this->tokens[] = $token;
return $token;
}
/**
* @inheritDoc
*/
......
......@@ -16,6 +16,13 @@ interface TokensRepository
*/
public function create(Token $token): Token;
/**
* @param string $userId
* @return \Source\Entities\Token
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function createLoginToken(string $userId): Token;
/**
* @param string $tokenId
* @param \Source\Entities\Token $token
......
......@@ -5,6 +5,7 @@ namespace Source\UseCases\Tokens\CreateToken;
use Carbon\Carbon;
use Source\Entities\Token;
use Source\Sanitize\CastsTo;
use InvalidArgumentException;
use Source\Entities\HashedSearchable;
use Source\Gateways\Tokens\TokensRepository;
......@@ -34,6 +35,11 @@ class CreateToken implements CreateTokenUseCase
*/
public function create(array $attributes, Presenter $presenter): void
{
$name = $attributes['name'] ?? null;
if (!$name) {
throw new InvalidArgumentException('Name cannot be null');
}
$tokenString = $this->tokens::generateTokenString();
$date = null;
......@@ -46,7 +52,7 @@ class CreateToken implements CreateTokenUseCase
0,
$this->castToInt($attributes['user_id']),
HashedSearchable::hash($this->salt, $tokenString),
$attributes['name'] ?? null,
$name,
$date
)
);
......
......@@ -8,14 +8,15 @@ interface CreateTokenUseCase
/**
* Required Attributes:
* - user_id
* - name
* Optional Attributes:
* - expires_at
* - name
*
* @param array $attributes
* @param \Source\UseCases\Tokens\CreateToken\Presenter $presenter
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Exception
* @throws \InvalidArgumentException
*/
public function create(array $attributes, Presenter $presenter): void;
}
......@@ -2,9 +2,7 @@
namespace Source\UseCases\Users\Authenticate;
use Carbon\Carbon;
use Source\Entities\User;
use Source\Entities\Token;
use Source\Gateways\Saml\SamlRepository;
use Source\Gateways\Users\UsersRepository;
use Source\Gateways\Tokens\TokensRepository;
......@@ -59,15 +57,7 @@ class Authenticate implements AuthenticateUseCase
throw new AuthenticationException();
}
$token = $this->tokens->create(
new Token(
0,
$user->getId(),
$this->tokens::generateTokenString(),
null,
Carbon::now()->addDays(2)
)
);
$token = $this->tokens->createLoginToken($user->getId());
$response = new ResponseModel($user, $token);
......@@ -98,33 +88,35 @@ class Authenticate implements AuthenticateUseCase
// If the user does not exist, create them.
if (!$user) {
$user = $this->users->create(
new User(
0,
$samlUser->getFirstName(),
$samlUser->getLastName(),
$samlUser->getDisplayName(),
$samlUser->getEmail(),
$samlUser->getEmplid(),
null,
null
)
);
$user = $this->users->create(new User(
0,
$samlUser->getFirstName(),
$samlUser->getLastName(),
$samlUser->getDisplayName(),
$samlUser->getEmail(),
$samlUser->getEmplid()
));
} else {
$user = $this->users->update($user->getId(), new User(
$user->getId(),
$samlUser->getFirstName(),
$samlUser->getLastName(),
$samlUser->getDisplayName(),
$samlUser->getEmail(),
$samlUser->getEmplid(),
$user->getPassword(),
$user->getDoorcode(),
$user->getExpiresAt(),
$user->getCreatedAt(),
$user->getUpdatedAt()
));
}
if (!$user) {
throw new UserCreationException();
}
$token = $this->tokens->create(
new Token(
0,
$user->getId(),
$this->tokens::generateTokenString(),
null,
Carbon::now()->addDays(2)
)
);
$token = $this->tokens->createLoginToken($user->getId());
$response = new ResponseModel($user, $token);
......
......@@ -40,6 +40,7 @@ interface AuthenticateUseCase
* @param Presenter $presenter
* @throws UserCreationException
* @throws EntityNotFoundException
* @throws \Source\Exceptions\EntityExistsException
*/
public function handleSamlLogin(Presenter $presenter): void;
}
......@@ -31,6 +31,7 @@ class AttemptUseCaseTest extends UseCaseBaseTest
/**
* @return \Source\Entities\User
* @throws \Source\Exceptions\EntityExistsException
*/
protected function createUser(): User
{
......@@ -49,6 +50,7 @@ class AttemptUseCaseTest extends UseCaseBaseTest
* @test
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_calls_present_on_presenter(): void
{
......@@ -79,6 +81,7 @@ class AttemptUseCaseTest extends UseCaseBaseTest
* @param array $credentials
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_cannot_find_users_for_invalid_input(array $credentials): void
{
......@@ -93,6 +96,7 @@ class AttemptUseCaseTest extends UseCaseBaseTest
* @test
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_creates_a_token_for_the_user(): void
{
......@@ -102,8 +106,8 @@ class AttemptUseCaseTest extends UseCaseBaseTest
$this->assertCount(1, $this->tokens->filter());
$token = $this->tokens->filter()[0];
$this->assertLessThan(Carbon::now()->addDays(2), $token->getExpiresAt());
$this->assertGreaterThan(Carbon::now()->addDays(1), $token->getExpiresAt());
$this->assertLessThan(Carbon::now()->addHours(25), $token->getExpiresAt());
$this->assertGreaterThan(Carbon::now()->subHours(23), $token->getExpiresAt());
$this->assertEquals($user->getId(), $token->getUserId());
$this->assertEquals(60, strlen($token->getTokenString()));
$this->assertEquals($token, $this->response->getToken());
......@@ -113,6 +117,7 @@ class AttemptUseCaseTest extends UseCaseBaseTest
* @test
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_authenticates_a_user(): void
{
......
......@@ -19,6 +19,7 @@ class SamlUseCaseTest extends UseCaseBaseTest
* @param \Source\Entities\SamlUser|null $samlUser
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\UseCases\Users\Authenticate\UserCreationException
* @throws \Source\Exceptions\EntityExistsException
*/
protected function handleLoginTest(?SamlUser $samlUser = null): void
{
......@@ -33,6 +34,7 @@ class SamlUseCaseTest extends UseCaseBaseTest
/**
* @return \Source\Entities\User
* @throws \Source\Exceptions\EntityExistsException
*/
protected function createUser(): User
{
......@@ -51,6 +53,7 @@ class SamlUseCaseTest extends UseCaseBaseTest
* @test
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\UseCases\Users\Authenticate\UserCreationException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_calls_present_on_presenter(): void
{
......@@ -82,6 +85,7 @@ class SamlUseCaseTest extends UseCaseBaseTest
/**
* @test
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_invalidates_token_on_saml_logout(): void
{
......@@ -96,6 +100,7 @@ class SamlUseCaseTest extends UseCaseBaseTest
* @test
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\UseCases\Users\Authenticate\UserCreationException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_cannot_create_null_users(): void
{
......@@ -108,6 +113,7 @@ class SamlUseCaseTest extends UseCaseBaseTest
* @test
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\UseCases\Users\Authenticate\UserCreationException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_creates_a_user_if_they_do_not_exist_in_local_database(): void
{
......@@ -132,6 +138,7 @@ class SamlUseCaseTest extends UseCaseBaseTest
* @test
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\UseCases\Users\Authenticate\UserCreationException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_throws_an_exception_if_it_cannot_create_a_user(): void
{
......@@ -146,6 +153,7 @@ class SamlUseCaseTest extends UseCaseBaseTest
* @test
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\UseCases\Users\Authenticate\UserCreationException
* @throws \Source\Exceptions\EntityExistsException
*/
public function it_creates_a_token_for_the_user(): void
{
......@@ -156,10 +164,31 @@ class SamlUseCaseTest extends UseCaseBaseTest
$this->assertCount(1, $this->tokens->filter());
$token = $this->tokens->filter()[0];
$this->assertLessThan(Carbon::now()->addDays(2), $token->getExpiresAt());
$this->assertGreaterThan(Carbon::now()->addDays(1), $token->getExpiresAt());
$this->assertLessThan(Carbon::now()->addHours(25), $token->getExpiresAt());
$this->assertGreaterThan(Carbon::now()->subHours(23), $token->getExpiresAt());
$this->assertEquals($user->getId(), $token->getUserId());
$this->assertEquals(60, strlen($token->getTokenString()));
$this->assertEquals($token, $this->response->getToken());
}
/**
* @test
* @throws \Source\Exceptions\EntityExistsException
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\UseCases\Users\Authenticate\UserCreationException
*/
public function it_updates_existing_users(): void
{
$samlUser = $this->createSamlUser();
$this->users->create(new User(0, '', '', '', $samlUser->getEmail()));
$this->handleLoginTest($samlUser);
$users = $this->users->search();
$this->assertCount(1, $users);
$this->assertEquals($samlUser->getEmplid(), $users[0]->getEmplid());
$this->assertEquals($samlUser->getFirstName(), $users[0]->getFirstName());
$this->assertEquals($samlUser->getLastName(), $users[0]->getLastName());
$this->assertEquals($samlUser->getDisplayName(), $users[0]->getDisplayName());
$this->assertEquals($samlUser->getEmail(), $users[0]->getEmail());
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment