Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loose coupling: security module #1630

Merged
merged 79 commits into from
Jul 7, 2020
Merged
Show file tree
Hide file tree
Changes from 78 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
a5a6bb3
always create user before credentials
vidiben Apr 28, 2020
09444a5
[wip] loose coupling: security module
scottinet May 9, 2020
fa5c561
[wip] loose coupling: security module
scottinet May 9, 2020
37cb022
Merge remote-tracking branch 'origin/security-create-user-before-cred…
scottinet May 9, 2020
807747b
[refactor] replace kuzzle arg with kuzzle property
scottinet May 9, 2020
3ae7403
Merge remote-tracking branch 'origin/security-create-user-before-cred…
scottinet May 9, 2020
16202e1
[wip] loose coupling: security module
scottinet May 9, 2020
e526c45
Merge remote-tracking branch 'origin/2-dev' into security-create-user…
scottinet May 9, 2020
cb79770
[test] update unit tests
scottinet May 9, 2020
c6d12f5
Merge remote-tracking branch 'origin/security-create-user-before-cred…
scottinet May 9, 2020
6916566
[wip] loose coupling: security module
scottinet May 9, 2020
e5b48f8
[wip] loose coupling: security module
scottinet May 10, 2020
9de12cc
Merge remote-tracking branch 'origin/loose-coupling-refactor-core-dir…
scottinet May 11, 2020
8e03a3a
[wip] loose coupling: security module
scottinet May 11, 2020
d425abc
[fix] forgot to add the user identifier to the update role call
scottinet May 12, 2020
f04cce5
Merge remote-tracking branch 'origin/loose-coupling-refactor-core-dir…
scottinet May 12, 2020
dc45c5c
[wip] loose coupling: security module
scottinet May 12, 2020
dd6cfee
[refactor] use singular form for directory names
scottinet May 13, 2020
656f6e7
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-refac…
scottinet May 13, 2020
80ef4a1
[refactor] update the error code documentation builder
scottinet May 13, 2020
7d084bd
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-refac…
scottinet May 13, 2020
48413b2
Merge remote-tracking branch 'origin/loose-coupling-refactor-core-dir…
scottinet May 13, 2020
7b7abcc
[doc] deprecated plugin.context.errorsManager and alias it to plugin.…
scottinet May 13, 2020
88e1447
Merge remote-tracking branch 'origin/loose-coupling-refactor-core-dir…
scottinet May 13, 2020
59f3d28
[wip] loose coupling: security module
scottinet May 13, 2020
f137379
[wip] loose coupling: security module
scottinet May 13, 2020
4e4cfc5
[wip] loose coupling: security module
scottinet May 14, 2020
1f0f8d0
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet May 14, 2020
3da7209
[wip] loose coupling: security module
scottinet May 16, 2020
0e6e105
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet May 16, 2020
cdab1b6
[test] wip - fix/update functional tests
scottinet May 16, 2020
e855d91
[test] fix/update functional tests
scottinet May 16, 2020
f72dbf3
[fix] resolve lint errors
scottinet May 16, 2020
cc5dfc2
[test] wip - fix/update unit tests
scottinet May 18, 2020
1c9b690
[test] wip - fix/update unit tests
scottinet May 18, 2020
8e7133d
[test] wip - fix/update unit tests
scottinet May 19, 2020
6fa962d
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet May 22, 2020
d3e8940
[test] wip - fix/update unit tests
scottinet May 22, 2020
b01c215
[test] wip - fix/update unit tests
scottinet May 23, 2020
71ab418
[test] wip - fix/update unit tests
scottinet May 25, 2020
bf9de1b
[test] wip - fix/update unit tests
scottinet May 28, 2020
c44fe30
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet May 31, 2020
3a630f0
[tests] fix unit tests
scottinet May 31, 2020
5a6ae5b
[tests] fix unit tests
scottinet Jun 1, 2020
3cf74bf
[tests] fix unit tests
scottinet Jun 1, 2020
6273f9d
[tests] fix unit tests
scottinet Jun 4, 2020
70c7674
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jun 4, 2020
e6a57fb
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jun 6, 2020
26991fa
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jun 6, 2020
e7a21f7
[tests] fix unit tests
scottinet Jun 8, 2020
fc3900b
[doc] typo fix
scottinet Jun 9, 2020
37fb9a3
[functests] fix erroneous function call
scottinet Jun 9, 2020
51ebcd9
[tests] fix unit tests
scottinet Jun 9, 2020
81112b3
[tests] new unit tests
scottinet Jun 9, 2020
b5a54f9
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jun 11, 2020
3e07870
[tests] unit tests: profileRepository
scottinet Jun 11, 2020
3cffba8
[tests] unit tests: roleRepository (part 1)
scottinet Jun 12, 2020
9680a98
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jun 12, 2020
b7b2731
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jun 17, 2020
9f2e592
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jun 20, 2020
b403ffb
[tests] unit tests: roleRepository (part 2)
scottinet Jun 20, 2020
ce41e43
[test] remove debug opts
scottinet Jun 20, 2020
3a3a04e
[tests] fix warning on a non-error promise rejection
scottinet Jun 20, 2020
6564035
[tests] unit tests: userRepository (part 1)
scottinet Jun 29, 2020
155ecd9
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jun 30, 2020
4495ad0
[tests] unit tests: userRepository (end)
scottinet Jun 30, 2020
635b1ab
[tests] unit tests: tokenRepository
scottinet Jun 30, 2020
8f74f4a
[tests] unit tests: securityLoader
scottinet Jun 30, 2020
d4e3989
[tests] unit tests: securityLoader
scottinet Jun 30, 2020
bc50bba
[fix] remove limitation on ids with a leading underscore
scottinet Jun 30, 2020
f13958d
[fix] forgot to update auth:updateSelf with the new user:update proto…
scottinet Jun 30, 2020
f170430
[fix] this is the very last commit. I promise.
scottinet Jun 30, 2020
e2d273c
[fix] ok I lied. THIS is the last one
scottinet Jun 30, 2020
70254ba
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jul 3, 2020
9d70e3b
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jul 3, 2020
edd30fa
[errors] throw a runtime assertion failed instead of a dedicated orph…
scottinet Jul 3, 2020
9ec2753
[errors] update error documentation
scottinet Jul 3, 2020
1aaa9a5
[fix] apply @aschen's suggestions
scottinet Jul 7, 2020
55cd119
Merge remote-tracking branch 'origin/2-dev' into loose-coupling-security
scottinet Jul 7, 2020
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
14 changes: 10 additions & 4 deletions doc/2/api/controllers/auth/update-self/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ title: updateSelf

