Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Syndesi committed Sep 14, 2023
1 parent 614ccde commit 3822cef
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ ELASTIC_AUTH=ember-nexus-elasticsearch:9200
REDIS_AUTH=tcp://ember-nexus-redis?password=redis-password
RABBITMQ_AUTH=amqp://user:password@ember-nexus-rabbitmq:5672

REFERENCE_DATASET_VERSION=0.0.8
REFERENCE_DATASET_VERSION=0.0.9
2 changes: 2 additions & 0 deletions docs/api-endpoints/user/get-token.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
Returns the currently used token.

To display all tokens, you can return all root elements and filter for the `Token` type.

Currently under development.
78 changes: 40 additions & 38 deletions docs/api-endpoints/user/post-token.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,18 @@ The posted request must be a valid JSON document.

The request must contain the following attributes:

- `type`: Containing the content "User". No other values are currently possible.
- `password`: The plain text password of the new user. Can contain any string, will be hashed internally. Whitespace at
the start or end of the string will **not** be removed, though it is discouraged.
No password complexity check is performed.
- `data.<identifier>`: By default `data.email`, must contain a new unique string. While not required, it is encouraged
to keep the content within 256 bytes. Optional limits might be added at a later time.
The required identifier name is returned by the
[instance configuration endpoint](/api-endpoints/get-instance-configuration) and in error messages.
- `type`: Containing the content "Token". No other values are currently possible.
- `user`: The value for the user's identifying property, by default the user's email address.
- `password`: The plain text password of the user.
- `data`: Object of properties, optional.

```json
{
"type": "User",
"type": "Token",
"user": "[email protected]",
"password": "1234",
"data": {
"<identifier>": "[email protected]"
"key": "value"
}
}
```
Expand All @@ -39,16 +36,20 @@ The request must contain the following attributes:
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"type": "User", "password": "1234", "data": {"email": "[email protected]"}}' \
https://api.localhost/register
-d '{"type": "Token", "user": "[email protected]", "password": "1234"}' \
https://api.localhost/token
```

<!-- tabs:start -->

### **Success 200**

Success responses do not have a return body. The location of the new user, containing the user's UUID, is written in the
`Location` header.
```json
{
"type": "_TokenResponse",
"token": "secret-token:ERgAAnWl0CY8bQs0m11nZ3"
}
```

### **Error 400**

Expand All @@ -57,21 +58,25 @@ Success responses do not have a return body. The location of the new user, conta
"type": "400-bad-request",
"title": "Bad Request",
"status": 400,
"detail": "Property 'email' must be set."
"detail": "Property 'user' must be set."
}
```

### **Error 403**
### **Error 401**

```problem+json
{
"type": "403-forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Client does not have permissions to perform action."
"type": "401-unauthorized",
"title": "Request does not contain valid token, or anonymous user is disabled.",
"status": 401,
"detail": ""
}
```

### **Error 500**

wip

<!-- tabs:end -->

