Completed
Push — master ( b8492c...7ef722 )
by Blizzz
158:19 queued 134:06
created

PublicKeyToken::setScope()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/** @noinspection ALL */
3
declare(strict_types=1);
4
/**
5
 * @copyright Copyright (c) 2018 Roeland Jago Douma <[email protected]>
6
 *
7
 * @author Roeland Jago Douma <[email protected]>
8
 *
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
namespace OC\Authentication\Token;
27
28
use OCP\AppFramework\Db\Entity;
29
30
/**
31
 * @method void setId(int $id)
32
 * @method void setUid(string $uid);
33
 * @method void setLoginName(string $loginname)
34
 * @method void setName(string $name)
35
 * @method string getToken()
36
 * @method void setType(int $type)
37
 * @method int getType()
38
 * @method void setRemember(int $remember)
39
 * @method void setLastActivity(int $lastactivity)
40
 * @method int getLastActivity()
41
 * @method string getPrivateKey()
42
 * @method void setPrivateKey(string $key)
43
 * @method string getPublicKey()
44
 * @method void setPublicKey(string $key)
45
 * @method void setVersion(int $version)
46
 */
47
class PublicKeyToken extends Entity implements IToken {
48
49
	const VERSION = 2;
50
51
	/** @var string user UID */
52
	protected $uid;
53
54
	/** @var string login name used for generating the token */
55
	protected $loginName;
56
57
	/** @var string encrypted user password */
58
	protected $password;
59
60
	/** @var string token name (e.g. browser/OS) */
61
	protected $name;
62
63
	/** @var string */
64
	protected $token;
65
66
	/** @var int */
67
	protected $type;
68
69
	/** @var int */
70
	protected $remember;
71
72
	/** @var int */
73
	protected $lastActivity;
74
75
	/** @var int */
76
	protected $lastCheck;
77
78
	/** @var string */
79
	protected $scope;
80
81
	/** @var int */
82
	protected $expires;
83
84
	/** @var string */
85
	protected $privateKey;
86
87
	/** @var string */
88
	protected $publicKey;
89
90
	/** @var int */
91
	protected $version;
92
93
	public function __construct() {
94
		$this->addType('uid', 'string');
95
		$this->addType('loginName', 'string');
96
		$this->addType('password', 'string');
97
		$this->addType('name', 'string');
98
		$this->addType('token', 'string');
99
		$this->addType('type', 'int');
100
		$this->addType('remember', 'int');
101
		$this->addType('lastActivity', 'int');
102
		$this->addType('lastCheck', 'int');
103
		$this->addType('scope', 'string');
104
		$this->addType('expires', 'int');
105
		$this->addType('publicKey', 'string');
106
		$this->addType('privateKey', 'string');
107
		$this->addType('version', 'int');
108
	}
109
110
	public function getId(): int {
111
		return $this->id;
112
	}
113
114
	public function getUID(): string {
115
		return $this->uid;
116
	}
117
118
	/**
119
	 * Get the login name used when generating the token
120
	 *
121
	 * @return string
122
	 */
123
	public function getLoginName(): string {
124
		return parent::getLoginName();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method getLoginName() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
125
	}
126
127
	/**
128
	 * Get the (encrypted) login password
129
	 *
130
	 * @return string|null
131
	 */
132
	public function getPassword() {
133
		return parent::getPassword();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method getPassword() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
134
	}
135
136 View Code Duplication
	public function jsonSerialize() {
137
		return [
138
			'id' => $this->id,
139
			'name' => $this->name,
140
			'lastActivity' => $this->lastActivity,
141
			'type' => $this->type,
142
			'scope' => $this->getScopeAsArray()
143
		];
144
	}
145
146
	/**
147
	 * Get the timestamp of the last password check
148
	 *
149
	 * @return int
150
	 */
151
	public function getLastCheck(): int {
152
		return parent::getLastCheck();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method getLastCheck() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
153
	}
154
155
	/**
156
	 * Get the timestamp of the last password check
157
	 *
158
	 * @param int $time
159
	 */
160
	public function setLastCheck(int $time) {
161
		parent::setLastCheck($time);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method setLastCheck() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
162
	}
163
164
	public function getScope(): string {
165
		$scope = parent::getScope();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method getScope() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
166
		if ($scope === null) {
167
			return '';
168
		}
169
170
		return $scope;
171
	}
172
173 View Code Duplication
	public function getScopeAsArray(): array {
174
		$scope = json_decode($this->getScope(), true);
175
		if (!$scope) {
176
			return [
177
				'filesystem'=> true
178
			];
179
		}
180
		return $scope;
181
	}
182
183
	public function setScope($scope) {
184
		if (is_array($scope)) {
185
			parent::setScope(json_encode($scope));
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method setScope() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
186
		} else {
187
			parent::setScope((string)$scope);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method setScope() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
188
		}
189
	}
190
191
	public function getName(): string {
192
		return parent::getName();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method getName() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OCA\OAuth2\Db\Client, OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken, OC\Tagging\Tag. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
193
	}
194
195
	public function getRemember(): int {
196
		return parent::getRemember();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method getRemember() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
197
	}
198
199
	public function setToken(string $token) {
200
		parent::setToken($token);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method setToken() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OCA\DAV\Db\Direct, OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
201
	}
202
203
	public function setPassword(string $password = null) {
204
		parent::setPassword($password);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method setPassword() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
205
	}
206
207
	public function setExpires($expires) {
208
		parent::setExpires($expires);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method setExpires() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
209
	}
210
211
	/**
212
	 * @return int|null
213
	 */
214
	public function getExpires() {
215
		return parent::getExpires();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class OCP\AppFramework\Db\Entity as the method getExpires() does only exist in the following sub-classes of OCP\AppFramework\Db\Entity: OC\Authentication\Token\DefaultToken, OC\Authentication\Token\PublicKeyToken. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
216
	}
217
}
218