Skip to content

Commit

Permalink
Update sdk to match authsignal's general sdk conventions (#24)
Browse files Browse the repository at this point in the history
* Change apiBase to apiURL

* Add updateAction function

* Make error handling consistent with general Authsignal SDK conventions

* Update track to use named params within array

* Use single associative array parameter instead of positional params

* Remove redirectUrl from getUser function

* Replace data with attributes

* Add getAuthenticators method

* Fix tests

* Add updateAction test

* Add PHPDoc comment to Update User

* Change order of functions to match Node SDK

* Change updateUser to use patch instead of post

* Reorder tests to match order of SDK functions

* Make attributes optional in track request

* Replace authenticator with attributes param

* Update AuthsignalTest.php

* Replace apiKey with apiSecretKey

* Rename setApiHostname to setApiUrl

* Remove `setApiVersion` and `getApiVersion`. Rename env var AUTHSIGNAL_SERVER_API_ENDPOINT  to AUTHSIGNAL_API_URL

* Fix tests
  • Loading branch information
stevenclouston authored Dec 8, 2024
1 parent 877abd6 commit 108a2ac
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 275 deletions.
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Check out our [official PHP SDK documentation](https://docs.authsignal.com/sdks/
Initialize the Authsignal SDK, ensuring you do not hard code the Authsignal Secret Key, always keep this safe.

```php
Authsignal::setApiKey('secretKey');
Authsignal::setApiSecretKey('secretKey');
```

You can find your `secretKey` in the [Authsignal Portal](https://portal.authsignal.com/organisations/tenants/api).
Expand All @@ -33,18 +33,18 @@ Authsignal has multiple api hosting regions. To view your hostname for your tena
| AU (Sydney) | https://au.signal.authsignal.com/v1 |
| EU (Dublin) | https://eu.signal.authsignal.com/v1 |

You can set the hostname via the following code. If the `setApiHostname` function is not called, the api call defaults to the main Authsignal US region hostname `https://signal.authsignal.com`
You can set the hostname via the following code. If the `setApiUrl` function is not called, the api call defaults to the main Authsignal US region hostname `https://signal.authsignal.com`

An example setting the client to use the AU region.

```php
Authsignal::setApiHostname("https://au.signal.authsignal.com");
Authsignal::setApiUrl("https://au.signal.authsignal.com/v1");
```

Alternatively, an environment variable can be used to set the base URL:
Alternatively, an environment variable can be used to set the API URL:

```bash
AUTHSIGNAL_SERVER_API_ENDPOINT=https://au.signal.authsignal.com/v1
AUTHSIGNAL_API_URL=https://au.signal.authsignal.com/v1
```

## Usage
Expand All @@ -53,6 +53,21 @@ Authsignal's server side signal API has five main calls `track`, `getAction`, `g

For more details on these api calls, refer to our [official PHP SDK docs](https://docs.authsignal.com/sdks/server/php#trackaction).

### Response & Error handling

Example:

```php
$result = Authsignal::updateAction(
userId: $userId,
action: $action,
idempotencyKey: "invalidKey",
attributes: ['state' => 'CHALLENGE_FAILED']
);

# PHP Fatal error: Uncaught AuthsignalNotFoundError: 404 - not_found
```

## License

The library is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
230 changes: 136 additions & 94 deletions lib/Authsignal/Authsignal.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,29 @@ abstract class Authsignal
{
const VERSION = '3.0.1';

public static $apiKey;
public static $apiSecretKey;

public static $apiHostname = 'https://signal.authsignal.com';

public static $apiVersion = 'v1';
public static $apiUrl = 'https://signal.authsignal.com';

private static $curlOpts = array();
private static $validCurlOpts = array(CURLOPT_CONNECTTIMEOUT,
CURLOPT_CONNECTTIMEOUT_MS,
CURLOPT_TIMEOUT,
CURLOPT_TIMEOUT_MS);

public static function getApiKey()
public static function getApiSecretKey()
{
return self::$apiKey;
return self::$apiSecretKey;
}

public static function setApiKey($apiKey)
public static function setApiSecretKey($apiSecretKey)
{
self::$apiKey = $apiKey;
self::$apiSecretKey = $apiSecretKey;
}

public static function setApiHostname($hostname)
public static function setApiUrl($apiUrl)
{
self::$apiHostname = $hostname;
self::$apiUrl = $apiUrl;
}

public static function setCurlOpts($curlOpts)
Expand All @@ -53,125 +51,109 @@ public static function getCurlOpts()
return self::$curlOpts;
}

public static function getApiVersion()
{
return self::$apiVersion;
}

public static function setApiVersion($apiVersion)
{
self::$apiVersion = $apiVersion;
}

/**
* Track an action
* @param string $userId The userId of the user you are tracking the action for
* @param string $action The action code that you are tracking
* @param Array $payload An array of attributes to track.
* Get a user
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user you are tracking the action for
* @return Array The authsignal response
*/
public static function track(string $userId, string $action, Array $payload)
public static function getUser(array $params)
{
$request = new AuthsignalClient();
$userId = urlencode($userId);
$action = urlencode($action);
list($response, $request) = $request->send("/users/{$userId}/actions/{$action}", $payload, 'post');

$userId = urlencode($params['userId']);

$path = "/users/{$userId}";
list($response, $request) = $request->send($path, null, 'get');

return $response;
}

/**
* Get an action
* @param string $userId The userId of the user you are tracking the action for
* @param string $action The action code that you are tracking
* @param string $idempotencyKey The action code that you are tracking
* @return Array The authsignal response
* Update User
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user to update
* - array 'attributes': The attributes to update for the user
* @return array The authsignal response
*/
public static function getAction(string $userId, string $action, string $idempotencyKey)
public static function updateUser(array $params)
{
$request = new AuthsignalClient();
$userId = urlencode($userId);
$action = urlencode($action);
list($response, $request) = $request->send("/users/{$userId}/actions/{$action}/{$idempotencyKey}", array(), 'get');

return $response;
$request = new AuthsignalClient();
$userId = urlencode($params['userId']);
$attributes = $params['attributes'];
$path = "/users/{$userId}";
list($response, $request) = $request->send($path, $attributes, 'patch');
return $response;
}

/**
* Get a user
* @param string $userId The userId of the user you are tracking the action for
* @param string $redirectUrl The redirectUrl if using the redirect flow (optional)
* Delete a user
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user you want to delete
* @return Array The authsignal response
*/
public static function getUser(string $userId, string $redirectUrl = null)
public static function deleteUser(array $params)
{
$request = new AuthsignalClient();
$userId = urlencode($userId);

$redirectUrl = empty($redirectUrl) ? null : urlencode($redirectUrl);

$path = empty($redirectUrl) ? "/users/{$userId}" : "/users/{$userId}?redirectUrl={$redirectUrl}";
list($response, $request) = $request->send($path, null, 'get');

$userId = urlencode($params['userId']);
$path = "/users/{$userId}";
list($response, $request) = $request->send($path, null, 'delete');
return $response;
}

public static function updateUser(string $userId, array $data)
{
$request = new AuthsignalClient();
$userId = urlencode($userId);
$path = "/users/{$userId}";
list($response, $request) = $request->send($path, $data, 'post');
return $response;
}


/**
* Enroll Authenticators
* @param string $userId The userId of the user you are tracking the action for
* @param Array $authenticator The authenticator object
* @return Array The authsignal response
* Get Authenticators
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user whose authenticators you want to retrieve
* @return array The list of user authenticators
* @throws AuthsignalApiException if the request fails
*/
public static function enrollVerifiedAuthenticator(string $userId, Array $authenticator)
public static function getAuthenticators(array $params)
{
$request = new AuthsignalClient();
$userId = urlencode($userId);
list($response, $request) = $request->send("/users/{$userId}/authenticators", $authenticator, 'post');

return $response;
$userId = urlencode($params['userId']);
$path = "/users/{$userId}/authenticators";

list($response, $request) = $request->send($path, null, 'get');
return $response;
}

/**
* Delete a user
* @param string $userId The userId of the user you want to delete

/**
* Enroll Authenticators
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user you are tracking the action for
* - array 'attributes': The authenticator object
* @return Array The authsignal response
*/
public static function deleteUser(string $userId)
public static function enrollVerifiedAuthenticator(array $params)
{
$request = new AuthsignalClient();
$userId = urlencode($userId);
$path = "/users/{$userId}";
list($response, $request) = $request->send($path, null, 'delete');
$userId = urlencode($params['userId']);
$attributes = $params['attributes'];
list($response, $request) = $request->send("/users/{$userId}/authenticators", $attributes, 'post');

return $response;
}

/**
* Delete a user authenticator
* @param string $userId The userId of the user
* @param string $userAuthenticatorId The userAuthenticatorId of the authenticator
* Delete an authenticator
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user
* - string 'userAuthenticatorId': The userAuthenticatorId of the authenticator
* @return Array The authsignal response
*/
public static function deleteAuthenticator(string $userId, string $userAuthenticatorId) {
if (empty($userId)) {
*/
public static function deleteAuthenticator(array $params) {
if (empty($params['userId'])) {
throw new InvalidArgumentException('user_id cannot be empty');
}

if (empty($userAuthenticatorId)) {
if (empty($params['userAuthenticatorId'])) {
throw new InvalidArgumentException('user_authenticator_id cannot be empty');
}

$userId = urlencode($userId);
$userAuthenticatorId = urlencode($userAuthenticatorId);
$userId = urlencode($params['userId']);
$userAuthenticatorId = urlencode($params['userAuthenticatorId']);
$path = "/users/{$userId}/authenticators/{$userAuthenticatorId}";

$request = new AuthsignalClient();
Expand All @@ -184,22 +166,45 @@ public static function deleteAuthenticator(string $userId, string $userAuthentic
}
}

/**
* Track an action
*
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user you are tracking the action for
* - string 'action': The action code that you are tracking
* - array 'attributes': An array of attributes to track (optional)
* @return array The authsignal response
*/
public static function track(array $params)
{
$request = new AuthsignalClient();
$userId = urlencode($params['userId']);
$action = urlencode($params['action']);
$attributes = isset($params['attributes']) ? $params['attributes'] : [];

$requestBody = ['attributes' => $attributes];

list($response, $request) = $request->send("/users/{$userId}/actions/{$action}", $requestBody, 'post');

return $response;
}

/**
* Validate Challenge
* Validates the token returned on a challenge response, this is a critical security measure
* also performs a back-end call to validate the state
* @param string|null $userId The userId of the user you are tracking the action for
* @param string $token The JWT token string returned on a challenge response
* @param array $params An associative array of parameters:
* - string 'token': The JWT token string returned on a challenge response
* - string|null 'userId': The userId of the user you are tracking the action for (optional)
* - string|null 'action': The action code that you are tracking (optional)
* @return Array The authsignal response
*/
public static function validateChallenge(string $token, ?string $userId = null, ?string $action = null)
public static function validateChallenge(array $params)
{
$request = new AuthsignalClient();

$payload = [
'userId' => $userId,
'action' => $action,
'token' => $token
'userId' => $params['userId'] ?? null,
'action' => $params['action'] ?? null,
'token' => $params['token']
];

list($response, $request) = $request->send("/validate", $payload, 'post');
Expand All @@ -210,4 +215,41 @@ public static function validateChallenge(string $token, ?string $userId = null,

return $response;
}

/**
* Get an action
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user you are tracking the action for
* - string 'action': The action code that you are tracking
* - string 'idempotencyKey': The idempotency key for the action
* @return Array The authsignal response
*/
public static function getAction(array $params)
{
$request = new AuthsignalClient();
$userId = urlencode($params['userId']);
$action = urlencode($params['action']);
$idempotencyKey = urlencode($params['idempotencyKey']);
list($response, $request) = $request->send("/users/{$userId}/actions/{$action}/{$idempotencyKey}", array(), 'get');

return $response;
}

/**
* Update Action
* @param array $params An associative array of parameters:
* - string 'userId': The userId of the user to update the action for
* - string 'action': The action code to update
* - string 'idempotencyKey': The idempotency key for the action
* - array 'attributes': Additional attributes for the action
* @return array The Authsignal response
*/
public static function updateAction(array $params)
{
$request = new AuthsignalClient();
$path = "/users/" . urlencode($params['userId']) . "/actions/" . urlencode($params['action']) . "/" . urlencode($params['idempotencyKey']);

list($response, $request) = $request->send($path, $params['attributes'], 'patch');
return $response;
}
}
Loading

0 comments on commit 108a2ac

Please sign in to comment.