2.0 release candidate (#3808)

* use SAML interface instead of implementation
* moved implementation of SAML configs to system-configuration base class
* bump composer packages
* simplify configuration for different env
This commit is contained in:
Kevin Papst
2023-02-02 00:45:50 +01:00
committed by GitHub
parent 5711c15eac
commit 63a3ae1147
21 changed files with 272 additions and 395 deletions

View File

@@ -9,9 +9,6 @@
namespace App\Configuration;
/**
* @CloudRequired
*/
final class SamlConfiguration implements SamlConfigurationInterface
{
public function __construct(private SystemConfiguration $configuration)
@@ -35,22 +32,17 @@ final class SamlConfiguration implements SamlConfigurationInterface
public function getAttributeMapping(): array
{
return $this->configuration->findArray('saml.mapping');
return $this->configuration->getSamlAttributeMapping();
}
public function getRolesAttribute(): ?string
{
$attr = $this->configuration->find('saml.roles.attribute');
if (empty($attr)) {
return null;
}
return (string) $attr;
return $this->configuration->getSamlRolesAttribute();
}
public function getRolesMapping(): array
{
return $this->configuration->findArray('saml.roles.mapping');
return $this->configuration->getSamlRolesMapping();
}
public function isRolesResetOnLogin(): bool
@@ -60,6 +52,6 @@ final class SamlConfiguration implements SamlConfigurationInterface
public function getConnection(): array
{
return $this->configuration->findArray('saml.connection');
return $this->configuration->getSamlConnection();
}
}

View File

@@ -9,12 +9,32 @@
namespace App\Configuration;
/**
* @CloudRequired
*/
interface SamlConfigurationInterface
{
/**
* Whether SAML login is activated.
*
* @return bool
*/
public function isActivated(): bool;
/**
* Returns the title that is exclusively used in the frontend.
* Currently, used to display the button in the login screen.
*
* @return string
*/
public function getTitle(): string;
/**
* Returns the provider name that is exclusively used in the frontend.
* Currently, used to display an icon in the login screen.
*
* @return string
*/
public function getProvider(): string;
public function getAttributeMapping(): array;

View File

@@ -218,6 +218,40 @@ final class SystemConfiguration
return (bool) $this->find('saml.roles.resetOnLogin');
}
/**
* @return array<mixed>
*/
public function getSamlRolesMapping(): array
{
return $this->findArray('saml.roles.mapping');
}
/**
* @return array<mixed>
*/
public function getSamlConnection(): array
{
return $this->findArray('saml.connection');
}
/**
* @return array<mixed>
*/
public function getSamlAttributeMapping(): array
{
return $this->findArray('saml.mapping');
}
public function getSamlRolesAttribute(): ?string
{
$attr = $this->find('saml.roles.attribute');
if (empty($attr)) {
return null;
}
return (string) $attr;
}
public function isLdapActive(): bool
{
return (bool) $this->find('ldap.activate');

View File

@@ -9,7 +9,7 @@
namespace App\Saml;
use App\Configuration\SamlConfiguration;
use App\Configuration\SamlConfigurationInterface;
use App\Saml\Security\SamlAuthenticationFailureHandler;
use App\Saml\Security\SamlAuthenticationSuccessHandler;
use Symfony\Component\HttpFoundation\Request;
@@ -40,7 +40,7 @@ class SamlAuthenticator extends AbstractAuthenticator
private SamlAuthenticationFailureHandler $failureHandler,
private SamlAuthFactory $samlAuthFactory,
private SamlProvider $samlProvider,
private SamlConfiguration $configuration
private SamlConfigurationInterface $configuration
) {
}

View File

@@ -18,6 +18,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* A voter to check permissions on Activities.
*
* @extends Voter<string, Activity>
*/
final class ActivityVoter extends Voter
{
@@ -37,11 +39,6 @@ final class ActivityVoter extends Voter
{
}
/**
* @param string $attribute
* @param Activity $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
if (!($subject instanceof Activity)) {
@@ -55,12 +52,6 @@ final class ActivityVoter extends Voter
return true;
}
/**
* @param string $attribute
* @param Activity $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -18,6 +18,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* A voter to check authorization on Customers.
*
* @extends Voter<string, Customer>
*/
final class CustomerVoter extends Voter
{
@@ -41,11 +43,6 @@ final class CustomerVoter extends Voter
{
}
/**
* @param string $attribute
* @param Customer $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
if (!($subject instanceof Customer)) {
@@ -59,12 +56,6 @@ final class CustomerVoter extends Voter
return true;
}
/**
* @param string $attribute
* @param Customer $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -17,6 +17,9 @@ use App\Security\RolePermissionManager;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* @extends Voter<string, Activity|Project|Customer|string>
*/
final class EntityMultiRoleVoter extends Voter
{
/**
@@ -38,11 +41,6 @@ final class EntityMultiRoleVoter extends Voter
{
}
/**
* @param string $attribute
* @param Activity|Project|Customer|string $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
if (!\in_array($attribute, self::ALLOWED_ATTRIBUTES)) {
@@ -60,12 +58,6 @@ final class EntityMultiRoleVoter extends Voter
return false;
}
/**
* @param string $attribute
* @param Activity|Project|Customer|string $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -18,6 +18,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* A voter to check permissions on Projects.
*
* @extends Voter<string, Project>
*/
final class ProjectVoter extends Voter
{
@@ -39,11 +41,6 @@ final class ProjectVoter extends Voter
{
}
/**
* @param string $attribute
* @param Project $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
if (!($subject instanceof Project)) {
@@ -57,12 +54,6 @@ final class ProjectVoter extends Voter
return true;
}
/**
* @param string $attribute
* @param Project $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -15,28 +15,20 @@ use App\Timesheet\TrackingModeService;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* @extends Voter<string, mixed>
*/
final class QuickEntryVoter extends Voter
{
public function __construct(private RolePermissionManager $permissionManager, private TrackingModeService $trackingModeService)
{
}
/**
* @param string $attribute
* @param mixed $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
return 'quick-entry' === $attribute;
}
/**
* @param string $attribute
* @param User $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -14,6 +14,9 @@ use App\Security\RolePermissionManager;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* @extends Voter<string, null>
*/
final class ReportingVoter extends Voter
{
private const ALLOWED_ATTRIBUTES = [
@@ -27,22 +30,11 @@ final class ReportingVoter extends Voter
{
}
/**
* @param string $attribute
* @param null $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
return $subject === null && \in_array($attribute, self::ALLOWED_ATTRIBUTES);
}
/**
* @param string $attribute
* @param null $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -9,7 +9,6 @@
namespace App\Voter;
use App\Entity\Activity;
use App\Entity\User;
use App\Security\RolePermissionManager;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
@@ -17,6 +16,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* A voter to check the free-configurable permission from "kimai.permissions".
*
* @extends Voter<string, null>
*/
final class RolePermissionVoter extends Voter
{
@@ -24,11 +25,6 @@ final class RolePermissionVoter extends Voter
{
}
/**
* @param string $attribute
* @param mixed $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
// we only work on single strings that have no subject
@@ -39,12 +35,6 @@ final class RolePermissionVoter extends Voter
return $this->permissionManager->isRegisteredPermission($attribute);
}
/**
* @param string $attribute
* @param Activity $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -15,6 +15,9 @@ use App\Security\RolePermissionManager;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* @extends Voter<string, Team>
*/
final class TeamVoter extends Voter
{
/**
@@ -30,11 +33,6 @@ final class TeamVoter extends Voter
{
}
/**
* @param string $attribute
* @param Team $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
if (!($subject instanceof Team)) {
@@ -48,12 +46,6 @@ final class TeamVoter extends Voter
return true;
}
/**
* @param string $attribute
* @param Team $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -18,6 +18,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* A voter to check permissions on Timesheets.
*
* @extends Voter<string, Timesheet>
*/
final class TimesheetVoter extends Voter
{
@@ -57,11 +59,6 @@ final class TimesheetVoter extends Voter
{
}
/**
* @param string $attribute
* @param mixed $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
if (!($subject instanceof Timesheet)) {
@@ -75,12 +72,6 @@ final class TimesheetVoter extends Voter
return true;
}
/**
* @param string $attribute
* @param Timesheet $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();

View File

@@ -16,6 +16,8 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/**
* A voter to check permissions on user profiles.
*
* @extends Voter<string, User>
*/
final class UserVoter extends Voter
{
@@ -37,11 +39,6 @@ final class UserVoter extends Voter
{
}
/**
* @param string $attribute
* @param mixed $subject
* @return bool
*/
protected function supports(string $attribute, mixed $subject): bool
{
if (!($subject instanceof User)) {
@@ -55,12 +52,6 @@ final class UserVoter extends Voter
return true;
}
/**
* @param string $attribute
* @param User $subject
* @param TokenInterface $token
* @return bool
*/
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
$user = $token->getUser();