<!-- div:right-panel -->
Expand Down Expand Up @@ -131,32 +136,29 @@ G6.registerEdge('polyline-edge', {
renderWorkflow(document.getElementById('graph-container-1'), {
nodes: [
{ id: 'init', ...workflowStart, label: 'server receives POST-request' },
{ id: 'checkEndpointEnabled', ...workflowDecision, label: 'is endpoint enabled?' },
{ id: 'checkPassword', ...workflowDecision, label: 'is password given?' },
{ id: 'checkType', ...workflowDecision, label: 'is type given?' },
{ id: 'checkTypeContent', ...workflowDecision, label: 'is type equal to "User"?' },
{ id: 'checkIdentifier', ...workflowDecision, label: "is identifier given?" },
{ id: 'checkIdentifierUnique', ...workflowDecision, label: 'is identifier unique?' },
{ id: 'createUser', ...workflowStep, label: "create user" },
{ id: 'checkTypeContent', ...workflowDecision, label: 'is type equal\nto "Token"?' },
{ id: 'checkUserProperty', ...workflowDecision, label: 'is user given?' },
{ id: 'checkPasswordProperty', ...workflowDecision, label: "is password given?" },
{ id: 'checkCredentials', ...workflowDecision, label: 'are credentials ok?' },
{ id: 'createToken', ...workflowStep, label: "create token" },
{ id: 'error400', ...workflowEndError, label: "return 400" },
{ id: 'error403', ...workflowEndError, label: 'return 403' },
{ id: 'error401', ...workflowEndError, label: 'return 401' },
{ id: 'success200', ...workflowEndSuccess , label: "return 200"},
],
edges: [
{ source: 'init', target: 'checkEndpointEnabled', label: '' },
{ source: 'checkEndpointEnabled', target: 'checkPassword', label: 'yes' },
{ source: 'checkEndpointEnabled', target: 'error403', label: 'no' },
{ source: 'checkPassword', target: 'checkType', label: 'yes' },
{ source: 'checkPassword', target: 'error400', label: 'no' },
{ source: 'init', target: 'checkType', label: '' },
{ source: 'checkType', target: 'checkTypeContent', label: 'yes' },
{ source: 'checkType', target: 'error400', label: 'no' },
{ source: 'checkTypeContent', target: 'checkIdentifier', label: 'yes' },
{ source: 'checkTypeContent', target: 'checkUserProperty', label: 'yes' },
{ source: 'checkTypeContent', target: 'error400', label: 'no' },
{ source: 'checkIdentifier', target: 'checkIdentifierUnique', label: 'yes' },
{ source: 'checkIdentifier', target: 'error400', label: 'no' },
{ source: 'checkIdentifierUnique', target: 'createUser', label: 'yes' },
{ source: 'checkIdentifierUnique', target: 'error400', label: 'no' },
{ source: 'createUser', target: 'success200', label: '' },
{ source: 'checkUserProperty', target: 'checkPasswordProperty', label: 'yes' },
{ source: 'checkUserProperty', target: 'error400', label: 'no' },
{ source: 'checkPasswordProperty', target: 'checkCredentials', label: 'yes' },
{ source: 'checkPasswordProperty', target: 'error400', label: 'no' },
{ source: 'checkCredentials', target: 'createToken', label: 'yes' },
{ source: 'checkCredentials', target: 'error401', label: 'no' },
{ source: 'createToken', target: 'success200', label: '' },
],
}, 'TB');
</script>
23 changes: 12 additions & 11 deletions src/Controller/User/PostTokenController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,23 @@ public function __construct(
public function postToken(Request $request): Response
{
$body = \Safe\json_decode($request->getContent(), true);

if (!array_key_exists('type', $body)) {
throw $this->client400MissingPropertyExceptionFactory->createFromTemplate('type', 'string');
}
if ('Token' !== $body['type']) {
throw $this->client400BadContentExceptionFactory->createFromTemplate('type', 'Token', $body['type']);
}

/**
* @var array<string, mixed> $body
*/
$uniqueIdentifier = $this->emberNexusConfiguration->getRegisterUniqueIdentifier();
if (!array_key_exists($uniqueIdentifier, $body)) {
throw $this->client400MissingPropertyExceptionFactory->createFromTemplate($uniqueIdentifier, 'string');
if (!array_key_exists('user', $body)) {
throw $this->client400MissingPropertyExceptionFactory->createFromTemplate('user', 'string');
}
$uniqueIdentifierValue = $body[$uniqueIdentifier];
$uniqueIdentifierValue = $body['user'];

$uniqueIdentifier = $this->emberNexusConfiguration->getRegisterUniqueIdentifier();
$res = $this->cypherEntityManager->getClient()->runStatement(Statement::create(
sprintf(
'MATCH (u:User {%s: $identifier}) RETURN u.id AS id',
Expand Down Expand Up @@ -84,13 +92,6 @@ public function postToken(Request $request): Response
$lifetimeInSeconds = (int) $body['lifetimeInSeconds'];
}

if (!array_key_exists('type', $body)) {
throw $this->client400MissingPropertyExceptionFactory->createFromTemplate('type', 'string');
}
if ('Token' !== $body['type']) {
throw $this->client400BadContentExceptionFactory->createFromTemplate('type', 'Token', $body['type']);
}

$data = [];
if (array_key_exists('data', $body)) {
$data = $body['data'];
Expand Down
Empty file modified test-feature-prepare
100644 → 100755
Empty file.
9 changes: 7 additions & 2 deletions tests/FeatureTests/Endpoint/User/PostTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

use App\Tests\FeatureTests\BaseRequestTestCase;

/**
* @group test
*/
class PostTokenTest extends BaseRequestTestCase
{
public const TOKEN = 'secret-token:3tgEP9MhD81rkp3qiJcm1U';
public const EMAIL = '';
public const PASSWORD = '';
public const EMAIL = '[email protected]';
public const PASSWORD = '1234';

public function testPostToken(): void
{
Expand All @@ -25,6 +28,8 @@ public function testPostToken(): void
]
);

echo "\n\n".((string) $response->getBody())."\n\n";

$this->assertSame(200, $response->getStatusCode());
$this->assertSame('application/json; charset=utf-8', $response->getHeader('content-type')[0]);
$body = \Safe\json_decode((string) $response->getBody(), true);
Expand Down

0 comments on commit 3822cef

Please sign in to comment.