settingsMetadataGateway->getValue(self::KEY_AUTH_MODE) ?? '')); return $value === self::AUTH_MODE_OAUTH2 ? self::AUTH_MODE_OAUTH2 : self::AUTH_MODE_BASIC; } public function setAuthMode(string $mode): bool { $mode = trim($mode); if (!in_array($mode, [self::AUTH_MODE_BASIC, self::AUTH_MODE_OAUTH2], true)) { return false; } return $this->settingsMetadataGateway->set(self::KEY_AUTH_MODE, $mode, self::KEY_AUTH_MODE); } public function getODataBaseUrl(): string { $value = trim((string) ($this->settingsMetadataGateway->getValue(self::KEY_ODATA_BASE_URL) ?? '')); return $value !== '' ? rtrim($value, '/') : ''; } public function setODataBaseUrl(?string $url): bool { $url = trim((string) ($url ?? '')); if ($url !== '' && !preg_match('#^https://#i', $url)) { return false; } return $this->settingsMetadataGateway->set( self::KEY_ODATA_BASE_URL, $url !== '' ? rtrim($url, '/') : null, self::KEY_ODATA_BASE_URL ); } public function getCompanyName(): string { return trim((string) ($this->settingsMetadataGateway->getValue(self::KEY_COMPANY_NAME) ?? '')); } public function setCompanyName(?string $name): bool { $name = trim((string) ($name ?? '')); return $this->settingsMetadataGateway->set( self::KEY_COMPANY_NAME, $name !== '' ? $name : null, self::KEY_COMPANY_NAME ); } public function getBasicUser(): ?string { $value = trim((string) ($this->settingsMetadataGateway->getValue(self::KEY_BASIC_USER) ?? '')); return $value !== '' ? $value : null; } public function setBasicUser(?string $user): bool { $user = trim((string) ($user ?? '')); return $this->settingsMetadataGateway->set( self::KEY_BASIC_USER, $user !== '' ? $user : null, self::KEY_BASIC_USER ); } public function getBasicPassword(): ?string { return $this->decryptSetting(self::KEY_BASIC_PASSWORD_ENC); } public function setBasicPassword(?string $password): bool { return $this->encryptSetting(self::KEY_BASIC_PASSWORD_ENC, $password); } public function getOAuthTenantId(): ?string { $value = trim((string) ($this->settingsMetadataGateway->getValue(self::KEY_OAUTH_TENANT_ID) ?? '')); return $value !== '' ? $value : null; } public function setOAuthTenantId(?string $tenantId): bool { $tenantId = trim((string) ($tenantId ?? '')); return $this->settingsMetadataGateway->set( self::KEY_OAUTH_TENANT_ID, $tenantId !== '' ? $tenantId : null, self::KEY_OAUTH_TENANT_ID ); } public function getOAuthClientId(): ?string { $value = trim((string) ($this->settingsMetadataGateway->getValue(self::KEY_OAUTH_CLIENT_ID) ?? '')); return $value !== '' ? $value : null; } public function setOAuthClientId(?string $clientId): bool { $clientId = trim((string) ($clientId ?? '')); return $this->settingsMetadataGateway->set( self::KEY_OAUTH_CLIENT_ID, $clientId !== '' ? $clientId : null, self::KEY_OAUTH_CLIENT_ID ); } public function getOAuthClientSecret(): ?string { return $this->decryptSetting(self::KEY_OAUTH_CLIENT_SECRET_ENC); } public function setOAuthClientSecret(?string $secret): bool { return $this->encryptSetting(self::KEY_OAUTH_CLIENT_SECRET_ENC, $secret); } public function getOAuthTokenEndpoint(): ?string { $value = trim((string) ($this->settingsMetadataGateway->getValue(self::KEY_OAUTH_TOKEN_ENDPOINT) ?? '')); return $value !== '' ? $value : null; } public function setOAuthTokenEndpoint(?string $endpoint): bool { $endpoint = trim((string) ($endpoint ?? '')); if ($endpoint !== '' && !preg_match('#^https://#i', $endpoint)) { return false; } return $this->settingsMetadataGateway->set( self::KEY_OAUTH_TOKEN_ENDPOINT, $endpoint !== '' ? $endpoint : null, self::KEY_OAUTH_TOKEN_ENDPOINT ); } /** * Build the full OData entity URL for a given entity set. */ public function buildEntityUrl(string $entitySet): string { $baseUrl = $this->getODataBaseUrl(); $company = rawurlencode($this->getCompanyName()); return $baseUrl . "/Company('" . $company . "')/" . $entitySet; } /** * Validate that required settings for the current auth mode are present. * * @return array List of missing setting descriptions (empty = valid) */ public function validateConfiguration(): array { $missing = []; if ($this->getODataBaseUrl() === '') { $missing[] = 'BC OData Base URL'; } if ($this->getCompanyName() === '') { $missing[] = 'BC Company Name'; } if ($this->getAuthMode() === self::AUTH_MODE_BASIC) { if ($this->getBasicUser() === null) { $missing[] = 'BC Basic Auth User'; } if ($this->getBasicPassword() === null) { $missing[] = 'BC Basic Auth Password'; } } else { if ($this->getOAuthClientId() === null) { $missing[] = 'BC OAuth2 Client ID'; } if ($this->getOAuthClientSecret() === null) { $missing[] = 'BC OAuth2 Client Secret'; } if ($this->getOAuthTokenEndpoint() === null) { $missing[] = 'BC OAuth2 Token Endpoint'; } } return $missing; } public function isConfigured(): bool { return $this->validateConfiguration() === []; } private function decryptSetting(string $key): ?string { $encrypted = trim((string) ($this->settingsMetadataGateway->getValue($key) ?? '')); if ($encrypted === '') { return null; } try { $decrypted = trim($this->settingsCryptoGateway->decryptString($encrypted)); } catch (\Throwable) { return null; } return $decrypted !== '' ? $decrypted : null; } private function encryptSetting(string $key, ?string $value): bool { $value = trim((string) ($value ?? '')); if ($value === '') { return $this->settingsMetadataGateway->set($key, null, $key); } try { $encrypted = $this->settingsCryptoGateway->encryptString($value); } catch (\Throwable) { return false; } return $this->settingsMetadataGateway->set($key, $encrypted, $key); } }