# updateSelf



Updates the currently logged in user information.

This route cannot update the list of associated security profiles. To change a user's security profiles, the route [security:updateUser](/core/2/api/controllers/security/update-user) must be used instead.
Expand All @@ -19,7 +17,7 @@ This route cannot update the list of associated security profiles. To change a u
### HTTP

```http
URL: http://kuzzle:7512/_updateSelf
URL: http://kuzzle:7512/_updateSelf[?refresh=wait_for][?retryOnConflict=10]
Method: PUT
Headers: Authorization: "Bearer <authentication token>"
Body:
Expand All @@ -42,7 +40,10 @@ Body:
"body": {
"foo": "bar",
"name": "Walter Smith"
}
},
// Optional
"refresh": "wait_for",
"retryOnConflict": 10
}
```

Expand All @@ -52,6 +53,11 @@ Body:

- `jwt`: valid authentication token (for the HTTP protocol, the token is to be passed to the `Authorization` header instead)

### Optional arguments

- `refresh`: if set to `wait_for`, Kuzzle will not respond until the user changes are indexed (default: `"wait_for"`)
- `retryOnConflict`: in case of an update conflict in Elasticsearch, the number of retries before aborting the operation (default: `10`)

---

## Body properties
Expand Down
6 changes: 2 additions & 4 deletions doc/2/api/controllers/security/create-first-admin/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ title: createFirstAdmin

# createFirstAdmin



Creates a Kuzzle administrator account, only if none exist.

---
Expand All @@ -25,8 +23,8 @@ Body:

