Nextcloud App Ecosystem V2 provides a new API for external apps on different programming languages
| Currently in a prototyping stage
Docs can be found here.
base.php
adjustment for authentication of Ex apps (patch).
protected static function tryAppEcosystemV2Login(OCP\IRequest $request): bool {
$appManager = Server::get(OCP\App\IAppManager::class);
if (!$request->getHeader('AE-SIGNATURE')) {
return false;
}
if (!$appManager->isInstalled('app_ecosystem_v2')) {
return false;
}
$appEcosystemV2Service = Server::get(OCA\AppEcosystemV2\Service\AppEcosystemV2Service::class);
return $appEcosystemV2Service->validateExAppRequestToNC($request);
}
base.php - handleLogin
if (self::tryAppEcosystemV2Login($request)) {
return true;
}
AppEcosystemV2 adds separate authentication for external apps. This authentication is based on a shared secret between Nextcloud and the external app.
- ExApp sends a request to Nextcloud
- Nextcloud passes request to AppEcosystemV2
- AppEcosystemV2 validates request (see authentication section)
- Request is accepted/rejected
sequenceDiagram
participant ExApp
box Nextcloud
participant Nextcloud
participant AppEcosystemV2
end
ExApp->>+Nextcloud: Request to API
Nextcloud->>+AppEcosystemV2: Validate request
AppEcosystemV2-->>-Nextcloud: Request accepted/rejected
Nextcloud-->>-ExApp: Response (200/401)
Each ExApp request to secured with AEAuth must contain the following headers (order is important):
AE-VERSION
-[required]
minimal version of the AppEcosystemV2EX-APP-ID
-[required]
id of the ExAppEX-APP-VERSION
-[required]
version of the ExAppNC-USER-ID
-[optional]
the user under which the request is made, can be empty in case of system apps (more details in scopes section)AE-DATA-HASH
-[required]
hash of the request body (see details in signature section)AE-SIGN-TIME
-[required]
unix timestamp of the requestAE-SIGNATURE
-[required]
signature of the request (see details signature section)
AppEcosystemV2 signature (AE-SIGNATURE) is a HMAC-SHA256 hash of the request signed with the shared secret.
Depending on request method signing body is different:
GET
- method
- uri (with urlencoded query params)
- headers (
AE-VERSION
,EX-APP-ID
,EX-APP-VERSION
,NC-USER-ID
,AE-DATA-HASH
,AE-SIGN-TIME
)
- Others
- method
- uri (with urlencoded query params)
- headers (
AE-VERSION
,EX-APP-ID
,EX-APP-VERSION
,NC-USER-ID
,AE-DATA-HASH
,AE-SIGN-TIME
) - xxh64 hash from request body (post data, json, files, etc)
AE-DATA-HASH
header must contain a xxh64 hash of the request body.
It's calculated even if the request body is empty (e.g. empty hash: ef46db3751d8e999
).
AppEcosystemV2 supports the following default scopes:
BASIC_API_SCOPE
- init scope, used when ExApp is on initialization step and has no user contextSYSTEM_API_SCOPE
- configured for system apps, mostly has no user contextDAV_API_SCOPE
- scope for dav requests, has user context
sequenceDiagram
autonumber
participant ExApp
box Nextcloud
participant Nextcloud
participant AppEcosystemV2
end
ExApp->>+Nextcloud: Request to API
Nextcloud->>Nextcloud: Check if AE-SIGNATURE header exists
Nextcloud-->>ExApp: Reject if AE-SIGNATURE header not exists
Nextcloud->>Nextcloud: Check if AppEcosystemV2 enabled
Nextcloud-->>ExApp: Reject if AppEcosystemV2 not enabled
Nextcloud->>+AppEcosystemV2: Validate request
AppEcosystemV2-->>AppEcosystemV2: Check if ExApp exists and enabled
AppEcosystemV2-->>Nextcloud: Reject if ExApp not exists or disabled
AppEcosystemV2-->>AppEcosystemV2: Validate AE-SIGN-TIME
AppEcosystemV2-->>Nextcloud: Reject if sign time diff > 5 min
AppEcosystemV2-->>AppEcosystemV2: Generate and validate AE-SIGNATURE
AppEcosystemV2-->>Nextcloud: Reject if signature not match
AppEcosystemV2-->>AppEcosystemV2: Validate AE-DATA-HASH
AppEcosystemV2-->>Nextcloud: Reject if data hash not match
AppEcosystemV2-->>AppEcosystemV2: Check API scope
AppEcosystemV2-->>Nextcloud: Reject if API scope not match
AppEcosystemV2-->>AppEcosystemV2: Check if user interacted with ExApp
AppEcosystemV2-->>Nextcloud: Reject if user has not interacted with ExApp (attempt to bypass user)
AppEcosystemV2-->>AppEcosystemV2: Check if user is not empty and active
AppEcosystemV2-->>Nextcloud: Set active user
AppEcosystemV2->>-Nextcloud: Request accepted/rejected
Nextcloud->>-ExApp: Response (200/401)
In Admin section you can configure existing external apps.