Skip to content

Commit f169491

Browse files
committed
create separated Security package from web package
1 parent e34defe commit f169491

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1747
-1
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 DevNet Framework
3+
Copyright (c) DevNet Framework
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# DevNet Security
2+
This dependency is the web security library of **DevNet Framework**, which includes the following web components:
3+
4+
- Authentication
5+
- Authorization
6+
- CSRF Prevention
7+
8+
## Requirements
9+
- [DevNet Core](https://github.com/DevNet-Framework/core/) version 1.0
10+
- [Composer](https://getcomposer.org/) version 2.0 or higher
11+
12+
## Installation
13+
You can install DevNet Security as a third-party library to any PHP project, by running the following command in the terminal:
14+
```
15+
composer require devnet/security
16+
```
17+
18+
## Documentation
19+
Full documentation on how to use **DevNet Framework** is available at [devnet-framework.github.io](https://devnet-framework.github.io)
20+
21+
## License
22+
This library is licensed under the MIT license. See [License File](https://github.com/DevNet-Framework/web/blob/master/LICENSE) in the root folder for more information.

composer.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "devnet/security",
3+
"description": "The DevNet Web Security Library",
4+
"type": "library",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Mohammed Moussaoui",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"require": {
13+
"php": "^8.1",
14+
"devnet/system": "1.1.*"
15+
},
16+
"autoload": {
17+
"psr-4": {
18+
"DevNet\\Security\\": "lib/"
19+
}
20+
}
21+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
/**
4+
* @author Mohammed Moussaoui
5+
* @license MIT license. For more license information, see the LICENSE file in the root directory.
6+
* @link https://github.com/DevNet-Framework
7+
*/
8+
9+
namespace DevNet\Security\Authentication;
10+
11+
use DevNet\System\PropertyTrait;
12+
use DevNet\Security\Claims\ClaimsIdentity;
13+
use Exception;
14+
15+
class Authentication implements IAuthentication
16+
{
17+
use PropertyTrait;
18+
19+
private array $handlers;
20+
21+
public function __construct(array $handlers)
22+
{
23+
$this->handlers = $handlers;
24+
}
25+
26+
public function get_Schemes(): array
27+
{
28+
return array_keys($this->handlers);
29+
}
30+
31+
public function get_Handlers(): array
32+
{
33+
return $this->handlers;
34+
}
35+
36+
public function authenticate(?string $scheme = null): AuthenticationResult
37+
{
38+
// get handler by scheme else get the first handler.
39+
$handler = $this->handlers[$scheme] ?? reset($this->handlers);
40+
41+
if ($handler) {
42+
return $handler->authenticate();
43+
}
44+
45+
return new AuthenticationResult(new Exception("The authentication handler is missing!"));
46+
}
47+
48+
public function signIn(ClaimsIdentity $user, bool $isPersistent = false, ?string $scheme = null): void
49+
{
50+
$authenticationHandler = $this->handlers[$scheme] ?? null;
51+
if ($authenticationHandler) {
52+
if (!$authenticationHandler instanceof IAuthenticationSigningHandler) {
53+
throw new Exception("The requested authentication handler must be of type IAuthenticationSigningHandler");
54+
}
55+
} else {
56+
foreach ($this->handlers as $handler) {
57+
if ($handler instanceof IAuthenticationSigningHandler) {
58+
$authenticationHandler = $handler;
59+
break;
60+
}
61+
}
62+
if (!$authenticationHandler) {
63+
throw new Exception("No IAuthenticationSigningHandler is registered!");
64+
}
65+
}
66+
67+
$authenticationHandler->signIn($user, $isPersistent);
68+
}
69+
70+
public function signOut(?string $scheme = null): void
71+
{
72+
$authenticationHandler = $this->handlers[$scheme] ?? null;
73+
if ($authenticationHandler) {
74+
if (!$authenticationHandler instanceof IAuthenticationSigningHandler) {
75+
throw new Exception("The requested authentication handler must be of type IAuthenticationSigningHandler");
76+
}
77+
} else {
78+
foreach ($this->handlers as $handler) {
79+
if ($handler instanceof IAuthenticationSigningHandler) {
80+
$authenticationHandler = $handler;
81+
break;
82+
}
83+
}
84+
if (!$authenticationHandler) {
85+
throw new Exception("No IAuthenticationSigningHandler is registered!");
86+
}
87+
}
88+
89+
$authenticationHandler->signOut();
90+
}
91+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/**
4+
* @author Mohammed Moussaoui
5+
* @license MIT license. For more license information, see the LICENSE file in the root directory.
6+
* @link https://github.com/DevNet-Framework
7+
*/
8+
9+
namespace DevNet\Security\Authentication;
10+
11+
use DevNet\Security\Authentication\JwtBearer\JwtBearerHandler;
12+
use DevNet\Security\Authentication\JwtBearer\JwtBearerOptions;
13+
use DevNet\Security\Authentication\Cookies\AuthenticationCookieHandler;
14+
use DevNet\Security\Authentication\Cookies\AuthenticationCookieOptions;
15+
use Closure;
16+
17+
class AuthenticationBuilder
18+
{
19+
private array $authentications;
20+
21+
public function addCookie(string $authenticationScheme = AuthenticationScheme::CookieSession, Closure $configuration = null): void
22+
{
23+
$options = new AuthenticationCookieOptions();
24+
if ($configuration) {
25+
$configuration($options);
26+
}
27+
28+
$this->authentications[$authenticationScheme] = new AuthenticationCookieHandler($options);
29+
}
30+
31+
public function addJwtBearer(string $authenticationScheme = AuthenticationScheme::JwtBearer, Closure $configuration = null): void
32+
{
33+
$options = new JwtBearerOptions();
34+
if ($configuration) {
35+
$configuration($options);
36+
}
37+
38+
$this->authentications[$authenticationScheme] = new JwtBearerHandler($options);
39+
}
40+
41+
public function build(): Authentication
42+
{
43+
return new Authentication($this->authentications);
44+
}
45+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
/**
4+
* @author Mohammed Moussaoui
5+
* @license MIT license. For more license information, see the LICENSE file in the root directory.
6+
* @link https://github.com/DevNet-Framework
7+
*/
8+
9+
namespace DevNet\Security\Authentication;
10+
11+
use DevNet\Http\Message\HttpException;
12+
13+
class AuthenticationException extends HttpException
14+
{
15+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/**
4+
* @author Mohammed Moussaoui
5+
* @license MIT license. For more license information, see the LICENSE file in the root directory.
6+
* @link https://github.com/DevNet-Framework
7+
*/
8+
9+
namespace DevNet\Security\Authentication;
10+
11+
use DevNet\System\PropertyTrait;
12+
use DevNet\Security\Claims\ClaimsIdentity;
13+
use Exception;
14+
15+
class AuthenticationResult
16+
{
17+
use PropertyTrait;
18+
19+
private ?ClaimsIdentity $identity = null;
20+
private ?Exception $error = null;
21+
22+
public function __construct(object $result)
23+
{
24+
if ($result instanceof ClaimsIdentity) {
25+
$this->identity = $result;
26+
} else if ($result instanceof Exception) {
27+
$this->error = $result;
28+
}
29+
}
30+
31+
public function get_Identity(): ?ClaimsIdentity
32+
{
33+
return $this->identity;
34+
}
35+
36+
public function get_Error(): ?Exception
37+
{
38+
return $this->error;
39+
}
40+
41+
public function isSucceeded(): bool
42+
{
43+
return $this->identity ? true : false;
44+
}
45+
46+
public function isFailed(): bool
47+
{
48+
return $this->error ? true : false;
49+
}
50+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
/**
4+
* @author Mohammed Moussaoui
5+
* @license MIT license. For more license information, see the LICENSE file in the root directory.
6+
* @link https://github.com/DevNet-Framework
7+
*/
8+
9+
namespace DevNet\Security\Authentication;
10+
11+
class AuthenticationScheme
12+
{
13+
public const CookieSession = 'CookieSession';
14+
public const JwtBearer = 'JwtBearer';
15+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
/**
4+
* @author Mohammed Moussaoui
5+
* @license MIT license. For more license information, see the LICENSE file in the root directory.
6+
* @link https://github.com/DevNet-Framework
7+
*/
8+
9+
namespace DevNet\Security\Authentication\Cookies;
10+
11+
use DevNet\System\TimeSpan;
12+
use DevNet\System\PropertyTrait;
13+
use DevNet\Security\Session;
14+
use DevNet\Security\Authentication\AuthenticationResult;
15+
use DevNet\Security\Authentication\IAuthenticationHandler;
16+
use DevNet\Security\Authentication\IAuthenticationSigningHandler;
17+
use DevNet\Security\Claims\ClaimsIdentity;
18+
use Exception;
19+
20+
class AuthenticationCookieHandler implements IAuthenticationHandler, IAuthenticationSigningHandler
21+
{
22+
use PropertyTrait;
23+
24+
private AuthenticationCookieOptions $options;
25+
private Session $session;
26+
27+
public function __construct(AuthenticationCookieOptions $options)
28+
{
29+
$this->options = $options;
30+
$this->session = new Session($options->CookieName, $options->CookiePath);
31+
32+
if (!$this->options->ExpireTime) {
33+
$this->options->ExpireTime = new TimeSpan();
34+
}
35+
}
36+
37+
public function get_Options(): AuthenticationCookieOptions
38+
{
39+
return $this->options;
40+
}
41+
42+
public function get_Session(): Session
43+
{
44+
return $this->session;
45+
}
46+
47+
public function authenticate(): AuthenticationResult
48+
{
49+
if ($this->session->isSet()) {
50+
$this->session->start();
51+
$identity = $this->session->get(ClaimsIdentity::class);
52+
53+
if ($identity) {
54+
return new AuthenticationResult($identity);
55+
}
56+
}
57+
58+
return new AuthenticationResult(new Exception("Session cookie dose not have ClaimsIdentity data"));
59+
}
60+
61+
public function signIn(ClaimsIdentity $user, bool $isPersistent = false): void
62+
{
63+
if ($isPersistent) {
64+
$this->session->setOptions(['cookie_lifetime' => (int) $this->options->ExpireTime->TotalSeconds]);
65+
} else {
66+
$this->session->setOptions(['cookie_lifetime' => 0]);
67+
}
68+
69+
$this->session->start();
70+
$this->session->set(ClaimsIdentity::class, $user);
71+
}
72+
73+
public function signOut(): void
74+
{
75+
$this->session->destroy();
76+
}
77+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/**
4+
* @author Mohammed Moussaoui
5+
* @license MIT license. For more license information, see the LICENSE file in the root directory.
6+
* @link https://github.com/DevNet-Framework
7+
*/
8+
9+
namespace DevNet\Security\Authentication\Cookies;
10+
11+
use DevNet\System\TimeSpan;
12+
13+
class AuthenticationCookieOptions
14+
{
15+
public string $CookieName = "Identity";
16+
public string $CookiePath = "/";
17+
public ?TimeSpan $ExpireTime = null;
18+
19+
public function __construct(string $cookieName = 'Identity', string $cookiePath = '/', ?TimeSpan $expireTime = null)
20+
{
21+
$this->CookieName = $cookieName;
22+
$this->CookiePath = $cookiePath;
23+
24+
$this->CookieName = $this->CookieName . "-" . md5($this->CookieName . $_SERVER['DOCUMENT_ROOT']);
25+
26+
if (!$expireTime) {
27+
$this->ExpireTime = TimeSpan::fromDays(7);
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)