```js
{
// administrator additional information (optional)
"content": {
// administrator information (optional)
},
"credentials": {
// for example, with the "local" authentication strategy:
Expand Down Expand Up @@ -75,7 +73,7 @@ Body:

## Body properties

- `content`: administrator additional information. Can be left empty.
- `content`: optional additional information
- `credentials`: describe how the new administrator can be authenticated. This object must contain one or multiple properties, named after the target authentication strategy to use. Each one of these properties are objects containing the credentials information, corresponding to that authentication strategy

---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ Body:

```js
{
// user additional information (optional)
"content": {
// user additional information (optional)
"fullname": "John Doe"
},
"credentials": {
Expand All @@ -48,6 +48,7 @@ Body:
"controller": "security",
"action": "createRestrictedUser",
"body": {
// optional
"content": {
"fullname": "John Doe"
},
Expand All @@ -70,7 +71,7 @@ Body:

## Arguments

### Optional:
### Optional

- `_id`: user [kuid](/core/2/guides/kuzzle-depth/authentication#the-kuzzle-user-identifier). An error is returned if the provided identifier already exists. If not provided, a random kuid is automatically generated.
- `refresh`: if set to `wait_for`, Kuzzle will not respond until the newly created user is indexed (default: `"wait_for"`)
Expand All @@ -79,7 +80,7 @@ Body:

## Body properties

- `content`: user additional information. Can be left empty.
- `content`: optional user additional information.
- `credentials`: describe how the new user can be authenticated. This object contains any number of properties, named after the target authentication strategy to use. Each one of these properties are objects containing the credentials information, corresponding to that authentication strategy. If left empty, the new user is created but cannot be authenticated.

---
Expand Down
12 changes: 8 additions & 4 deletions doc/2/api/controllers/security/update-profile/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Updates a security profile definition.
### HTTP

```http
URL: http://kuzzle:7512/profiles/<_id>/_update[?refresh=wait_for]
URL: http://kuzzle:7512/profiles/<_id>/_update[?refresh=wait_for][&retryOnConflict=10]
Method: PUT
Body:
```
Expand Down Expand Up @@ -77,7 +77,10 @@ Body:
]
}
]
}
},
// Optional
"refresh": "wait_for",
"retryOnConflict": 10
}
```

Expand All @@ -87,9 +90,10 @@ Body:

- `_id`: profile identifier

### Optional:
### Optional arguments

- `refresh`: if set to `wait_for`, Kuzzle will not respond until the profile changes are indexed (default: `"wait_for"`)
- `refresh`: if set to `wait_for`, Kuzzle will not respond until the user changes are indexed (default: `"wait_for"`)
- `retryOnConflict`: in case of an update conflict in Elasticsearch, the number of retries before aborting the operation (default: `10`)

---

Expand Down
18 changes: 10 additions & 8 deletions doc/2/api/controllers/security/update-role/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ title: updateRole

# updateRole



Updates a security role definition.

**Note:** partial updates are not supported for roles, this API route will replace the entire role content with the provided one.
Expand All @@ -19,7 +17,7 @@ Updates a security role definition.
### HTTP

```http
URL: http://kuzzle:7512/roles/<_id>/_update[?refresh=wait_for][&force]
URL: http://kuzzle:7512/roles/<_id>/_update[?refresh=wait_for][&force][&retryOnConflict=10]
Method: PUT
Body:
```
Expand Down Expand Up @@ -51,7 +49,11 @@ Body:
}
}
}
}
},
// Optional
"force": false,
"refresh": "wait_for",
"retryOnConflict": 10
}
```

Expand All @@ -61,11 +63,11 @@ Body:

- `_id`: role identifier

### Optional:

- `refresh`: if set to `wait_for`, Kuzzle will not respond until the role changes are indexed (default: `"wait_for"`)
### Optional arguments

- `force`: if set to `true`, updates the role even if it gives access to non-existent plugins API routes.
- `force`: if set to `true`, updates the role even if it gives access to non-existent plugins API routes (default: `false`)
- `refresh`: if set to `wait_for`, Kuzzle will not respond until the user changes are indexed (default: `"wait_for"`)
- `retryOnConflict`: in case of an update conflict in Elasticsearch, the number of retries before aborting the operation (default: `10`)

---

Expand Down
12 changes: 7 additions & 5 deletions doc/2/api/controllers/security/update-user/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ title: updateUser

# updateUser



Updates a user definition.

---
Expand All @@ -17,7 +15,7 @@ Updates a user definition.
### HTTP

