Skip to content

Commit

Permalink
Merge pull request #111 from Saeven/feature/php74-removal
Browse files Browse the repository at this point in the history
Remove annotations, favors attributes, updates Doctrine, adds Psalm.
  • Loading branch information
Saeven authored Mar 21, 2024
2 parents 41c8027 + 077af52 commit 5d94da5
Show file tree
Hide file tree
Showing 37 changed files with 313 additions and 448 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/phpspec-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
operating-system: [ ubuntu-20.04 ]
php-versions: [ '7.4', '8.0.12', '8.1', '8.2', '8.3' ]
php-versions: [ '8.1', '8.2', '8.3' ]
name: Evaluate Behavior, ${{ matrix.php-versions }} on ${{ matrix.operating-system }}
steps:
# Get the source code
Expand Down
16 changes: 6 additions & 10 deletions bundle/Spec/CirclicalUser/Objects/SampleUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,14 @@ class SampleUser implements UserInterface
{
private int $id;

/**
* @var RoleInterface[]
*/
/**@var RoleInterface[] */
private array $roles;

private string $email;

private string $name;

/**
* @var ?AuthenticationRecordInterface
*/
/** @var ?AuthenticationRecordInterface */
private $authenticationRecord;

public function __construct(int $id, array $roles, string $email, string $name)
Expand All @@ -37,22 +33,22 @@ public function getName(): string
return $this->name;
}

public function getId()
public function getId(): int|string|null
{
return $this->id;
}

public function getRoles()
public function getRoles(): array
{
return $this->roles;
}

public function getEmail()
public function getEmail(): string
{
return $this->email;
}

