Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
D
Doorcode
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
5
Issues
5
List
Boards
Labels
Service Desk
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Guardians of the Kretschmar Elock System
Doorcode
Commits
87df45f6
Commit
87df45f6
authored
Feb 18, 2020
by
Jacob Priddy
👌
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add login route
parent
b86f1216
Pipeline
#1585
passed with stages
in 1 minute and 38 seconds
Changes
17
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
309 additions
and
8 deletions
+309
-8
src/web/backend/app/Http/Controllers/AuthController.php
src/web/backend/app/Http/Controllers/AuthController.php
+45
-0
src/web/backend/app/Providers/AppServiceProvider.php
src/web/backend/app/Providers/AppServiceProvider.php
+2
-0
src/web/backend/routes/api.php
src/web/backend/routes/api.php
+3
-0
src/web/backend/src/Entities/Token.php
src/web/backend/src/Entities/Token.php
+15
-0
src/web/backend/src/Entities/User.php
src/web/backend/src/Entities/User.php
+1
-0
src/web/backend/src/Exceptions/AuthorizationException.php
src/web/backend/src/Exceptions/AuthorizationException.php
+14
-0
src/web/backend/src/Gateways/Tokens/DatabaseTokensRepository.php
.../backend/src/Gateways/Tokens/DatabaseTokensRepository.php
+10
-4
src/web/backend/src/Gateways/Tokens/InMemoryTokensRepository.php
.../backend/src/Gateways/Tokens/InMemoryTokensRepository.php
+6
-2
src/web/backend/src/Gateways/Tokens/TokensRepository.php
src/web/backend/src/Gateways/Tokens/TokensRepository.php
+1
-1
src/web/backend/src/UseCases/BasePresenter.php
src/web/backend/src/UseCases/BasePresenter.php
+13
-0
src/web/backend/src/UseCases/Token/Authenticate/Authenticate.php
.../backend/src/UseCases/Token/Authenticate/Authenticate.php
+1
-1
src/web/backend/src/UseCases/Users/Authenticate/APIPresenter.php
.../backend/src/UseCases/Users/Authenticate/APIPresenter.php
+26
-0
src/web/backend/src/UseCases/Users/Authenticate/Authenticate.php
.../backend/src/UseCases/Users/Authenticate/Authenticate.php
+53
-0
src/web/backend/src/UseCases/Users/Authenticate/AuthenticateUseCase.php
...d/src/UseCases/Users/Authenticate/AuthenticateUseCase.php
+20
-0
src/web/backend/src/UseCases/Users/Authenticate/AuthenticateUseCaseServiceProvider.php
...Users/Authenticate/AuthenticateUseCaseServiceProvider.php
+42
-0
src/web/backend/src/UseCases/Users/Authenticate/Presenter.php
...web/backend/src/UseCases/Users/Authenticate/Presenter.php
+16
-0
src/web/backend/src/UseCases/Users/Authenticate/ResponseModel.php
...backend/src/UseCases/Users/Authenticate/ResponseModel.php
+41
-0
No files found.
src/web/backend/app/Http/Controllers/AuthController.php
0 → 100644
View file @
87df45f6
<?php
namespace
App\Http\Controllers
;
use
Illuminate\Http\Request
;
use
Illuminate\Http\JsonResponse
;
use
Illuminate\Auth\AuthenticationException
;
use
Source\Exceptions\AuthorizationException
;
use
Illuminate\Validation\ValidationException
;
use
Source\Exceptions\EntityNotFoundException
;
use
Source\UseCases\Users\Authenticate\APIPresenter
;
use
Source\UseCases\Users\Authenticate\AuthenticateUseCase
;
class
AuthController
extends
ApiController
{
protected
Request
$request
;
public
function
__construct
(
Request
$request
)
{
$this
->
request
=
$request
;
}
/**
* @param AuthenticateUseCase $authenticateUseCase
* @return JsonResponse
* @throws ValidationException
* @throws AuthenticationException
* @throws EntityNotFoundException
*/
public
function
login
(
AuthenticateUseCase
$authenticateUseCase
):
JsonResponse
{
$this
->
validate
(
$this
->
request
,
[
'email'
=>
'required'
,
'password'
=>
'required'
]);
$presenter
=
new
APIPresenter
();
try
{
$authenticateUseCase
->
attempt
(
$presenter
,
$this
->
request
->
all
());
}
catch
(
AuthorizationException
$e
)
{
throw
new
AuthenticationException
();
}
return
$this
->
respondWithData
(
$presenter
->
getViewModel
());
}
}
src/web/backend/app/Providers/AppServiceProvider.php
View file @
87df45f6
...
...
@@ -13,6 +13,7 @@ use Source\UseCases\Users\UpdateUser\UpdateUserUseCaseServiceProvider;
use
Source\UseCases\Users\GetAllUsers\GetAllUsersUseCaseServiceProvider
;
use
Source\UseCases\Token\Authenticate\AuthenticateUseCaseServiceProvider
;
use
Source\UseCases\Doors\Authenticate\AuthenticateUseCaseServiceProvider
as
DoorAuthenticateUseCaseServiceProvider
;
use
Source\UseCases\Users\Authenticate\AuthenticateUseCaseServiceProvider
as
UserAuthenticateUseCaseServiceProvider
;
class
AppServiceProvider
extends
ServiceProvider
{
...
...
@@ -38,6 +39,7 @@ class AppServiceProvider extends ServiceProvider
AuthenticateUseCaseServiceProvider
::
class
,
DoorAuthenticateUseCaseServiceProvider
::
class
,
UserAuthenticateUseCaseServiceProvider
::
class
,
];
/**
...
...
src/web/backend/routes/api.php
View file @
87df45f6
...
...
@@ -2,6 +2,7 @@
use
Illuminate\Http\Request
;
use
Illuminate\Support\Facades\Route
;
use
App\Http\Controllers\AuthController
;
use
App\Http\Controllers\UsersController
;
/*
...
...
@@ -14,6 +15,8 @@ use App\Http\Controllers\UsersController;
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route
::
post
(
'login'
,
[
AuthController
::
class
,
'login'
]);
Route
::
group
([
'middleware'
=>
'auth:api'
],
static
function
()
{
Route
::
group
(
[
...
...
src/web/backend/src/Entities/Token.php
View file @
87df45f6
...
...
@@ -128,4 +128,19 @@ class Token {
public
function
getUpdatedAt
():
?Carbon
{
return
$this
->
updatedAt
;
}
/**
* @param int $id
*/
public
function
setId
(
int
$id
):
void
{
$this
->
id
=
$id
;
}
/**
* @param Carbon $date
* @return bool
*/
public
function
isValidAtTime
(
Carbon
$date
):
bool
{
return
$this
->
expiresAt
===
null
||
$this
->
expiresAt
->
isAfter
(
$date
);
}
}
src/web/backend/src/Entities/User.php
View file @
87df45f6
...
...
@@ -199,6 +199,7 @@ class User {
if
(
!
$password
||
!
$email
)
{
return
false
;
}
return
$this
->
getEmail
()
===
$email
&&
$this
->
getPassword
()
===
$password
;
}
...
...
src/web/backend/src/Exceptions/AuthorizationException.php
0 → 100644
View file @
87df45f6
<?php
namespace
Source\Exceptions
;
use
Exception
;
use
Throwable
;
class
AuthorizationException
extends
Exception
{
public
function
__construct
(
$message
=
'Unauthorized'
,
$code
=
0
,
Throwable
$previous
=
null
)
{
parent
::
__construct
(
$message
,
$code
,
$previous
);
}
}
src/web/backend/src/Gateways/Tokens/DatabaseTokensRepository.php
View file @
87df45f6
...
...
@@ -5,7 +5,9 @@ namespace Source\Gateways\Tokens;
use
App\User
;
use
Carbon\Carbon
;
use
Source\Entities\Token
;
use
Basho\Riak\Node\Builder
;
use
Source\Exceptions\EntityNotFoundException
;
class
DatabaseTokensRepository
implements
TokensRepository
{
...
...
@@ -21,8 +23,8 @@ class DatabaseTokensRepository implements TokensRepository {
return
$user
->
tokens
()
->
create
(
[
'name'
=>
$token
->
getName
(),
'api_token'
=>
$token
->
getTokenString
(),
'name'
=>
$token
->
getName
(),
'api_token'
=>
$token
->
getTokenString
(),
'expires_at'
=>
$token
->
getExpiresAt
(),
]
);
...
...
@@ -31,8 +33,12 @@ class DatabaseTokensRepository implements TokensRepository {
/**
* @inheritDoc
*/
public
function
findByToken
(
string
$token
):
?Token
{
$found
=
\
App\Token
::
where
(
'api_token'
,
$token
)
->
first
();
public
function
findValidToken
(
string
$token
):
?Token
{
$found
=
\
App\Token
::
where
(
'api_token'
,
$token
)
->
andWhere
(
'expired_at'
,
'<'
,
Carbon
::
now
())
->
orWhere
(
static
function
(
Builder
$query
)
use
(
$token
)
{
$query
->
where
(
'api_token'
,
$token
)
->
andWhere
(
'expired_at'
,
null
);
}
)
->
first
();
if
(
!
$found
)
{
return
null
;
...
...
src/web/backend/src/Gateways/Tokens/InMemoryTokensRepository.php
View file @
87df45f6
...
...
@@ -4,6 +4,7 @@
namespace
Source\Gateways\Tokens
;
use
Carbon\Carbon
;
use
Source\Entities\Token
;
class
InMemoryTokensRepository
implements
TokensRepository
{
...
...
@@ -12,17 +13,20 @@ class InMemoryTokensRepository implements TokensRepository {
*/
protected
array
$tokens
=
[];
protected
static
int
$id
=
1
;
/** @inheritDoc */
public
function
create
(
Token
$token
):
Token
{
$token
->
setId
(
static
::
$id
++
);
$this
->
tokens
[]
=
$token
;
return
$token
;
}
/** @inheritDoc */
public
function
find
By
Token
(
string
$tokenToMatch
):
?Token
{
public
function
find
Valid
Token
(
string
$tokenToMatch
):
?Token
{
foreach
(
$this
->
tokens
as
$token
)
{
if
(
$token
->
matches
(
$tokenToMatch
))
{
if
(
$token
->
matches
(
$tokenToMatch
)
&&
$token
->
isValidAtTime
(
Carbon
::
now
())
)
{
return
$token
;
}
}
...
...
src/web/backend/src/Gateways/Tokens/TokensRepository.php
View file @
87df45f6
...
...
@@ -19,5 +19,5 @@ interface TokensRepository {
* @param string $token
* @return Token|null
*/
public
function
find
By
Token
(
string
$token
):
?Token
;
public
function
find
Valid
Token
(
string
$token
):
?Token
;
}
src/web/backend/src/UseCases/BasePresenter.php
View file @
87df45f6
...
...
@@ -48,6 +48,19 @@ abstract class BasePresenter {
return
$time
->
format
(
$format
);
}
/**
* @param Carbon|null $datetime
* @param string $format
* @return string|null
*/
public
function
formatDateTime
(
?Carbon
$datetime
,
string
$format
=
'c'
):
?string
{
if
(
$datetime
===
null
)
{
return
null
;
}
return
$datetime
->
format
(
$format
);
}
/**
* @param User $user
* @return array
...
...
src/web/backend/src/UseCases/Token/Authenticate/Authenticate.php
View file @
87df45f6
...
...
@@ -29,7 +29,7 @@ class Authenticate implements AuthenticateUseCase {
return
;
}
$found
=
$this
->
tokens
->
find
By
Token
(
$token
);
$found
=
$this
->
tokens
->
find
Valid
Token
(
$token
);
if
(
!
$found
)
{
return
;
...
...
src/web/backend/src/UseCases/Users/Authenticate/APIPresenter.php
0 → 100644
View file @
87df45f6
<?php
namespace
Source\UseCases\Users\Authenticate
;
use
Source\UseCases\BasePresenter
;
class
APIPresenter
extends
BasePresenter
implements
Presenter
{
protected
array
$viewModel
=
[];
/** @inheritDoc */
public
function
present
(
ResponseModel
$responseModel
):
void
{
$user
=
$responseModel
->
getUser
();
$token
=
$responseModel
->
getToken
();
$this
->
viewModel
[
'user'
]
=
$this
->
formatUser
(
$user
);
$this
->
viewModel
[
'token'
]
=
[
'value'
=>
$token
->
getTokenString
(),
'expires_at'
=>
$this
->
formatDateTime
(
$token
->
getExpiresAt
()),
];
}
/** @inheritDoc */
public
function
getViewModel
():
array
{
return
$this
->
viewModel
;
}
}
src/web/backend/src/UseCases/Users/Authenticate/Authenticate.php
0 → 100644
View file @
87df45f6
<?php
namespace
Source\UseCases\Users\Authenticate
;
use
Carbon\Carbon
;
use
Source\Entities\Token
;
use
Illuminate\Support\Str
;
use
Source\Gateways\Users\UsersRepository
;
use
Source\Gateways\Tokens\TokensRepository
;
use
Source\Exceptions\AuthorizationException
;
class
Authenticate
implements
AuthenticateUseCase
{
protected
UsersRepository
$users
;
protected
TokensRepository
$tokens
;
public
function
__construct
(
UsersRepository
$users
,
TokensRepository
$tokens
)
{
$this
->
users
=
$users
;
$this
->
tokens
=
$tokens
;
}
/**
* @inheritDoc
*/
public
function
attempt
(
Presenter
$presenter
,
array
$credentials
):
void
{
$email
=
$credentials
[
'email'
]
??
null
;
$password
=
$credentials
[
'password'
]
??
null
;
if
(
!
$email
||
!
$password
)
{
throw
new
AuthorizationException
();
}
$user
=
$this
->
users
->
findByCredentials
(
strtolower
(
$email
),
$password
);
if
(
!
$user
)
{
throw
new
AuthorizationException
();
}
$token
=
$this
->
tokens
->
create
(
new
Token
(
0
,
$user
->
getId
(),
Str
::
random
(
60
),
null
,
Carbon
::
now
()
->
days
(
2
)
)
);
$response
=
new
ResponseModel
(
$user
,
$token
);
$presenter
->
present
(
$response
);
}
}
src/web/backend/src/UseCases/Users/Authenticate/AuthenticateUseCase.php
0 → 100644
View file @
87df45f6
<?php
namespace
Source\UseCases\Users\Authenticate
;
use
Source\Exceptions\AuthorizationException
;
use
Source\Exceptions\EntityNotFoundException
;
interface
AuthenticateUseCase
{
/**
* Attempt an auth with credentials
*
* @param Presenter $presenter
* @param array $credentials
* @throws AuthorizationException
* @throws EntityNotFoundException
*/
public
function
attempt
(
Presenter
$presenter
,
array
$credentials
):
void
;
}
src/web/backend/src/UseCases/Users/Authenticate/AuthenticateUseCaseServiceProvider.php
0 → 100644
View file @
87df45f6
<?php
namespace
Source\UseCases\Users\Authenticate
;
use
Source\Gateways\Users\UsersRepository
;
use
Source\Gateways\Tokens\TokensRepository
;
use
Illuminate\Contracts\Foundation\Application
;
use
Illuminate\Contracts\Support\DeferrableProvider
;
use
Illuminate\Support\ServiceProvider
;
/**
* Service provider must be registered in AppServiceProvider
*/
class
AuthenticateUseCaseServiceProvider
extends
ServiceProvider
implements
DeferrableProvider
{
/**
* Register any application services.
*
* @return void
*/
public
function
register
()
{
$this
->
app
->
bind
(
AuthenticateUseCase
::
class
,
static
function
(
Application
$app
)
{
return
new
Authenticate
(
$app
->
make
(
UsersRepository
::
class
),
$app
->
make
(
TokensRepository
::
class
));
});
}
/**
* Bootstrap any application services.
*
* @return void
*/
public
function
boot
():
void
{
}
/**
* @return array
*/
public
function
provides
()
{
return
[
AuthenticateUseCase
::
class
];
}
}
src/web/backend/src/UseCases/Users/Authenticate/Presenter.php
0 → 100644
View file @
87df45f6
<?php
namespace
Source\UseCases\Users\Authenticate
;
interface
Presenter
{
/**
* @param ResponseModel $responseModel
* @return void
*/
public
function
present
(
ResponseModel
$responseModel
):
void
;
/**
* @return array
*/
public
function
getViewModel
():
array
;
}
src/web/backend/src/UseCases/Users/Authenticate/ResponseModel.php
0 → 100644
View file @
87df45f6
<?php
namespace
Source\UseCases\Users\Authenticate
;
use
Source\Entities\User
;
use
Source\Entities\Token
;
class
ResponseModel
{
/**
* @var User
*/
protected
User
$user
;
/**
* @var Token
*/
protected
Token
$token
;
/**
* @param User $user
* @param Token $token
*/
public
function
__construct
(
User
$user
,
Token
$token
)
{
$this
->
user
=
$user
;
$this
->
token
=
$token
;
}
/**
* @return User
*/
public
function
getUser
():
User
{
return
$this
->
user
;
}
/**
* @return Token
*/
public
function
getToken
():
Token
{
return
$this
->
token
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment