Skip to content

Commit

Permalink
Merge pull request #14 from mittwald/feature/ext-auth
Browse files Browse the repository at this point in the history
Add additional authentication mechanisms for extensions
martin-helmich authored Jan 21, 2025

Verified

This commit was signed with the committer’s verified signature.
Freyskeyd Simon Paitrault
2 parents dfd36d9 + 5021c45 commit 32fccf4
Showing 2 changed files with 56 additions and 6 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -29,8 +29,9 @@ different types of authentication:

1. `MittwaldAPIClient::newUnauthenticated()`
2. `MittwaldAPIClient::newWithToken(string $apiToken)` (recommended)
3. `MittwaldAPIClient::newWithCredentials(string $email, string $password)` (does
actually perform a login in the background; does not work when using 2FA)
3. `MittwaldAPIClient::newWithCredentials(string $email, string $password)`, does actually perform a login in the background; does not work when using 2FA.
4. `MittwaldAPIClient::newWithAccessTokenRetrievalKey(string $userId, string $key)`, authenticates an mStudio user using the [access token retrieval key][atrek] mechanism. Only useful if you're building an mStudio extension.
5. `MittwaldAPIClient::newWithExtensionSecret(string $extensionInstanceId, string $extensionSecret)`, authenticates an mStudio extension itself (without any user interaction). Only useful if you're building an mStudio extension.

Have a look at our [API introduction][api-getting-started] for more information
on how to obtain an API token and how to get started with the API.
@@ -53,4 +54,5 @@ foreach ($listProjectResponse->getBody() as $project) {
The API documentation can be found in our [Developer Portal][api-ref]. You can find the operation ID on the right side of each operation.

[api-getting-started]: https://developer.mittwald.de/docs/v2/api/intro
[api-ref]: https://developer.mittwald.de/reference/v2/
[api-ref]: https://developer.mittwald.de/reference/v2/
[atrek]: https://developer.mittwald.de/docs/v2/contribution/overview/concepts/authentication/
54 changes: 51 additions & 3 deletions src/MittwaldAPIV2Client.php
Original file line number Diff line number Diff line change
@@ -5,8 +5,13 @@
namespace Mittwald\ApiClient;

use Mittwald\ApiClient\Generated\V2\ClientImpl;
use Mittwald\ApiClient\Generated\V2\Clients\Marketplace\ExtensionAuthenticateInstance\ExtensionAuthenticateInstanceRequest;
use Mittwald\ApiClient\Generated\V2\Clients\Marketplace\ExtensionAuthenticateInstance\ExtensionAuthenticateInstanceRequestBody;
use Mittwald\ApiClient\Generated\V2\Clients\User\Authenticate\AuthenticateRequest;
use Mittwald\ApiClient\Generated\V2\Clients\User\Authenticate\AuthenticateRequestBody;
use Mittwald\ApiClient\Generated\V2\Clients\User\AuthenticateWithAccessTokenRetrievalKey\AuthenticateWithAccessTokenRetrievalKeyRequest;
use Mittwald\ApiClient\Generated\V2\Clients\User\AuthenticateWithAccessTokenRetrievalKey\AuthenticateWithAccessTokenRetrievalKeyRequestBody;
use SensitiveParameter;

/**
* MittwaldAPIV2Client is the main entry point for the mStudio v2 API.
@@ -24,7 +29,7 @@ class MittwaldAPIV2Client extends ClientImpl
{
private const DEFAULT_BASE_URL = 'https://api.mittwald.de/v2/';

final protected function __construct(string $baseUri, string|null $apiKey = null)
final protected function __construct(string $baseUri, #[SensitiveParameter] string|null $apiKey = null)
{
parent::__construct($baseUri, $apiKey);
}
@@ -38,7 +43,7 @@ final protected function __construct(string $baseUri, string|null $apiKey = null
* @param string $apiToken The API token
* @param string $baseUri The base URL of the API. Defaults to the production API. Note that this is only useful for testing.
*/
public static function newWithToken(string $apiToken, string $baseUri = self::DEFAULT_BASE_URL): static
public static function newWithToken(#[SensitiveParameter] string $apiToken, string $baseUri = self::DEFAULT_BASE_URL): static
{
return new static($baseUri, $apiToken);
}
@@ -67,11 +72,54 @@ public static function newUnauthenticated(string $baseUri = self::DEFAULT_BASE_U
* @param string $password The password of your mStudio user.
* @param string $baseUri The base URL of the API. Defaults to the production API. Note that this is only useful for testing.
*/
public static function newWithCredentials(string $email, string $password, string $baseUri = self::DEFAULT_BASE_URL): static
public static function newWithCredentials(string $email, #[SensitiveParameter] string $password, string $baseUri = self::DEFAULT_BASE_URL): static
{
$authenticateRequest = new AuthenticateRequest(new AuthenticateRequestBody($email, $password));
$authenticateResponse = static::newUnauthenticated($baseUri)->user()->authenticate($authenticateRequest);

return static::newWithToken($authenticateResponse->getBody()->getToken(), baseUri: $baseUri);
}

/**
* Instantiates a new client that is authenticated using an "access token retrieval key".
*
* This is a special mechanism for one-click-authenticating users that are
* redirected to an mStudio extension [1].
*
* [1]: https://developer.mittwald.de/docs/v2/contribution/overview/concepts/authentication/
*
* @param string $userId The ID of the user to authenticate. This value is passed as a parameter during the authentication flow.
* @param string $key The access token retrieval key.
* @param string $baseUri The base URL of the API. Defaults to the production API. Note that this is only useful for testing.
*/
public static function newWithAccessTokenRetrievalKey(string $userId, #[SensitiveParameter] string $key, string $baseUri = self::DEFAULT_BASE_URL): static
{
$authenticateRequest = new AuthenticateWithAccessTokenRetrievalKeyRequest(new AuthenticateWithAccessTokenRetrievalKeyRequestBody(
accessTokenRetrievalKey: $key,
userId: $userId,
));
$authenticateResponse = static::newUnauthenticated($baseUri)->user()->authenticateWithAccessTokenRetrievalKey($authenticateRequest);

return static::newWithToken($authenticateResponse->getBody()->getToken(), baseUri: $baseUri);
}

/**
* Instantiates a client that is authenticated as an mStudio extension (not a user).
*
* @param string $extensionInstanceId The extension instance ID; this is passed to you via a webhook when the extension is installed.
* @param string $extensionSecret The extension instance secret; this is passed to you via a webhook when the extension is installed.
* @param string $baseUri The base URL of the API. Defaults to the production API. Note that this is only useful for testing.
*/
public static function newWithExtensionSecret(string $extensionInstanceId, #[SensitiveParameter] string $extensionSecret, string $baseUri = self::DEFAULT_BASE_URL): static
{
$authenticateRequest = new ExtensionAuthenticateInstanceRequest(
extensionInstanceId: $extensionInstanceId,
body: new ExtensionAuthenticateInstanceRequestBody(
extensionInstanceSecret: $extensionSecret,
)
);
$authenticateResponse = static::newUnauthenticated($baseUri)->marketplace()->extensionAuthenticateInstance($authenticateRequest);

return static::newWithToken($authenticateResponse->getBody()->getPublicToken(), baseUri: $baseUri);
}
}

0 comments on commit 32fccf4

Please sign in to comment.