public function addRole(RoleInterface $role)
public function addRole(RoleInterface $role): void
{
$this->roles[] = $role;
}
Expand Down
12 changes: 7 additions & 5 deletions bundle/Spec/CirclicalUser/Service/AccessServiceSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ function let(
$userRules->getUserPermission('beer', $admin)->willReturn($userRule1);
$userRules->getUserPermission('complex', $user)->willReturn($userRule4);
$userRules->create($user, 'string', 'beer', ['buy'])->willReturn($userRule2);
$userRules->save($userRule2)->willReturn(null);
// $userRules->save($userRule2)->willReturn(null);
$userRules->getResourceUserPermission($resourceObject, $user)->willReturn($userRule3);
$userRules->update(Argument::any())->willReturn(null);
// $userRules->update(Argument::any())->willReturn(null);

// to test a case, where a user implementation returns complete garbage
$userRules->getUserPermission('badresult', $user)->willReturn($someObject);
Expand Down Expand Up @@ -204,7 +204,7 @@ function let(

$user->getId()->willReturn(100);
$user->getRoles()->willReturn([$userRole]);
$user->addRole(Argument::any())->willReturn(null);
// $user->addRole(Argument::any())->willReturn(null);

$admin->getId()->willReturn(101);
$admin->getRoles()->willReturn([$adminRole]);
Expand Down Expand Up @@ -285,7 +285,7 @@ function it_accepts_a_user_with_an_id(User $testUser)

function it_rejects_users_with_no_id(User $noUser)
{
$noUser->getId()->willReturn(null);
$noUser->getId()->willReturn();
$this->shouldThrow(UserRequiredException::class)->during('setUser', [$noUser]);
}

Expand All @@ -300,6 +300,7 @@ function it_compiles_roles_properly_1(User $admin)
function it_adds_roles(User $user)
{
$this->setUser($user);
$user->addRole(Argument::type(Role::class))->shouldBeCalled();
$this->hasRoleWithName('admin')->shouldBe(false);
$this->addRoleByName('admin');
$this->hasRoleWithName('admin')->shouldBe(true);
Expand Down Expand Up @@ -496,10 +497,11 @@ function it_can_grant_users_access_to_strings(User $user, $userRules, $userRule2
$this->grantUserAccess('beer', 'buy');
}

function it_can_grant_users_access_to_existing_resources(User $user, ResourceInterface $resourceObject, UserPermissionInterface $userRule3)
function it_can_grant_users_access_to_existing_resources(User $user, UserPermissionProviderInterface $userRules, ResourceInterface $resourceObject, UserPermissionInterface $userRule3)
{
$this->setUser($user);
$this->isAllowed($resourceObject, 'foo')->shouldBe(false);
$userRules->update($userRule3)->shouldBeCalled();
$userRule3->addAction('foo')->shouldBeCalled();
$this->grantUserAccess($resourceObject, 'foo');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
use CirclicalUser\Mapper\UserMapper;
use CirclicalUser\Provider\UserResetTokenInterface;
use CirclicalUser\Service\AuthenticationService;
use CirclicalUser\Service\PasswordChecker\Passwdqc;
use CirclicalUser\Service\PasswordChecker\PasswordNotChecked;
use CirclicalUser\Service\PasswordChecker\Zxcvbn;
use ParagonIE\Halite\HiddenString;
Expand Down
File renamed without changes.
16 changes: 9 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@
"prefer-stable": true,
"require": {
"ext-json": "*",
"php": "^7.4.0 || ~8.0.12 || ~8.1.0 || ~8.2.0 || ~8.3.0",
"php": "~8.0.12 || ~8.1.0 || ~8.2.0 || ~8.3.0",
"laminas/laminas-eventmanager": "^3.4",
"laminas/laminas-servicemanager": "^3.7",
"laminas/laminas-mvc": "^3.3",
"laminas/laminas-view": "^2.13",
"laminas/laminas-http": "^2.15",
"laminas/laminas-router": "^3.5",
"doctrine/doctrine-orm-module": "^4.1|~5.1|~6.1",
"doctrine/doctrine-module": "^4.2|~5.1|~6.0|~6.1",
"doctrine/doctrine-orm-module": "~5.3.0|~6.1",
"doctrine/doctrine-module": "~6.0.0|~6.1.0",
"doctrine/orm": "^2.10",
"paragonie/halite": "^4.7| ^5.0",
"paragonie/halite": "~5.1.0",
"paragonie/hidden-string": "v2.0.0",
"ramsey/uuid": "^4",
"ramsey/uuid-doctrine": "^1.6",
"laminas/laminas-validator": "^2.15"
Expand All @@ -48,10 +49,10 @@
"codacy/coverage": "^1.0",
"bjeavons/zxcvbn-php": "^1.0",
"laminas/laminas-coding-standard": "^2.3.0",
"phpstan/phpstan": "1.1.1"
"phpstan/phpstan": "~1.10.0",
"vimeo/psalm": "5.23.1"
},
"suggest": {
"paragonie/passwdqc": "Add built-in support for password-strength checking! See README for configuration details.",
"bjeavons/zxcvbn-php": "Even better password checking!",
"laminas/laminas-diactoros": "Recommended to support middleware guards.",
"laminas/laminas-psr7bridge": "Recommended to support middleware guards.",
Expand All @@ -71,7 +72,8 @@
],
"cs": "vendor/bin/phpcs",
"stan": "vendor/bin/phpstan analyse -c ./phpstan.neon --memory-limit 1G --xdebug --ansi -vvv src",
"test": "XDEBUG_MODE=coverage vendor/bin/phpspec run"
"test": "XDEBUG_MODE=coverage vendor/bin/phpspec run",
"psalm": "vendor/bin/psalm --shepherd"
},
"config": {
"allow-plugins": {
Expand Down
3 changes: 2 additions & 1 deletion config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use CirclicalUser\View\Helper\RoleAccessViewHelper;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;

use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use function dirname;

return [
Expand Down Expand Up @@ -62,7 +63,7 @@

'driver' => [
'circlical_entities' => [
'class' => AnnotationDriver::class,
'class' => AttributeDriver::class,
'paths' => [
dirname(__DIR__) . '/src/Entity',
],
Expand Down
7 changes: 1 addition & 6 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
parameters:
level: 5
ignoreErrors:
- '#Parameter \#3 \$options of function setcookie expects array#'
- '#Property CirclicalUser\\Entity\\UserApiToken::\$creation_time is never read, only written.#'
- '#Property CirclicalUser\\Service\\PasswordChecker\\PasswordNotChecked::\$creationOptions is never read, only written.#'
- '#Property CirclicalUser\\Service\\PasswordChecker\\Passwdqc::\$creationOptions is never read, only written.#'
- '#Property CirclicalUser\\Entity\\UserResetToken::\$status is never read, only written.#'
- '#Property CirclicalUser\\Entity\\UserResetToken::\$id is never written, only read.#'
- '#Call to method check\(\) on an unknown class ParagonIE\\Passwdqc\\Passwdqc#'
- '#Instantiated class ParagonIE\\Passwdqc\\Passwdqc not found.#'

- '#Parameter \$targetEntity of attribute class Doctrine#'

17 changes: 17 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<psalm
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src"/>
</projectFiles>

<issueHandlers>
<PropertyNotSetInConstructor errorLevel="suppress" />
<MoreSpecificReturnType errorLevel="suppress" />
<LessSpecificReturnStatement errorLevel="suppress" />
</issueHandlers>
</psalm>
76 changes: 23 additions & 53 deletions src/Entity/Authentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,57 +12,30 @@
use function base64_decode;
use function base64_encode;

/**
* @ORM\Entity
* @ORM\Table(name="users_auth", indexes={@ORM\Index(name="username_idx", columns={"username"})})
*/
#[ORM\Entity, ORM\Table(name: 'users_auth')]
#[ORM\Index(name: 'username_idx', columns: ['username'])]
class Authentication implements AuthenticationRecordInterface
{
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="CirclicalUser\Entity\User", inversedBy="authenticationRecord")
* @ORM\JoinColumn(onDelete="CASCADE")
*
* @var UserInterface
*/
private $user;
/** @psalm-suppress ArgumentTypeCoercion */
#[ORM\Id]
#[ORM\OneToOne(targetEntity: 'CirclicalUser\Entity\User', inversedBy: 'authenticationRecord')]
#[ORM\JoinColumn(onDelete: 'CASCADE')]
private UserInterface $user;

/**
* @ORM\Column(type="string", unique=true, nullable=false, length=254)
*
* @var string
*/
private $username;
#[ORM\Column(type: "string", length: 254, unique: true, nullable: false)]
private string $username;

/**
* @ORM\Column(type="string", nullable=false, length=255)
*
* @var string
*/
private $hash;
#[ORM\Column(type: "string", length: 255, nullable: false)]
private string $hash;

/**
* A base64-encoded representation of the user's session key
*
* @ORM\Column(type="string", nullable=true, length=192, options={"fixed" = true})
*
* @var string
*/
private $session_key;
#[ORM\Column(type: "string", length: 192, nullable: true, options: ['fixed' => true])]
private string $session_key;

/**
* @ORM\Column(type="string", nullable=true, length=32, options={"fixed" = true})
*
* @var string
*/
private $reset_hash;
#[ORM\Column(type: "string", length: 32, nullable: true, options: ['fixed' => true])]
private ?string $reset_hash;

/**
* @ORM\Column(type="datetime_immutable", nullable=true)
*
* @var DateTimeImmutable
*/
private $reset_expiry;
#[ORM\Column(type: "datetime_immutable", nullable: true)]
private ?DateTimeImmutable $reset_expiry;

public function __construct(UserInterface $user, string $username, string $hash, string $encodedSessionKey)
{
Expand Down Expand Up @@ -92,7 +65,7 @@ public function getHash(): string
return $this->hash;
}

public function setHash(string $hash)
public function setHash(string $hash): void
{
$this->hash = $hash;
}
Expand All @@ -119,12 +92,12 @@ public function setSessionKey(string $sessionKey): void
* Instead of setting a bas64-encoded string, you can set the raw bytes for the key.
* This setter will base64-encode.
*/
public function setRawSessionKey(string $sessionKey): void
public function setRawSessionKey(string $rawKey): void
{
$this->session_key = base64_encode($sessionKey);
$this->session_key = base64_encode($rawKey);
}

public function getResetHash(): string
public function getResetHash(): ?string
{
return $this->reset_hash;
}
Expand All @@ -134,7 +107,7 @@ public function setResetHash(string $resetHash): void
$this->reset_hash = $resetHash;
}

public function getResetExpiry(): DateTimeImmutable
public function getResetExpiry(): ?DateTimeImmutable
{
return $this->reset_expiry;
}
Expand All @@ -144,10 +117,7 @@ public function setResetExpiry(DateTimeImmutable $dateTime): void
$this->reset_expiry = $dateTime;
}

/**
* @return mixed
*/
public function getUserId()
public function getUserId(): int|string
{
return $this->getUser()->getId();
}
Expand Down
54 changes: 15 additions & 39 deletions src/Entity/GroupPermission.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,48 +13,24 @@

/**
* An example entity that represents an action rule.
*
* @ORM\Entity
* @ORM\Table(name="acl_actions")
*/
#[ORM\Entity, ORM\Table(name: 'acl_actions')]
class GroupPermission implements GroupPermissionInterface
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*
* @var int
*/
protected $id;

/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
protected $resource_class;

/**
* @ORM\Column(type="string", length=255)
*
* @var string
*/
protected $resource_id;

/**
* @ORM\ManyToOne(targetEntity="CirclicalUser\Entity\Role")
*
* @var RoleInterface
*/
protected $role;

/**
* @ORM\Column(type="array")
*
* @var array
*/
protected $actions;
#[ORM\Id, ORM\Column(type: "integer"), ORM\GeneratedValue(strategy: "AUTO")]
protected ?int $id = null;

#[ORM\Column(type: "string", length: 255)]
protected string $resource_class;

#[ORM\Column(type: "string", length: 255)]
protected string $resource_id;

#[ORM\ManyToOne(targetEntity: Role::class)]
protected RoleInterface $role;

#[ORM\Column(type: 'array')]
protected array $actions;

public function __construct(RoleInterface $role, string $resourceClass, string $resourceId, array $actions)
{
Expand Down
Loading

0 comments on commit 5d94da5

Please sign in to comment.