```http
URL: http://kuzzle:7512/users/<_id>/_update[?refresh=wait_for]
URL: http://kuzzle:7512/users/<_id>/_update[?refresh=wait_for][&retryOnConflict=10]
Method: PUT
Body:
```
Expand All @@ -37,7 +35,10 @@ Body:
"_id": "<kuid>",
"body": {
"fullname": "Walter Smith"
}
},
// Optional
"refresh": "wait_for",
"retryOnConflict": 10
}
```

Expand All @@ -47,9 +48,10 @@ Body:

- `_id`: user [kuid](/core/2/guides/kuzzle-depth/authentication#the-kuzzle-user-identifier)

### Optional:
### Optional arguments

- `refresh`: if set to `wait_for`, Kuzzle will not respond until the user changes are indexed (default: `"wait_for"`)
- `retryOnConflict`: in case of an update conflict in Elasticsearch, the number of retries before aborting the operation (default: `10`)

---

Expand Down
1 change: 1 addition & 0 deletions doc/2/api/essentials/error-codes/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ description: Error codes definitions
| api.process.incompatible_sdk_version<br/><pre>0x02020006</pre> | [BadRequestError](/core/2/api/essentials/error-handling#badrequesterror) <pre>(400)</pre> | Incompatible SDK client. Your SDK version (%s) does not match Kuzzle requirement (%s). | SDK is incompatible with the current Kuzzle version |
| api.process.shutting_down<br/><pre>0x02020007</pre> | [ServiceUnavailableError](/core/2/api/essentials/error-handling#serviceunavailableerror) <pre>(503)</pre> | Rejected: this node is shutting down. | This Kuzzle node is shutting down and refuses new requests |
| api.process.too_many_requests<br/><pre>0x02020008</pre> | [TooManyRequestsError](/core/2/api/essentials/error-handling#toomanyrequestserror) <pre>(429)</pre> | Rejected: requests rate limit exceeded for this user. | The request has been refused because a rate limit has been exceeded for this user |
| api.process.admin_exists<br/><pre>0x02020009</pre> | [PreconditionError](/core/2/api/essentials/error-handling#preconditionerror) <pre>(412)</pre> | Admin user is already set. | Attempted to create the first administrator, when one already exists |

---
1 change: 1 addition & 0 deletions doc/2/api/essentials/error-codes/security/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ description: Error codes definitions
| security.user.cannot_hydrate<br/><pre>0x07040004</pre> | [InternalError](/core/2/api/essentials/error-handling#internalerror) <pre>(500)</pre> | Unable to hydrate the user "%s": missing profile(s) in the database | Database inconsistency error: a user is referencing non-existing profiles |
| security.user.uninitialized<br/><pre>0x07040005</pre> | [InternalError](/core/2/api/essentials/error-handling#internalerror) <pre>(500)</pre> | Cannot get profiles for uninitialized user "%s" | Attempted to access to an unitialized User object |
| security.user.prevent_overwrite<br/><pre>0x07040006</pre> | [BadRequestError](/core/2/api/essentials/error-handling#badrequesterror) <pre>(400)</pre> | Cannot overwrite existing users. | Attempted to overwrite existing users. Change "onExistingUsers" params to modify this method behavior. |
| security.user.no_profile<br/><pre>0x07040007</pre> | [InternalError](/core/2/api/essentials/error-handling#internalerror) <pre>(500)</pre> | Cannot load user "%s": there is no security profiles associated to it | Database inconsistency error: a user does not have profiles associated to it |

---

Expand Down
2 changes: 1 addition & 1 deletion features-sdk/step_definitions/security-steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Then('I am able to find {int} roles by searching controller:', async function (c
Then('I am able to mGet roles and get {int} roles with the following ids:', async function (count, dataTable) {
const data = this.parseObject(dataTable);
const roleIds = [];
for (const role of Object.entries(data.ids)) {
for (const role of Object.values(data.ids)) {
Copy link
Contributor Author

@scottinet scottinet May 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Review help]

The ids arguments passed to security:mGetRoles was:

{
  ids: [
    ['0', 'test-role'],
    ['1', 'test-role2'],
    ['2', 'test-role3']
  ]
}

Now that security:mGetRoles is stricter, this test fails with a security.role.not_found exception, because there is no role with the id ['0', 'test-role'].

roleIds.push(role);
}

Expand Down
43 changes: 20 additions & 23 deletions lib/api/controller/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class AdminController extends NativeController {
/**
* Reset Redis cache
*/
resetCache (request) {
async resetCache (request) {
const database = this.getString(request, 'database');

let cacheEngine;
Expand All @@ -64,38 +64,33 @@ class AdminController extends NativeController {
throw kerror.get('services', 'cache', 'database_not_found', database);
}

cacheEngine.flushdb(); // NOSONAR
cacheEngine.flushdb();

return Bluebird.resolve({ acknowledge: true });
return { acknowledge: true };
}

/**
* Reset all roles, profiles and users
*/
async resetSecurity (request) {
this._lockAction(
request,
'Kuzzle is already reseting roles, profiles and users.');
this._lockAction(request, 'Kuzzle is already reseting roles, profiles and users.');

const result = {};

try {
const repositories = this.kuzzle.repositories;

const options = { refresh: 'wait_for' };

result.deletedUsers = await repositories.user.truncate(options);
result.deletedProfiles = await repositories.profile.truncate(options);
result.deletedRoles = await repositories.role.truncate(options);

const { profileIds, roleIds } = await this.kuzzle.internalIndex
.bootstrap
.createInitialSecurities();

await Bluebird.all([
repositories.profile.loadProfiles(profileIds, { resetCache: true }),
repositories.role.loadRoles(roleIds, { resetCache: true })
]);
result.deletedUsers = await this.ask(
'core:security:user:truncate',
options);
result.deletedProfiles = await this.ask(
'core:security:profile:truncate',
options);
result.deletedRoles = await this.ask(
'core:security:role:truncate',
options);

await this.kuzzle.internalIndex.bootstrap.createInitialSecurities();
}
finally {
delete _locks.resetSecurity;
Expand Down Expand Up @@ -172,9 +167,11 @@ class AdminController extends NativeController {
const force = this.getBoolean(request, 'force');
const waitForRefresh = this.getRefresh(request, 'true');

const promise = this.kuzzle.repositories.loadSecurities(
securities,
{ force, onExistingUsers, user });
const promise = this.ask('core:security:load', securities, {
force,
onExistingUsers,
user,
});

return this._waitForAction(waitForRefresh, promise);
}
Expand Down
Loading