Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,3 @@ phpcs.xml
/vendor/*
/wpcs/*

!/.gitignore
1 change: 0 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

return (new PhpCsFixer\Config())
->setRules([
'@PHP8x4Migration' => true,
'@PER-CS' => true,
'array_syntax' => ['syntax' => 'short'],
'declare_strict_types' => true,
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
parameters:
level: 5
level: 7
paths:
- ./src
- ./test
43 changes: 41 additions & 2 deletions src/AbstractToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ abstract class AbstractToken

private Configuration $config;

/**
* @var Constraint[]
*/
private array $constraints;

/**
Expand Down Expand Up @@ -92,6 +95,9 @@ protected function validateToken(): void
*/
protected function hasClaim(string $claim): bool
{
if (empty($claim)) {
return false;
}
return $this->token->claims()->has($claim);
}

Expand All @@ -102,13 +108,25 @@ protected function hasClaim(string $claim): bool
*
* @return mixed
*/
protected function getClaim(string $claim)
/**
* Get a claim without checking for existence.
*
* @param string $claim name.
*
* @return mixed
*/
protected function getClaim(string $claim): mixed
{
if (empty($claim)) {
return null;
}
return $this->token->claims()->get($claim);
}

/**
* Get an array of all available claims and their values.
*
* @return array<string, mixed>
*/
protected function getAllClaims(): array
{
Expand All @@ -125,12 +143,19 @@ protected function getAllClaims(): array
*/
public static function base64ToPEMPublicKey(string $data): string
{
if (empty($data)) {
throw new SSOException('Empty base64 data provided for PEM conversion.');
}

$data = strtr($data, [
"\r" => "",
"\n" => "",
]);

if (empty($data)) {
throw new SSOException('Base64 data is empty after cleanup.');
}

return
"-----BEGIN PUBLIC KEY-----\n"
. chunk_split($data, 64)
Expand Down Expand Up @@ -179,12 +204,26 @@ public function getSignerKey(): Key
*/
private function getKey(string $appSecret): Key
{
// Ensure the app secret is not empty to satisfy strict non-empty-string requirements
if (!trim($appSecret)) {
throw new SSOException('Empty appSecret provided when creating signer key.');
}

if (strpos($appSecret, '-----') === 0) {
if (empty($appSecret)) {
throw new SSOException('Empty PEM key provided.');
}
$key = InMemory::plainText($appSecret);
} elseif (strpos($appSecret, 'file://') === 0) {
if (empty($appSecret)) {
throw new SSOException('Empty file path provided.');
}
$key = InMemory::file($appSecret);
} else {
$key = InMemory::plainText(self::base64ToPEMPublicKey($appSecret));
$pem = self::base64ToPEMPublicKey($appSecret);
// After our validation in base64ToPEMPublicKey, we know $pem is non-empty
/** @var non-empty-string $pem */
$key = InMemory::plainText($pem);
}
return $key;
}
Expand Down
4 changes: 2 additions & 2 deletions src/RemoteCall/AbstractRemoteCallHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ abstract class AbstractRemoteCallHandler implements RemoteCallInterface
*
* This will tell Staffbase that everything went OK.
*/
public function exitSuccess()
public function exitSuccess(): void
{
header("HTTP/1.1 200 OK");
exit;
Expand All @@ -41,7 +41,7 @@ public function exitSuccess()
*
* This will tell Staffbase that it should try again later.
*/
public function exitFailure()
public function exitFailure(): void
{
header('HTTP/1.1 500 Internal Server Error');
exit;
Expand Down
4 changes: 2 additions & 2 deletions src/RemoteCall/RemoteCallInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ interface RemoteCallInterface
*
* This will tell Staffbase that everything went OK.
*/
public function exitSuccess();
public function exitSuccess(): void;

/**
* Stop the execution by providing a non 2XX HTTP response
*
* This will tell Staffbase that it should try again later.
*/
public function exitFailure();
public function exitFailure(): void;
}
2 changes: 1 addition & 1 deletion src/SSOData/ClaimAccessTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ abstract protected function getClaim(string $claim);
/**
* Get an array of all available claims and their values.
*
* @return array
* @return array<string, mixed>
*/
Comment on lines 42 to +44
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
*
* @return array
*/
/**
* @return array<string, mixed>
*/
*
* @return array<string, mixed>
*/

abstract protected function getAllClaims(): array;

Expand Down
2 changes: 1 addition & 1 deletion src/SSOData/SSODataTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ public function getLocale(): string
/**
* Get the user tags.
*
* @return array|null
* @return array<mixed>|null
*/
public function getTags(): ?array
{
Expand Down
4 changes: 2 additions & 2 deletions src/SSOData/SharedDataTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ trait SharedDataTrait
*/
public function getAudience(): ?string
{
/** @var array|string|null $audience */
/** @var array<string>|string|null $audience */
$audience = $this->getClaimSafe(SharedClaimsInterface::CLAIM_AUDIENCE);

if (is_array($audience)) {
Expand Down Expand Up @@ -127,7 +127,7 @@ public function getRole(): ?string
/**
* Get all stored data.
*
* @return array
* @return array<string,mixed>
*/
public function getData(): array
{
Expand Down
4 changes: 4 additions & 0 deletions src/SSOToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class SSOToken extends AbstractToken implements SharedClaimsInterface, SSODataCl
*/
public function __construct(string $appSecret, string $tokenData, ?int $leeway = 0)
{
if (empty($tokenData)) {
throw new SSOException('Parameter tokenData for SSOToken is empty.');
}

$constrains = [
new StrictValidAt(SystemClock::fromUTC(), $this->getLeewayInterval((int) $leeway)),
new HasInstanceId(),
Expand Down
17 changes: 11 additions & 6 deletions src/SSOTokenGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,28 @@
class SSOTokenGenerator
{
/**
* Create a signed token from an array.
*
* Can be used in development in conjunction with getTokenData.
*
* @param string $privateKey private key
* @param array $tokenData associative array of claims
* @param array<string,mixed> $tokenData associative array of claims
* @param Signer|null $signer the Signer instance to sign the token, defaults to SHA256
*
* @return string Encoded token.
*/
public static function createSignedTokenFromData(string $privateKey, array $tokenData, ?Signer $signer = null): string
{

if (!trim($privateKey)) {
throw new \InvalidArgumentException('Parameter privateKey for token generation is empty.');
}

// After validation, we know $privateKey is non-empty
/** @var non-empty-string $privateKey */
$config = Configuration::forSymmetricSigner($signer ?: new Sha256(), InMemory::plainText($privateKey));
return self::buildToken($config, $tokenData)->toString();
}

/**
* @param Configuration $config
* @param array $tokenData
* @param array<string,mixed> $tokenData
* @return Token
*/
private static function buildToken(Configuration $config, array $tokenData): Token
Expand Down Expand Up @@ -76,6 +78,9 @@ private static function buildToken(Configuration $config, array $tokenData): Tok
);

foreach ($claims as $claim => $value) {
if (empty($claim)) {
continue;
}
$token = $token->withClaim($claim, $value);
}

Expand Down
48 changes: 32 additions & 16 deletions src/SessionHandling/SessionHandlerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
* Trait to handle a php session. Opening, closing and destroying the session.
* Accessing variables, stored in the session.
*
* PHP version 7.4
*
* @category SessionHandling
* @copyright 2017-2025 Staffbase SE.
* @copyright 2017-2022 Staffbase, GmbH.
* @author Daniel Grosse
* @license http://www.apache.org/licenses/LICENSE-2.0
* @link https://github.com/staffbase/plugins-sdk-php
Expand All @@ -29,13 +31,18 @@ trait SessionHandlerTrait
/**
* Open a session.
*
* @param string|null $name of the session
* @param string|null $sessionId
* @param string $name of the session
* @param string $sessionId
*/
protected function openSession(?string $name, ?string $sessionId): void
protected function openSession(string $name = '', string $sessionId = ''): void
{
session_id($sessionId);
session_name($name);

// session_name expects a non-empty string; only set it when provided
if ($name !== '') {
session_name($name);
}

session_start();
}

Expand All @@ -50,25 +57,25 @@ protected function closeSession(): void
/**
* Checks if the given key is set
*
* @param mixed $key
* @param string $key
* @param string|null $parentKey
*
* @return bool
*/
public function hasSessionVar($key, ?string $parentKey = null): bool
public function hasSessionVar(string $key, ?string $parentKey = null): bool
{
return isset($_SESSION[$this->pluginInstanceId][$parentKey ?? self::$KEY_DATA][$key]);
}

/**
* Get a previously set session variable.
*
* @param mixed $key
* @param string $key
* @param string|null $parentKey
*
* @return mixed|null
*/
public function getSessionVar($key, ?string $parentKey = null)
public function getSessionVar(string $key, ?string $parentKey = null)
{
return $_SESSION[$this->pluginInstanceId][$parentKey ?? self::$KEY_DATA][$key] ?? null;
}
Expand All @@ -78,7 +85,7 @@ public function getSessionVar($key, ?string $parentKey = null)
*
* @param string|null $parentKey
*
* @return array
* @return array<string,mixed>
*/
public function getSessionData(?string $parentKey = null): array
{
Expand All @@ -92,7 +99,10 @@ public function getSessionData(?string $parentKey = null): array
* @param string|null $parentKey
*
*/
public function setSessionData($data, ?string $parentKey = null): void
/**
* @param array<string,mixed> $data
*/
public function setSessionData(array $data, ?string $parentKey = null): void
{
$_SESSION[$this->pluginInstanceId][$parentKey ?? self::$KEY_DATA] = $data;
}
Expand All @@ -104,7 +114,11 @@ public function setSessionData($data, ?string $parentKey = null): void
* @param mixed $val
* @param string|null $parentKey
*/
public function setSessionVar($key, $val, ?string $parentKey = null): void
/**
* @param string $key
* @param mixed $val
*/
public function setSessionVar(string $key, mixed $val, ?string $parentKey = null): void
{
$_SESSION[$this->pluginInstanceId][$parentKey ?? self::$KEY_DATA][$key] = $val;
}
Expand All @@ -116,12 +130,12 @@ public function setSessionVar($key, $val, ?string $parentKey = null): void
* @param String|null $sessionId
* @return bool true on success or false on failure.
*/
public function destroySession(?String $sessionId = null): bool
public function destroySession(?string $sessionId = null): bool
{
$sessionId = $sessionId ?: $this->sessionId;

// save the current session
$currentId = session_id();
$currentId = session_id() ?: '';
session_write_close();

// switch to the target session and removes it
Expand All @@ -138,9 +152,11 @@ public function destroySession(?String $sessionId = null): bool
return $result;
}

private function createCompatibleSessionId(String $string): String
private function createCompatibleSessionId(?string $input = ''): string
{
$string = $input ?? '';
$notAllowedCharsPattern = '/[^a-zA-Z0-9,-]/';
return preg_replace($notAllowedCharsPattern, '-', $string);
$replaced = preg_replace($notAllowedCharsPattern, '-', $string);
return (string) $replaced;
}
}
Loading
Loading