├── .gitignore ├── .travis.yml ├── Module.php ├── README.md ├── composer.json ├── config ├── oauth2.doctrine-orm.global.php.dist └── orm │ ├── ZF.OAuth2.Doctrine.Entity.AccessToken.dcm.xml │ ├── ZF.OAuth2.Doctrine.Entity.AuthorizationCode.dcm.xml │ ├── ZF.OAuth2.Doctrine.Entity.Client.dcm.xml │ ├── ZF.OAuth2.Doctrine.Entity.Jti.dcm.xml │ ├── ZF.OAuth2.Doctrine.Entity.Jwt.dcm.xml │ ├── ZF.OAuth2.Doctrine.Entity.PublicKey.dcm.xml │ ├── ZF.OAuth2.Doctrine.Entity.RefreshToken.dcm.xml │ └── ZF.OAuth2.Doctrine.Entity.Scope.dcm.xml ├── media ├── OAuth2-orm.module.xml ├── OAuth2-orm.skipper └── oauth2-doctrine-erd.png ├── phpcs.xml.dist ├── phpunit.xml ├── src ├── Adapter │ ├── DoctrineAdapter.php │ └── DoctrineAdapterFactory.php ├── ClientAssertionType │ └── AuthorizationCode.php ├── ConfigProvider.php ├── Entity │ ├── AccessToken.php │ ├── AuthorizationCode.php │ ├── Client.php │ ├── Jti.php │ ├── Jwt.php │ ├── PublicKey.php │ ├── RefreshToken.php │ ├── Scope.php │ └── UserInterface.php ├── EventListener │ └── DynamicMappingSubscriber.php ├── Mapper │ ├── AbstractMapper.php │ ├── AccessToken.php │ ├── AuthorizationCode.php │ ├── Client.php │ ├── Jti.php │ ├── Jwt.php │ ├── MapperManager.php │ ├── PublicKey.php │ ├── RefreshToken.php │ ├── Scope.php │ └── User.php ├── Module.php └── Query │ ├── OAuth2ServerInitializer.php │ ├── OAuth2ServerInterface.php │ └── OAuth2ServerTrait.php └── test ├── Bootstrap.php ├── ORM ├── AbstractTest.php ├── AccessTokenTest.php ├── AuthorizationCodeTest.php ├── ClientCredentialsTest.php ├── ClientTest.php ├── JwtAccessTokenTest.php ├── JwtBearerTest.php ├── PublicKeyTest.php ├── RefreshTokenTest.php ├── ScopeTest.php └── UserCredentialsTest.php └── asset ├── data ├── key.pem └── pubkey.pem ├── module └── Doctrine │ ├── Module.php │ ├── config │ ├── module.config.php │ └── orm │ │ └── ZFTest.OAuth2.Doctrine.Entity.User.dcm.xml │ └── src │ ├── Entity │ └── User.php │ └── Listener │ └── TestEvents.php ├── orm-autoload └── local.php └── orm.config.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.phar 3 | composer.lock 4 | test/coverage 5 | build 6 | .DS_Store 7 | /.settings/ 8 | /.buildpath 9 | /.project 10 | /deployment.properties 11 | /deployment.xml 12 | test/asset/orm-autoload/oauth2.doctrine-orm.global.php 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: php 4 | 5 | cache: 6 | directories: 7 | - $HOME/.composer/cache 8 | 9 | env: 10 | global: 11 | - COMPOSER_ARGS="--no-interaction" 12 | 13 | matrix: 14 | fast_finish: true 15 | include: 16 | - php: 7.1 17 | env: 18 | - EXECUTE_COVERAGE=true 19 | - EXECUTE_CS_CHECK=true 20 | - DEPS=lowest 21 | - php: 7.1 22 | env: 23 | - DEPS=latest 24 | - php: 7.2 25 | - php: 7.3 26 | 27 | notifications: 28 | irc: "irc.freenode.org#apigility-dev" 29 | email: false 30 | 31 | before_install: 32 | - if [[ $EXECUTE_COVERAGE != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi 33 | - composer self-update 34 | - chmod -R +rwX test/asset/data 35 | 36 | install: 37 | - if [[ $DEPS == 'latest' ]]; then travis_retry composer update $COMPOSER_ARGS ; fi 38 | - if [[ $DEPS == 'lowest' ]]; then travis_retry composer update --prefer-lowest --prefer-stable $COMPOSER_ARGS ; fi 39 | - travis_retry composer install $COMPOSER_ARGS 40 | - composer show --installed 41 | 42 | script: 43 | - mkdir -p build/logs 44 | - if [[ EXECUTE_COVERAGE == 'true' ]]; then ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml ; fi 45 | - if [[ EXECUTE_COVERAGE != 'true' ]]; then ./vendor/bin/phpunit ; fi 46 | - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/phpcs; fi 47 | 48 | after_script: 49 | - php vendor/bin/coveralls 50 | -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | =7.1", 12 | "zfcampus/zf-oauth2": "^1.4", 13 | "doctrine/orm": "^2.5.11", 14 | "doctrine/doctrine-module": "^1.2 || ^2.1", 15 | "doctrine/doctrine-orm-module": "^1.1.5 || ^2.1", 16 | "zfcampus/zf-mvc-auth": "^1.4.3", 17 | "zendframework/zend-mvc": "^3.0", 18 | "zendframework/zend-config": "^2.6 || ^3.0", 19 | "zendframework/zend-modulemanager": "^2.0", 20 | "zendframework/zend-servicemanager": "^3.0", 21 | "zendframework/zend-i18n": "^2.7" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "^7.0", 25 | "zendframework/zend-form": "^2.10", 26 | "zendframework/zend-loader": "^2.4", 27 | "zendframework/zend-log": "^2.9", 28 | "zendframework/zend-serializer": "^2.7", 29 | "zendframework/zend-test": "^3.1", 30 | "zendframework/zend-authentication": "^2.5", 31 | "zendframework/zend-eventmanager": "^3.2", 32 | "mockery/mockery": "^0.9.5", 33 | "satooshi/php-coveralls": "^1.0", 34 | "api-skeletons/coding-standard": "^1.0" 35 | }, 36 | "autoload": { 37 | "psr-4": { 38 | "ZF\\OAuth2\\Doctrine\\": "src/" 39 | } 40 | }, 41 | "autoload-dev": { 42 | "psr-4": { 43 | "ZFTest\\OAuth2\\Doctrine\\": "test/" 44 | } 45 | }, 46 | "extra": { 47 | "zf": { 48 | "component": "ZF\\OAuth2\\Doctrine", 49 | "config-provider": "ZF\\OAuth2\\Doctrine\\ConfigProvider" 50 | } 51 | }, 52 | "suggest": { 53 | "api-skeletons/zf-oauth2-doctrine-permissions-acl": "Access Control Lists for zf-oauth2-doctrine", 54 | "bushbaby/zf-oauth2-doctrine-mutatetablenames": "Allows configuration of the table names that this module uses" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /config/oauth2.doctrine-orm.global.php.dist: -------------------------------------------------------------------------------- 1 | [ 10 | 'default' => [ 11 | 'object_manager' => 'doctrine.entitymanager.orm_default', 12 | 'event_manager' => 'doctrine.eventmanager.orm_default', 13 | 'driver' => 'doctrine.driver.orm_default', 14 | 'enable_default_entities' => true, 15 | 'bcrypt_cost' => 10, # match php default 16 | 'auth_identity_fields' => ['username'], 17 | // Dynamically map the user_entity to the client_entity 18 | 'dynamic_mapping' => [ 19 | 'user_entity' => [ 20 | 'entity' => $userEntity, 21 | 'field' => 'user', 22 | ], 23 | 'client_entity' => [ 24 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 25 | 'field' => 'client', 26 | 'additional_mapping_data' => [ 27 | 'joinColumns' => [ 28 | [ 29 | 'onDelete' => 'CASCADE' 30 | ], 31 | ], 32 | ], 33 | ], 34 | 'access_token_entity' => [ 35 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\AccessToken', 36 | 'field' => 'accessToken', 37 | 'additional_mapping_data' => [ 38 | 'joinColumns' => [ 39 | [ 40 | 'onDelete' => 'CASCADE' 41 | ], 42 | ], 43 | ], 44 | ], 45 | 'authorization_code_entity' => [ 46 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\AuthorizationCode', 47 | 'field' => 'authorizationCode', 48 | 'additional_mapping_data' => [ 49 | 'joinColumns' => [ 50 | [ 51 | 'onDelete' => 'CASCADE' 52 | ], 53 | ], 54 | ], 55 | ], 56 | 'refresh_token_entity' => [ 57 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\RefreshToken', 58 | 'field' => 'refreshToken', 59 | 'additional_mapping_data' => [ 60 | 'joinColumns' => [ 61 | [ 62 | 'onDelete' => 'CASCADE' 63 | ], 64 | ], 65 | ], 66 | ], 67 | 'scope_entity' => [ 68 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Scope', 69 | 'field' => 'scope', 70 | ], 71 | ], 72 | 'mapping' => [ 73 | 'User' => [ 74 | 'entity' => $userEntity, 75 | 'mapping' => [ 76 | 'user_id' => [ 77 | 'type' => 'field', 78 | 'name' => 'id', 79 | 'datatype' => 'bigint', 80 | ], 81 | 'username' => [ 82 | 'type' => 'field', 83 | 'name' => 'username', 84 | 'datatype' => 'string', 85 | ], 86 | 'password' => [ 87 | 'type' => 'field', 88 | 'name' => 'password', 89 | 'datatype' => 'string', 90 | ], 91 | ], 92 | ], 93 | 94 | 'Client' => [ 95 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 96 | 'mapping' => [ 97 | 'client_id' => [ 98 | 'type' => 'field', 99 | 'name' => 'clientId', 100 | 'datatype' => 'string', 101 | ], 102 | 'client_secret' => [ 103 | 'type' => 'field', 104 | 'name' => 'secret', 105 | 'datatype' => 'string', 106 | ], 107 | 'redirect_uri' => [ 108 | 'type' => 'field', 109 | 'name' => 'redirectUri', 110 | 'datatype' => 'text', 111 | ], 112 | 'grant_types' => [ 113 | 'type' => 'field', 114 | 'name' => 'grantType', 115 | 'datatype' => 'array', 116 | ], 117 | 'scope' => [ 118 | 'type' => 'collection', 119 | 'name' => 'scope', 120 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Scope', 121 | 'mapper' => 'Scope', 122 | ], 123 | 'user_id' => [ 124 | 'type' => 'relation', 125 | 'name' => 'user', 126 | 'entity_field_name' => 'id', 127 | 'entity' => $userEntity, 128 | 'datatype' => 'bigint', 129 | 'allow_null' => true, 130 | ], 131 | ], 132 | ], 133 | 134 | 'AccessToken' => [ 135 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\AccessToken', 136 | 'mapping' => [ 137 | 'access_token' => [ 138 | 'type' => 'field', 139 | 'name' => 'accessToken', 140 | 'datatype' => 'text', 141 | ], 142 | 'expires' => [ 143 | 'type' => 'field', 144 | 'name' => 'expires', 145 | 'datatype' => 'datetime', 146 | ], 147 | 'scope' => [ 148 | 'type' => 'collection', 149 | 'name' => 'scope', 150 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Scope', 151 | 'mapper' => 'Scope', 152 | ], 153 | 'client_id' => [ 154 | 'type' => 'relation', 155 | 'name' => 'client', 156 | 'entity_field_name' => 'clientId', 157 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 158 | 'datatype' => 'bigint', 159 | ], 160 | 'user_id' => [ 161 | 'type' => 'relation', 162 | 'name' => 'user', 163 | 'entity_field_name' => 'id', 164 | 'entity' => $userEntity, 165 | 'datatype' => 'bigint', 166 | 'allow_null' => true, 167 | ], 168 | ], 169 | ], 170 | 171 | 'RefreshToken' => [ 172 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\RefreshToken', 173 | 'mapping' => [ 174 | 'refresh_token' => [ 175 | 'type' => 'field', 176 | 'name' => 'refreshToken', 177 | 'datatype' => 'string', 178 | ], 179 | 'expires' => [ 180 | 'type' => 'field', 181 | 'name' => 'expires', 182 | 'datatype' => 'datetime', 183 | ], 184 | 'scope' => [ 185 | 'type' => 'collection', 186 | 'name' => 'scope', 187 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Scope', 188 | 'mapper' => 'Scope', 189 | ], 190 | 'client_id' => [ 191 | 'type' => 'relation', 192 | 'name' => 'client', 193 | 'entity_field_name' => 'clientId', 194 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 195 | 'datatype' => 'bigint', 196 | ], 197 | 'user_id' => [ 198 | 'type' => 'relation', 199 | 'name' => 'user', 200 | 'entity_field_name' => 'id', 201 | 'entity' => $userEntity, 202 | 'datatype' => 'bigint', 203 | 'allow_null' => true, 204 | ], 205 | ], 206 | ], 207 | 208 | 'AuthorizationCode' => [ 209 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\AuthorizationCode', 210 | 'mapping' => [ 211 | 'authorization_code' => [ 212 | 'type' => 'field', 213 | 'name' => 'authorizationCode', 214 | 'datatype' => 'string', 215 | ], 216 | 'redirect_uri' => [ 217 | 'type' => 'field', 218 | 'name' => 'redirectUri', 219 | 'datatype' => 'text', 220 | ], 221 | 'expires' => [ 222 | 'type' => 'field', 223 | 'name' => 'expires', 224 | 'datatype' => 'datetime', 225 | ], 226 | 'scope' => [ 227 | 'type' => 'collection', 228 | 'name' => 'scope', 229 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Scope', 230 | 'mapper' => 'Scope', 231 | ], 232 | 'id_token' => [ 233 | 'type' => 'field', 234 | 'name' => 'idToken', 235 | 'datatype' => 'text', 236 | ], 237 | 'client_id' => [ 238 | 'type' => 'relation', 239 | 'name' => 'client', 240 | 'entity_field_name' => 'clientId', 241 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 242 | 'datatype' => 'bigint', 243 | ], 244 | 'user_id' => [ 245 | 'type' => 'relation', 246 | 'name' => 'user', 247 | 'entity_field_name' => 'id', 248 | 'entity' => $userEntity, 249 | 'datatype' => 'bigint', 250 | 'allow_null' => true, 251 | ], 252 | ], 253 | ], 254 | 255 | 'Jwt' => [ 256 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Jwt', 257 | 'mapping' => [ 258 | 'subject' => [ 259 | 'type' => 'field', 260 | 'name' => 'subject', 261 | 'datatype' => 'string', 262 | ], 263 | 'public_key' => [ 264 | 'type' => 'field', 265 | 'name' => 'publicKey', 266 | 'datatype' => 'text', 267 | ], 268 | 'client_id' => [ 269 | 'type' => 'relation', 270 | 'name' => 'client', 271 | 'entity_field_name' => 'clientId', 272 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 273 | 'datatype' => 'bigint', 274 | ], 275 | ], 276 | ], 277 | 278 | 'Jti' => [ 279 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Jti', 280 | 'mapping' => [ 281 | 'subject' => [ 282 | 'type' => 'field', 283 | 'name' => 'subject', 284 | 'datatype' => 'string', 285 | ], 286 | 'audience' => [ 287 | 'type' => 'field', 288 | 'name' => 'audience', 289 | 'datatype' => 'string', 290 | ], 291 | 'expires' => [ 292 | 'type' => 'field', 293 | 'name' => 'expires', 294 | 'datatype' => 'datetime', 295 | ], 296 | 'jti' => [ 297 | 'type' => 'field', 298 | 'name' => 'jti', 299 | 'datatype' => 'text', 300 | ], 301 | 'client_id' => [ 302 | 'type' => 'relation', 303 | 'name' => 'client', 304 | 'entity_field_name' => 'clientId', 305 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 306 | 'datatype' => 'bigint', 307 | ], 308 | ], 309 | ], 310 | 311 | 'Scope' => [ 312 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Scope', 313 | 'mapping' => [ 314 | 'scope' => [ 315 | 'type' => 'field', 316 | 'name' => 'scope', 317 | 'datatype' => 'string', 318 | ], 319 | 'is_default' => [ 320 | 'type' => 'field', 321 | 'name' => 'isDefault', 322 | 'datatype' => 'boolean', 323 | ], 324 | 'client_id' => [ 325 | 'type' => 'relation', 326 | 'name' => 'client', 327 | 'entity_field_name' => 'clientId', 328 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 329 | 'datatype' => 'bigint', 330 | ], 331 | ], 332 | ], 333 | 334 | 'PublicKey' => [ 335 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\PublicKey', 336 | 'mapping' => [ 337 | 'public_key' => [ 338 | 'type' => 'field', 339 | 'name' => 'publicKey', 340 | 'datatype' => 'text', 341 | ], 342 | 'private_key' => [ 343 | 'type' => 'field', 344 | 'name' => 'privateKey', 345 | 'datatype' => 'text', 346 | ], 347 | 'encryption_algorithm' => [ 348 | 'type' => 'field', 349 | 'name' => 'encryptionAlgorithm', 350 | 'datatype' => 'string', 351 | ], 352 | 'client_id' => [ 353 | 'type' => 'relation', 354 | 'name' => 'client', 355 | 'entity_field_name' => 'clientId', 356 | 'entity' => 'ZF\OAuth2\Doctrine\Entity\Client', 357 | 'datatype' => 'bigint', 358 | ], 359 | ], 360 | ], 361 | ], 362 | ], 363 | ], 364 | ]; 365 | -------------------------------------------------------------------------------- /config/orm/ZF.OAuth2.Doctrine.Entity.AccessToken.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /config/orm/ZF.OAuth2.Doctrine.Entity.AuthorizationCode.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /config/orm/ZF.OAuth2.Doctrine.Entity.Client.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /config/orm/ZF.OAuth2.Doctrine.Entity.Jti.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /config/orm/ZF.OAuth2.Doctrine.Entity.Jwt.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /config/orm/ZF.OAuth2.Doctrine.Entity.PublicKey.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /config/orm/ZF.OAuth2.Doctrine.Entity.RefreshToken.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /config/orm/ZF.OAuth2.Doctrine.Entity.Scope.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /media/OAuth2-orm.module.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Client_OAuth2 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Scope_OAuth2 25 | 26 | 27 | 28 | 29 | 30 | 31 | ClientToScope_OAuth2 32 | 33 | 34 | 35 | 36 | 37 | 38 | AuthorizationCodeToScope_OAuth2 39 | 40 | 41 | 42 | 43 | 44 | 45 | RefreshTokenToScope_OAuth2 46 | 47 | 48 | 49 | 50 | 51 | 52 | AccessTokenToScope_OAuth2 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | CASCADE 61 | 62 | 63 | 64 | 65 | 66 | CASCADE 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | CASCADE 75 | 76 | 77 | 78 | 79 | 80 | CASCADE 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | CASCADE 89 | 90 | 91 | 92 | 93 | 94 | CASCADE 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | CASCADE 103 | 104 | 105 | 106 | 107 | 108 | CASCADE 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | AccessToken_OAuth2 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | RefreshToken_OAuth2 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | AuthorizationCode_OAuth2 140 | 141 | 142 | 143 | 144 | 145 | 146 | CASCADE 147 | 148 | 149 | 150 | 151 | 152 | CASCADE 153 | 154 | 155 | 156 | 157 | 158 | CASCADE 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | Jwt_OAuth2 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | Jti_OAuth2 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | PublicKey_OAuth2 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | CASCADE 198 | 199 | 200 | 201 | 202 | 203 | CASCADE 204 | 205 | 206 | 207 | 208 | 209 | CASCADE 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | -------------------------------------------------------------------------------- /media/OAuth2-orm.skipper: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /media/oauth2-doctrine-erd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/API-Skeletons/zf-oauth2-doctrine/bc1c8fcf4d984bf9278cdc1bf763add3b8768a26/media/oauth2-doctrine-erd.png -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | v1.0 Coding Standard for API Skeletons 4 | src 5 | test 6 | Bootstrap.php 7 | */data/* 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./test/ORM 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ./src 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Adapter/DoctrineAdapterFactory.php: -------------------------------------------------------------------------------- 1 | config = $config; 34 | 35 | return $this; 36 | } 37 | 38 | /** 39 | * @param ServiceLocatorInterface $services 40 | * @throws \ZF\OAuth2\Controller\Exception\RuntimeException 41 | * @return \ZF\OAuth2\Doctrine\Adapter\DoctrineAdapter 42 | */ 43 | public function createService(ServiceLocatorInterface $services) 44 | { 45 | return $this->create($services); 46 | } 47 | 48 | /** 49 | * @param ContainerInterface | ServiceLocatorInterface $services 50 | * @param string $objectManagerAlias 51 | * 52 | * @return ObjectManager 53 | * @throws \Zend\ServiceManager\Exception\ServiceNotCreatedException 54 | * @throws InvalidArgumentException 55 | */ 56 | protected function loadObjectManager($services, $objectManagerAlias) 57 | { 58 | if (! $services instanceof ContainerInterface && ! $services instanceof ServiceLocatorInterface) { 59 | throw new InvalidArgumentException('Invalid container'); 60 | } 61 | 62 | if ($services->has($objectManagerAlias)) { 63 | $objectManager = $services->get($objectManagerAlias); 64 | } else { 65 | // @codeCoverageIgnoreStart 66 | throw new ServiceNotCreatedException('The object_manager ' . $objectManagerAlias . ' could not be found.'); 67 | } 68 | // @codeCoverageIgnoreEnd 69 | 70 | return $objectManager; 71 | } 72 | 73 | /** 74 | * @param ContainerInterface | ServiceLocatorInterface $services 75 | * @param Config $config 76 | * 77 | * @return MapperManager 78 | * @throws \Zend\ServiceManager\Exception\ServiceNotCreatedException 79 | * @throws InvalidArgumentException 80 | */ 81 | protected function loadMapperManager($services, Config $config) 82 | { 83 | if (! $services instanceof ContainerInterface && ! $services instanceof ServiceLocatorInterface) { 84 | throw new InvalidArgumentException('Invalid container'); 85 | } 86 | 87 | if ($services->has('ZF\OAuth2\Doctrine\Mapper\MapperManager')) { 88 | $mapperManager = new MapperManager($services); 89 | } else { 90 | // @codeCoverageIgnoreStart 91 | throw new ServiceNotCreatedException( 92 | 'The MapperManager ZF\OAuth2\Doctrine\Mapper\MapperManager could not be found.' 93 | ); 94 | } 95 | // @codeCoverageIgnoreEnd 96 | 97 | $mapperManager->setConfig($config->mapping); 98 | $mapperManager->setObjectManager($this->loadObjectManager($services, $config->object_manager)); 99 | 100 | return $mapperManager; 101 | } 102 | 103 | /** 104 | * Create an object 105 | * 106 | * @param ContainerInterface $container 107 | * @param string $requestedName 108 | * @param null|array $options 109 | * @return DoctrineAdapter 110 | * @throws \Interop\Container\Exception\NotFoundException 111 | * @throws \Interop\Container\Exception\ContainerException 112 | * @throws InvalidArgumentException 113 | * @throws ServiceNotFoundException if unable to resolve the service. 114 | * @throws ServiceNotCreatedException if an exception is raised when 115 | * creating a service. 116 | * @throws ContainerException if any other error occurs 117 | */ 118 | public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 119 | { 120 | return $this->create($container); 121 | } 122 | 123 | /** 124 | * @param ContainerInterface | ServiceLocatorInterface $container 125 | * @return DoctrineAdapter 126 | * @throws \Interop\Container\Exception\NotFoundException 127 | * @throws \Interop\Container\Exception\ContainerException 128 | * @throws InvalidArgumentException 129 | */ 130 | protected function create($container) 131 | { 132 | if (! $container instanceof ContainerInterface && ! $container instanceof ServiceLocatorInterface) { 133 | throw new InvalidArgumentException('Invalid container'); 134 | } 135 | 136 | $adapter = $container->get('ZF\OAuth2\Doctrine\Adapter\DoctrineAdapter'); 137 | 138 | $adapter->setConfig($this->config); 139 | $adapter->setObjectManager($this->loadObjectManager($container, $this->config->object_manager)); 140 | $adapter->setMapperManager($this->loadMapperManager($container, $this->config)); 141 | 142 | return $adapter; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/ClientAssertionType/AuthorizationCode.php: -------------------------------------------------------------------------------- 1 | $offset = $value; 23 | } 24 | // CodeCoverageIgnoreEnd 25 | 26 | public function offsetExists($offset) 27 | { 28 | return isset($this->$offset); 29 | } 30 | 31 | public function offsetUnset($offset) 32 | { 33 | // @codeCoverageIgnoreStart 34 | throw new \Exception('not implemented'); 35 | } 36 | // @codeCoverageIgnoreEnd 37 | 38 | public function offsetGet($offset) 39 | { 40 | return isset($this->$offset) ? $this->$offset : null; 41 | } 42 | 43 | public $authorization_code; 44 | 45 | public $redirect_uri; 46 | 47 | public $expires; 48 | 49 | public $scope; 50 | 51 | public $id_token; 52 | 53 | public $client_id; 54 | 55 | public $user_id; 56 | 57 | public function getAuthorizationCode() 58 | { 59 | return $this->authorization_code; 60 | } 61 | 62 | public function setAuthorizationCode($value) 63 | { 64 | $this->authorization_code = $value; 65 | 66 | return $this; 67 | } 68 | 69 | public function getRedirectUri() 70 | { 71 | return $this->redirect_uri; 72 | } 73 | 74 | public function setRedirectUri($value) 75 | { 76 | $this->redirect_uri = $value; 77 | 78 | return $this; 79 | } 80 | 81 | public function getExpires() 82 | { 83 | return $this->expires; 84 | } 85 | 86 | public function setExpires($value) 87 | { 88 | $this->expires = $value; 89 | 90 | return $this; 91 | } 92 | 93 | public function getScope() 94 | { 95 | return $this->scope; 96 | } 97 | 98 | public function setScope($value) 99 | { 100 | $this->scope = $value; 101 | 102 | return $this; 103 | } 104 | 105 | public function getIdToken() 106 | { 107 | return $this->id_token; 108 | } 109 | 110 | public function setIdToken($value) 111 | { 112 | $this->id_token = $value; 113 | 114 | return $this; 115 | } 116 | 117 | public function getUserId() 118 | { 119 | return $this->user_id; 120 | } 121 | 122 | public function setUserId($value) 123 | { 124 | $this->user_id = $value; 125 | 126 | return $this; 127 | } 128 | 129 | public function getClientId() 130 | { 131 | return $this->client_id; 132 | } 133 | 134 | public function setClientId($value) 135 | { 136 | $this->client_id = $value; 137 | 138 | return $this; 139 | } 140 | 141 | public function getArrayCopy() 142 | { 143 | return [ 144 | 'authorization_code' => $this->getAuthorizationCode(), 145 | 'redirect_uri' => $this->getRedirectUri(), 146 | 'expires' => $this->getExpires(), 147 | 'scope' => $this->getScope(), 148 | 'id_token' => $this->getIdToken(), 149 | 'client_id' => $this->getClientId(), 150 | 'user_id' => $this->getUserId(), 151 | ]; 152 | } 153 | 154 | public function exchangeArray(array $array) 155 | { 156 | foreach ($array as $key => $value) { 157 | $key = strtolower($key); 158 | $key = str_replace('_', '', $key); 159 | switch ($key) { 160 | case 'authorizationcode': 161 | $this->setAuthorizationCode($value); 162 | break; 163 | case 'redirecturi': 164 | $this->setRedirectUri($value); 165 | break; 166 | case 'expires': 167 | $this->setExpires($value); 168 | break; 169 | case 'scope': 170 | $this->setScope($value); 171 | break; 172 | case 'idtoken': 173 | $this->setIdToken($value); 174 | break; 175 | case 'clientid': 176 | $this->setClientId($value); 177 | break; 178 | case 'userid': 179 | $this->setUserId($value); 180 | break; 181 | // @codeCoverageIgnoreStart 182 | default: 183 | break; 184 | } 185 | // @codeCoverageIgnoreEnd 186 | } 187 | 188 | return $this; 189 | } 190 | 191 | public function validateRequest(RequestInterface $request, ResponseInterface $response) 192 | { 193 | // @codeCoverageIgnoreStart 194 | throw new \Exception('Not implemented'); 195 | } 196 | // @codeCoverageIgnoreEnd 197 | } 198 | -------------------------------------------------------------------------------- /src/ConfigProvider.php: -------------------------------------------------------------------------------- 1 | $this->getDependencyConfig(), 18 | 'zf-apigility-doctrine-query-create-filter' => $this->getQueryCreateFilterConfig(), 19 | 'zf-apigility-doctrine-query-provider' => $this->getQueryProviderConfig(), 20 | ]; 21 | } 22 | 23 | /** 24 | * Return application-level dependency configuration. 25 | * 26 | * @return array 27 | */ 28 | public function getDependencyConfig() 29 | { 30 | return [ 31 | 'factories' => [ 32 | Adapter\DoctrineAdapterFactory::class => InvokableFactory::class, 33 | Mapper\MapperManager::class => InvokableFactory::class, 34 | Adapter\DoctrineAdapter::class => InvokableFactory::class, 35 | ], 36 | 'shared' => [ 37 | Adapter\DoctrineAdapterFactory::class => false, 38 | Mapper\MapperManager::class => false, 39 | ], 40 | ]; 41 | } 42 | 43 | /** 44 | * Return QueryCreateFilter configuration. 45 | * 46 | * @return array 47 | */ 48 | public function getQueryCreateFilterConfig() 49 | { 50 | return [ 51 | 'initializers' => [ 52 | Query\OAuth2ServerInitializer::class, 53 | ], 54 | ]; 55 | } 56 | 57 | /** 58 | * Return QueryProvider configuration. 59 | * 60 | * @return array 61 | */ 62 | public function getQueryProviderConfig() 63 | { 64 | return [ 65 | 'initializers' => [ 66 | Query\OAuth2ServerInitializer::class, 67 | ], 68 | ]; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Entity/AccessToken.php: -------------------------------------------------------------------------------- 1 | scope = new ArrayCollection(); 50 | } 51 | 52 | public function getArrayCopy() 53 | { 54 | return [ 55 | 'id' => $this->getId(), 56 | 'accessToken' => $this->getAccessToken(), 57 | 'expires' => $this->getExpires(), 58 | 'client' => $this->getClient(), 59 | 'scope' => $this->getScope(), 60 | 'user' => $this->getUser(), 61 | ]; 62 | } 63 | 64 | public function exchangeArray(array $array) 65 | { 66 | foreach ($array as $key => $value) { 67 | switch ($key) { 68 | case 'accessToken': 69 | $this->setAccessToken($value); 70 | break; 71 | case 'expires': 72 | $this->setExpires($value); 73 | break; 74 | case 'client': 75 | $this->setClient($value); 76 | break; 77 | case 'scope': 78 | // Clear old collection 79 | foreach ($value as $remove) { 80 | $this->removeScope($remove); 81 | $remove->removeAccessToken($this); 82 | } 83 | 84 | // Add new collection 85 | foreach ($value as $scope) { 86 | $this->addScope($scope); 87 | $scope->addAccessToken($this); 88 | } 89 | break; 90 | case 'user': 91 | $this->setUser($value); 92 | break; 93 | default: 94 | break; 95 | } 96 | } 97 | 98 | return $this; 99 | } 100 | 101 | /** 102 | * Set accessToken 103 | * 104 | * @param string $accessToken 105 | * @return AccessToken 106 | */ 107 | public function setAccessToken($accessToken) 108 | { 109 | $this->accessToken = $accessToken; 110 | 111 | return $this; 112 | } 113 | 114 | /** 115 | * Get accessToken 116 | * 117 | * @return string 118 | */ 119 | public function getAccessToken() 120 | { 121 | return $this->accessToken; 122 | } 123 | 124 | /** 125 | * Set expires 126 | * 127 | * @param \DateTime $expires 128 | * @return AccessToken 129 | */ 130 | public function setExpires($expires) 131 | { 132 | $this->expires = $expires; 133 | 134 | return $this; 135 | } 136 | 137 | /** 138 | * Get expires 139 | * 140 | * @return \DateTime 141 | */ 142 | public function getExpires() 143 | { 144 | return $this->expires; 145 | } 146 | 147 | /** 148 | * Get id 149 | * 150 | * @return bigint 151 | */ 152 | public function getId() 153 | { 154 | return $this->id; 155 | } 156 | 157 | /** 158 | * Set client 159 | * 160 | * @param Client $client 161 | * @return AccessToken 162 | */ 163 | public function setClient(Client $client) 164 | { 165 | $this->client = $client; 166 | 167 | return $this; 168 | } 169 | 170 | /** 171 | * Get client 172 | * 173 | * @return Client 174 | */ 175 | public function getClient() 176 | { 177 | return $this->client; 178 | } 179 | 180 | /** 181 | * Add scope 182 | * 183 | * @param Scope $scope 184 | * @return AccessToken 185 | */ 186 | public function addScope(Scope $scope) 187 | { 188 | $this->scope[] = $scope; 189 | 190 | return $this; 191 | } 192 | 193 | /** 194 | * Remove scope 195 | * 196 | * @param Scope $scope 197 | */ 198 | public function removeScope(Scope $scope) 199 | { 200 | $this->scope->removeElement($scope); 201 | } 202 | 203 | /** 204 | * Get scope 205 | * 206 | * @return \Doctrine\Common\Collections\Collection 207 | */ 208 | public function getScope() 209 | { 210 | return $this->scope; 211 | } 212 | 213 | /** 214 | * Set user 215 | * 216 | * @param $user 217 | * @return AuthorizationCode 218 | */ 219 | public function setUser(UserInterface $user = null) 220 | { 221 | $this->user = $user; 222 | 223 | return $this; 224 | } 225 | 226 | /** 227 | * Get user 228 | * 229 | * @return user 230 | */ 231 | public function getUser() 232 | { 233 | return $this->user; 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/Entity/AuthorizationCode.php: -------------------------------------------------------------------------------- 1 | scope = new ArrayCollection(); 59 | } 60 | 61 | public function getArrayCopy() 62 | { 63 | return [ 64 | 'id' => $this->getId(), 65 | 'authorizationCode' => $this->getAuthorizationCode(), 66 | 'redirectUri' => $this->getRedirectUri(), 67 | 'expires' => $this->getExpires(), 68 | 'idToken' => $this->getIdToken(), 69 | 'scope' => $this->getScope(), 70 | 'client' => $this->getClient(), 71 | 'user' => $this->getUser(), 72 | ]; 73 | } 74 | 75 | public function exchangeArray(array $array) 76 | { 77 | foreach ($array as $key => $value) { 78 | switch ($key) { 79 | case 'authorizationCode': 80 | $this->setAuthorizationCode($value); 81 | break; 82 | case 'redirectUri': 83 | $this->setRedirectUri($value); 84 | break; 85 | case 'expires': 86 | $this->setExpires($value); 87 | break; 88 | case 'idToken': 89 | $this->setIdToken($value); 90 | break; 91 | case 'client': 92 | $this->setClient($value); 93 | break; 94 | case 'scope': 95 | // Clear old collection 96 | foreach ($value as $remove) { 97 | $this->removeScope($remove); 98 | $remove->removeAuthorizationCode($this); 99 | } 100 | // Add new collection 101 | foreach ($value as $scope) { 102 | $this->addScope($scope); 103 | $scope->addAuthorizationCode($this); 104 | } 105 | break; 106 | case 'user': 107 | $this->setUser($value); 108 | break; 109 | default: 110 | break; 111 | } 112 | } 113 | return $this; 114 | } 115 | 116 | /** 117 | * Set authorizationCode 118 | * 119 | * @param string $authorizationCode 120 | * @return AuthorizationCode 121 | */ 122 | public function setAuthorizationCode($authorizationCode) 123 | { 124 | $this->authorizationCode = $authorizationCode; 125 | 126 | return $this; 127 | } 128 | 129 | /** 130 | * Get authorizationCode 131 | * 132 | * @return string 133 | */ 134 | public function getAuthorizationCode() 135 | { 136 | return $this->authorizationCode; 137 | } 138 | 139 | /** 140 | * Set redirectUri 141 | * 142 | * @param string $redirectUri 143 | * @return AuthorizationCode 144 | */ 145 | public function setRedirectUri($redirectUri) 146 | { 147 | $this->redirectUri = $redirectUri; 148 | 149 | return $this; 150 | } 151 | 152 | /** 153 | * Get redirectUri 154 | * 155 | * @return string 156 | */ 157 | public function getRedirectUri() 158 | { 159 | return $this->redirectUri; 160 | } 161 | 162 | /** 163 | * Set expires 164 | * 165 | * @param \DateTime $expires 166 | * @return AuthorizationCode 167 | */ 168 | public function setExpires($expires) 169 | { 170 | $this->expires = $expires; 171 | 172 | return $this; 173 | } 174 | 175 | /** 176 | * Get expires 177 | * 178 | * @return \DateTime 179 | */ 180 | public function getExpires() 181 | { 182 | return $this->expires; 183 | } 184 | 185 | /** 186 | * Set idToken 187 | * 188 | * @param string $idToken 189 | * @return AuthorizationCode 190 | */ 191 | public function setIdToken($idToken) 192 | { 193 | $this->idToken = $idToken; 194 | 195 | return $this; 196 | } 197 | 198 | /** 199 | * Get idToken 200 | * 201 | * @return string 202 | */ 203 | public function getIdToken() 204 | { 205 | return $this->idToken; 206 | } 207 | 208 | /** 209 | * Get id 210 | * 211 | * @return bigint 212 | */ 213 | public function getId() 214 | { 215 | return $this->id; 216 | } 217 | 218 | /** 219 | * Set client 220 | * 221 | * @param Client $client 222 | * @return AuthorizationCode 223 | */ 224 | public function setClient(Client $client) 225 | { 226 | $this->client = $client; 227 | 228 | return $this; 229 | } 230 | 231 | /** 232 | * Get client 233 | * 234 | * @return Client 235 | */ 236 | public function getClient() 237 | { 238 | return $this->client; 239 | } 240 | 241 | /** 242 | * Add scope 243 | * 244 | * @param Scope $scope 245 | * @return AuthorizationCode 246 | */ 247 | public function addScope(Scope $scope) 248 | { 249 | $this->scope[] = $scope; 250 | 251 | return $this; 252 | } 253 | 254 | /** 255 | * Remove scope 256 | * 257 | * @param Scope $scope 258 | */ 259 | public function removeScope(Scope $scope) 260 | { 261 | $this->scope->removeElement($scope); 262 | } 263 | 264 | /** 265 | * Get scope 266 | * 267 | * @return \Doctrine\Common\Collections\Collection 268 | */ 269 | public function getScope() 270 | { 271 | return $this->scope; 272 | } 273 | 274 | /** 275 | * Set user 276 | * 277 | * @param $user 278 | * @return AuthorizationCode 279 | */ 280 | public function setUser(UserInterface $user = null) 281 | { 282 | $this->user = $user; 283 | 284 | return $this; 285 | } 286 | 287 | /** 288 | * Get user 289 | * 290 | * @return user 291 | */ 292 | public function getUser() 293 | { 294 | return $this->user; 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /src/Entity/Client.php: -------------------------------------------------------------------------------- 1 | accessToken = new ArrayCollection(); 90 | $this->refreshToken = new ArrayCollection(); 91 | $this->authorizationCode = new ArrayCollection(); 92 | $this->jwt = new ArrayCollection(); 93 | $this->jti = new ArrayCollection(); 94 | $this->scope = new ArrayCollection(); 95 | } 96 | 97 | public function getArrayCopy() 98 | { 99 | return [ 100 | 'id' => $this->getId(), 101 | 'clientId' => $this->getClientId(), 102 | 'secret' => $this->getSecret(), 103 | 'redirectUri' => $this->getRedirectUri(), 104 | 'grantType' => $this->getGrantType(), 105 | 'scope' => $this->getScope(), 106 | 'user' => $this->getUser(), 107 | ]; 108 | } 109 | 110 | public function exchangeArray(array $array) 111 | { 112 | foreach ($array as $key => $value) { 113 | switch ($key) { 114 | case 'clientId': 115 | $this->setClientId($value); 116 | break; 117 | case 'secret': 118 | $this->setSecret($value); 119 | break; 120 | case 'redirectUri': 121 | $this->setRedirectUri($value); 122 | break; 123 | case 'grantType': 124 | $this->setGrantType($value); 125 | break; 126 | case 'user': 127 | $this->setUser($value); 128 | break; 129 | case 'scope': 130 | // Clear old collection 131 | foreach ($value as $remove) { 132 | $this->removeScope($remove); 133 | $remove->removeClient($this); 134 | } 135 | 136 | // Add new collection 137 | foreach ($value as $scope) { 138 | $this->addScope($scope); 139 | $scope->removeClient($this); 140 | } 141 | break; 142 | default: 143 | break; 144 | } 145 | } 146 | 147 | return $this; 148 | } 149 | 150 | /** 151 | * Set clientId 152 | * 153 | * @param string $clientId 154 | * @return Client 155 | */ 156 | public function setClientId($clientId) 157 | { 158 | $this->clientId = $clientId; 159 | 160 | return $this; 161 | } 162 | 163 | /** 164 | * Get clientId 165 | * 166 | * @return string 167 | */ 168 | public function getClientId() 169 | { 170 | return $this->clientId; 171 | } 172 | 173 | /** 174 | * Set secret 175 | * 176 | * @param string $secret 177 | * @return Client 178 | */ 179 | public function setSecret($secret) 180 | { 181 | $this->secret = $secret; 182 | 183 | return $this; 184 | } 185 | 186 | /** 187 | * Get secret 188 | * 189 | * @return string 190 | */ 191 | public function getSecret() 192 | { 193 | return $this->secret; 194 | } 195 | 196 | /** 197 | * Set redirectUri 198 | * 199 | * @param string $redirectUri 200 | * @return Client 201 | */ 202 | public function setRedirectUri($redirectUri) 203 | { 204 | $this->redirectUri = $redirectUri; 205 | 206 | return $this; 207 | } 208 | 209 | /** 210 | * Get redirectUri 211 | * 212 | * @return string 213 | */ 214 | public function getRedirectUri() 215 | { 216 | return $this->redirectUri; 217 | } 218 | 219 | /** 220 | * Set grantType 221 | * 222 | * @param array $grantType 223 | * @return Client 224 | */ 225 | public function setGrantType($grantType) 226 | { 227 | $this->grantType = $grantType; 228 | 229 | return $this; 230 | } 231 | 232 | /** 233 | * Get grantType 234 | * 235 | * @return array 236 | */ 237 | public function getGrantType() 238 | { 239 | return $this->grantType; 240 | } 241 | 242 | /** 243 | * Set clientScope 244 | * 245 | * @param string $clientScope 246 | * @return Client 247 | */ 248 | public function setClientScope($clientScope) 249 | { 250 | $this->clientScope = $clientScope; 251 | 252 | return $this; 253 | } 254 | 255 | /** 256 | * Get clientScope 257 | * 258 | * @return string 259 | */ 260 | public function getClientScope() 261 | { 262 | return $this->clientScope; 263 | } 264 | 265 | /** 266 | * Get id 267 | * 268 | * @return bigint 269 | */ 270 | public function getId() 271 | { 272 | return $this->id; 273 | } 274 | 275 | /** 276 | * Add accessToken 277 | * 278 | * @param AccessToken $accessToken 279 | * @return Client 280 | */ 281 | public function addAccessToken(AccessToken $accessToken) 282 | { 283 | $this->accessToken[] = $accessToken; 284 | 285 | return $this; 286 | } 287 | 288 | /** 289 | * Remove accessToken 290 | * 291 | * @param AccessToken $accessToken 292 | */ 293 | public function removeAccessToken(AccessToken $accessToken) 294 | { 295 | $this->accessToken->removeElement($accessToken); 296 | } 297 | 298 | /** 299 | * Get accessToken 300 | * 301 | * @return \Doctrine\Common\Collections\Collection 302 | */ 303 | public function getAccessToken() 304 | { 305 | return $this->accessToken; 306 | } 307 | 308 | /** 309 | * Add refreshToken 310 | * 311 | * @param RefreshToken $refreshToken 312 | * @return Client 313 | */ 314 | public function addRefreshToken(RefreshToken $refreshToken) 315 | { 316 | $this->refreshToken[] = $refreshToken; 317 | 318 | return $this; 319 | } 320 | 321 | /** 322 | * Remove refreshToken 323 | * 324 | * @param RefreshToken $refreshToken 325 | */ 326 | public function removeRefreshToken(RefreshToken $refreshToken) 327 | { 328 | $this->refreshToken->removeElement($refreshToken); 329 | } 330 | 331 | /** 332 | * Get refreshToken 333 | * 334 | * @return \Doctrine\Common\Collections\Collection 335 | */ 336 | public function getRefreshToken() 337 | { 338 | return $this->refreshToken; 339 | } 340 | 341 | /** 342 | * Add authorizationCode 343 | * 344 | * @param AuthorizationCode $authorizationCode 345 | * @return Client 346 | */ 347 | public function addAuthorizationCode(AuthorizationCode $authorizationCode) 348 | { 349 | $this->authorizationCode[] = $authorizationCode; 350 | 351 | return $this; 352 | } 353 | 354 | /** 355 | * Remove authorizationCode 356 | * 357 | * @param AuthorizationCode $authorizationCode 358 | */ 359 | public function removeAuthorizationCode(AuthorizationCode $authorizationCode) 360 | { 361 | $this->authorizationCode->removeElement($authorizationCode); 362 | } 363 | 364 | /** 365 | * Get authorizationCode 366 | * 367 | * @return \Doctrine\Common\Collections\Collection 368 | */ 369 | public function getAuthorizationCode() 370 | { 371 | return $this->authorizationCode; 372 | } 373 | 374 | /** 375 | * Add jwt 376 | * 377 | * @param Jwt $jwt 378 | * @return Client 379 | */ 380 | public function addJwt(Jwt $jwt) 381 | { 382 | $this->jwt[] = $jwt; 383 | 384 | return $this; 385 | } 386 | 387 | /** 388 | * Remove jwt 389 | * 390 | * @param Jwt $jwt 391 | */ 392 | public function removeJwt(Jwt $jwt) 393 | { 394 | $this->jwt->removeElement($jwt); 395 | } 396 | 397 | /** 398 | * Get jwt 399 | * 400 | * @return \Doctrine\Common\Collections\Collection 401 | */ 402 | public function getJwt() 403 | { 404 | return $this->jwt; 405 | } 406 | 407 | /** 408 | * Add jti 409 | * 410 | * @param Jti $jti 411 | * @return Client 412 | */ 413 | public function addJti(Jti $jti) 414 | { 415 | $this->jti[] = $jti; 416 | 417 | return $this; 418 | } 419 | 420 | /** 421 | * Remove jti 422 | * 423 | * @param Jti $jti 424 | */ 425 | public function removeJti(Jti $jti) 426 | { 427 | $this->jti->removeElement($jti); 428 | } 429 | 430 | /** 431 | * Get jti 432 | * 433 | * @return \Doctrine\Common\Collections\Collection 434 | */ 435 | public function getJti() 436 | { 437 | return $this->jti; 438 | } 439 | 440 | /** 441 | * Get publicKey 442 | * 443 | * @return PublicKey 444 | */ 445 | public function getPublicKey() 446 | { 447 | return $this->publicKey; 448 | } 449 | 450 | /** 451 | * Set publicKey 452 | */ 453 | public function setPublicKey(PublicKey $value) 454 | { 455 | $this->publicKey = $value; 456 | 457 | return $this; 458 | } 459 | 460 | /** 461 | * Add scope 462 | * 463 | * @param Scope $scope 464 | * @return Client 465 | */ 466 | public function addScope(Scope $scope) 467 | { 468 | $this->scope[] = $scope; 469 | 470 | return $this; 471 | } 472 | 473 | /** 474 | * Remove scope 475 | * 476 | * @param Scope $scope 477 | */ 478 | public function removeScope(Scope $scope) 479 | { 480 | $this->scope->removeElement($scope); 481 | } 482 | 483 | /** 484 | * Get scope 485 | * 486 | * @return \Doctrine\Common\Collections\Collection 487 | */ 488 | public function getScope() 489 | { 490 | return $this->scope; 491 | } 492 | 493 | /** 494 | * Set user 495 | * 496 | * @param $user 497 | * @return Client 498 | */ 499 | public function setUser(UserInterface $user = null) 500 | { 501 | $this->user = $user; 502 | 503 | return $this; 504 | } 505 | 506 | /** 507 | * Get user 508 | * 509 | * @return User 510 | */ 511 | public function getUser() 512 | { 513 | return $this->user; 514 | } 515 | } 516 | -------------------------------------------------------------------------------- /src/Entity/Jti.php: -------------------------------------------------------------------------------- 1 | $value) { 43 | switch ($key) { 44 | case 'client': 45 | $this->setClient($value); 46 | break; 47 | case 'subject': 48 | $this->setSubject($value); 49 | break; 50 | case 'audience': 51 | $this->setAudience($value); 52 | break; 53 | case 'expires': 54 | $this->setExpires($value); 55 | break; 56 | case 'jti': 57 | $this->setJti($value); 58 | break; 59 | default: 60 | // @codeCoverageIgnoreStart 61 | break; 62 | } 63 | // @codeCoverageIgnoreEnd 64 | } 65 | 66 | return $this; 67 | } 68 | 69 | public function getArrayCopy() 70 | { 71 | return [ 72 | 'id' => $this->getId(), 73 | 'client' => $this->getClient(), 74 | 'subject' => $this->getSubject(), 75 | 'audience' => $this->getAudience(), 76 | 'expires' => $this->getExpires(), 77 | 'jti' => $this->getJti(), 78 | ]; 79 | } 80 | 81 | /** 82 | * Set subject 83 | * 84 | * @param string $subject 85 | * @return Jti 86 | */ 87 | public function setSubject($subject) 88 | { 89 | $this->subject = $subject; 90 | 91 | return $this; 92 | } 93 | 94 | /** 95 | * Get subject 96 | * 97 | * @return string 98 | */ 99 | public function getSubject() 100 | { 101 | return $this->subject; 102 | } 103 | 104 | /** 105 | * Set audience 106 | * 107 | * @param string $audience 108 | * @return Jti 109 | */ 110 | public function setAudience($audience) 111 | { 112 | $this->audience = $audience; 113 | 114 | return $this; 115 | } 116 | 117 | /** 118 | * Get audience 119 | * 120 | * @return string 121 | */ 122 | public function getAudience() 123 | { 124 | return $this->audience; 125 | } 126 | 127 | /** 128 | * Set expires 129 | * 130 | * @param \DateTime $expires 131 | * @return Jti 132 | */ 133 | public function setExpires($expires) 134 | { 135 | $this->expires = $expires; 136 | 137 | return $this; 138 | } 139 | 140 | /** 141 | * Get expires 142 | * 143 | * @return \DateTime 144 | */ 145 | public function getExpires() 146 | { 147 | return $this->expires; 148 | } 149 | 150 | /** 151 | * Set jti 152 | * 153 | * @param string $jti 154 | * @return Jti 155 | */ 156 | public function setJti($jti) 157 | { 158 | $this->jti = $jti; 159 | 160 | return $this; 161 | } 162 | 163 | /** 164 | * Get jti 165 | * 166 | * @return string 167 | */ 168 | public function getJti() 169 | { 170 | return $this->jti; 171 | } 172 | 173 | /** 174 | * Get id 175 | * 176 | * @return bigint 177 | */ 178 | public function getId() 179 | { 180 | return $this->id; 181 | } 182 | 183 | /** 184 | * Set client 185 | * 186 | * @param Client $client 187 | * @return Jti 188 | */ 189 | public function setClient(Client $client) 190 | { 191 | $this->client = $client; 192 | 193 | return $this; 194 | } 195 | 196 | /** 197 | * Get client 198 | * 199 | * @return Client 200 | */ 201 | public function getClient() 202 | { 203 | return $this->client; 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/Entity/Jwt.php: -------------------------------------------------------------------------------- 1 | $this->getId(), 34 | 'client' => $this->getClient(), 35 | 'subject' => $this->getSubject(), 36 | 'publicKey' => $this->getPublicKey(), 37 | ]; 38 | } 39 | 40 | /** 41 | * Set subject 42 | * 43 | * @param string $subject 44 | * @return Jwt 45 | */ 46 | public function setSubject($subject) 47 | { 48 | $this->subject = $subject; 49 | 50 | return $this; 51 | } 52 | 53 | /** 54 | * Get subject 55 | * 56 | * @return string 57 | */ 58 | public function getSubject() 59 | { 60 | return $this->subject; 61 | } 62 | 63 | /** 64 | * Set publicKey 65 | * 66 | * @param string $publicKey 67 | * @return Jwt 68 | */ 69 | public function setPublicKey($publicKey) 70 | { 71 | $this->publicKey = $publicKey; 72 | 73 | return $this; 74 | } 75 | 76 | /** 77 | * Get publicKey 78 | * 79 | * @return string 80 | */ 81 | public function getPublicKey() 82 | { 83 | return $this->publicKey; 84 | } 85 | 86 | /** 87 | * Get id 88 | * 89 | * @return bigint 90 | */ 91 | public function getId() 92 | { 93 | return $this->id; 94 | } 95 | 96 | /** 97 | * Set client 98 | * 99 | * @param Client $client 100 | * @return Jwt 101 | */ 102 | public function setClient(Client $client) 103 | { 104 | $this->client = $client; 105 | 106 | return $this; 107 | } 108 | 109 | /** 110 | * Get client 111 | * 112 | * @return Client 113 | */ 114 | public function getClient() 115 | { 116 | return $this->client; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Entity/PublicKey.php: -------------------------------------------------------------------------------- 1 | $this->getId(), 39 | 'publicKey' => $this->getPublicKey(), 40 | 'privateKey' => $this->getPrivateKey(), 41 | 'encryptionAlgorithm' => $this->getEncryptionAlgorithm(), 42 | 'client' => $this->getClient(), 43 | ]; 44 | } 45 | 46 | /** 47 | * Set publicKey 48 | * 49 | * @param string $publicKey 50 | * @return PublicKey 51 | */ 52 | public function setPublicKey($publicKey) 53 | { 54 | $this->publicKey = $publicKey; 55 | 56 | return $this; 57 | } 58 | 59 | /** 60 | * Get publicKey 61 | * 62 | * @return string 63 | */ 64 | public function getPublicKey() 65 | { 66 | return $this->publicKey; 67 | } 68 | 69 | /** 70 | * Set privateKey 71 | * 72 | * @param string $privateKey 73 | * @return PublicKey 74 | */ 75 | public function setPrivateKey($privateKey) 76 | { 77 | $this->privateKey = $privateKey; 78 | 79 | return $this; 80 | } 81 | 82 | /** 83 | * Get privateKey 84 | * 85 | * @return string 86 | */ 87 | public function getPrivateKey() 88 | { 89 | return $this->privateKey; 90 | } 91 | 92 | /** 93 | * Set encryptionAlgorithm 94 | * 95 | * @param string $encryptionAlgorithm 96 | * @return PublicKey 97 | */ 98 | public function setEncryptionAlgorithm($encryptionAlgorithm) 99 | { 100 | $this->encryptionAlgorithm = $encryptionAlgorithm; 101 | 102 | return $this; 103 | } 104 | 105 | /** 106 | * Get encryptionAlgorithm 107 | * 108 | * @return string 109 | */ 110 | public function getEncryptionAlgorithm() 111 | { 112 | return $this->encryptionAlgorithm; 113 | } 114 | 115 | /** 116 | * Get id 117 | * 118 | * @return bigint 119 | */ 120 | public function getId() 121 | { 122 | return $this->id; 123 | } 124 | 125 | /** 126 | * Set client 127 | * 128 | * @param Client $client 129 | * @return PublicKey 130 | */ 131 | public function setClient(Client $client) 132 | { 133 | $this->client = $client; 134 | 135 | return $this; 136 | } 137 | 138 | /** 139 | * Get client 140 | * 141 | * @return Client 142 | */ 143 | public function getClient() 144 | { 145 | return $this->client; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/Entity/RefreshToken.php: -------------------------------------------------------------------------------- 1 | scope = new ArrayCollection(); 49 | } 50 | 51 | public function exchangeArray(array $array) 52 | { 53 | foreach ($array as $key => $value) { 54 | switch ($key) { 55 | case 'refreshToken': 56 | $this->setRefreshToken($value); 57 | break; 58 | case 'expires': 59 | $this->setExpires($value); 60 | break; 61 | case 'client': 62 | $this->setClient($value); 63 | break; 64 | case 'scope': 65 | // Clear old collection 66 | foreach ($value as $remove) { 67 | $this->removeScope($remove); 68 | $remove->removeRefreshToken($this); 69 | } 70 | 71 | // Add new collection 72 | foreach ($value as $scope) { 73 | $this->addScope($scope); 74 | $scope->removeRefreshToken($this); 75 | } 76 | break; 77 | case 'user': 78 | $this->setUser($value); 79 | break; 80 | default: 81 | // @codeCoverageIgnoreStart 82 | break; 83 | } 84 | // @codeCoverageIgnoreEnd 85 | } 86 | 87 | return $this; 88 | } 89 | 90 | public function getArrayCopy() 91 | { 92 | return [ 93 | 'id' => $this->getId(), 94 | 'refreshToken' => $this->getRefreshToken(), 95 | 'expires' => $this->getExpires(), 96 | 'client' => $this->getClient(), 97 | 'scope' => $this->getScope(), 98 | 'user' => $this->getUser(), 99 | ]; 100 | } 101 | 102 | /** 103 | * Set refreshToken 104 | * 105 | * @param string $refreshToken 106 | * @return RefreshToken 107 | */ 108 | public function setRefreshToken($refreshToken) 109 | { 110 | $this->refreshToken = $refreshToken; 111 | 112 | return $this; 113 | } 114 | 115 | /** 116 | * Get refreshToken 117 | * 118 | * @return string 119 | */ 120 | public function getRefreshToken() 121 | { 122 | return $this->refreshToken; 123 | } 124 | 125 | /** 126 | * Set expires 127 | * 128 | * @param \DateTime $expires 129 | * @return RefreshToken 130 | */ 131 | public function setExpires($expires) 132 | { 133 | $this->expires = $expires; 134 | 135 | return $this; 136 | } 137 | 138 | /** 139 | * Get expires 140 | * 141 | * @return \DateTime 142 | */ 143 | public function getExpires() 144 | { 145 | return $this->expires; 146 | } 147 | 148 | /** 149 | * Get id 150 | * 151 | * @return bigint 152 | */ 153 | public function getId() 154 | { 155 | return $this->id; 156 | } 157 | 158 | /** 159 | * Set client 160 | * 161 | * @param Client $client 162 | * @return RefreshToken 163 | */ 164 | public function setClient(Client $client) 165 | { 166 | $this->client = $client; 167 | 168 | return $this; 169 | } 170 | 171 | /** 172 | * Get client 173 | * 174 | * @return Client 175 | */ 176 | public function getClient() 177 | { 178 | return $this->client; 179 | } 180 | 181 | /** 182 | * Add scope 183 | * 184 | * @param Scope $scope 185 | * @return RefreshToken 186 | */ 187 | public function addScope(Scope $scope) 188 | { 189 | $this->scope[] = $scope; 190 | 191 | return $this; 192 | } 193 | 194 | /** 195 | * Remove scope 196 | * 197 | * @param Scope $scope 198 | */ 199 | public function removeScope(Scope $scope) 200 | { 201 | $this->scope->removeElement($scope); 202 | } 203 | 204 | /** 205 | * Get scope 206 | * 207 | * @return \Doctrine\Common\Collections\Collection 208 | */ 209 | public function getScope() 210 | { 211 | return $this->scope; 212 | } 213 | 214 | 215 | /** 216 | * Set user 217 | * 218 | * @param $user 219 | * @return AuthorizationCode 220 | */ 221 | public function setUser(UserInterface $user = null) 222 | { 223 | $this->user = $user; 224 | 225 | return $this; 226 | } 227 | 228 | /** 229 | * Get user 230 | * 231 | * @return user 232 | */ 233 | public function getUser() 234 | { 235 | return $this->user; 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /src/Entity/Scope.php: -------------------------------------------------------------------------------- 1 | client = new ArrayCollection(); 53 | $this->authorizationCode = new ArrayCollection(); 54 | $this->refreshToken = new ArrayCollection(); 55 | $this->accessToken = new ArrayCollection(); 56 | } 57 | 58 | public function getArrayCopy() 59 | { 60 | return [ 61 | 'id' => $this->getId(), 62 | 'scope' => $this->getScope(), 63 | 'isDefault' => $this->getIsDefault(), 64 | ]; 65 | } 66 | 67 | /** 68 | * Set scope 69 | * 70 | * @param string $scope 71 | * @return Scope 72 | */ 73 | public function setScope($scope) 74 | { 75 | $this->scope = $scope; 76 | 77 | return $this; 78 | } 79 | 80 | /** 81 | * Get scope 82 | * 83 | * @return string 84 | */ 85 | public function getScope() 86 | { 87 | return $this->scope; 88 | } 89 | 90 | /** 91 | * Set isDefault 92 | * 93 | * @param boolean $isDefault 94 | * @return Scope 95 | */ 96 | public function setIsDefault($isDefault) 97 | { 98 | $this->isDefault = $isDefault; 99 | 100 | return $this; 101 | } 102 | 103 | /** 104 | * Get isDefault 105 | * 106 | * @return boolean 107 | */ 108 | public function getIsDefault() 109 | { 110 | return $this->isDefault; 111 | } 112 | 113 | /** 114 | * Get id 115 | * 116 | * @return bigint 117 | */ 118 | public function getId() 119 | { 120 | return $this->id; 121 | } 122 | 123 | public function setId($id) 124 | { 125 | $this->id = $id; 126 | 127 | return $this; 128 | } 129 | 130 | /** 131 | * Add client 132 | * 133 | * @param Client $client 134 | * @return Scope 135 | */ 136 | public function addClient(Client $client) 137 | { 138 | $this->client[] = $client; 139 | 140 | return $this; 141 | } 142 | 143 | /** 144 | * Remove client 145 | * 146 | * @param Client $client 147 | */ 148 | public function removeClient(Client $client) 149 | { 150 | $this->client->removeElement($client); 151 | } 152 | 153 | /** 154 | * Get client 155 | * 156 | * @return \Doctrine\Common\Collections\Collection 157 | */ 158 | public function getClient() 159 | { 160 | return $this->client; 161 | } 162 | 163 | /** 164 | * Add authorizationCode 165 | * 166 | * @param AuthorizationCode $authorizationCode 167 | * @return Scope 168 | */ 169 | public function addAuthorizationCode(AuthorizationCode $authorizationCode) 170 | { 171 | $this->authorizationCode[] = $authorizationCode; 172 | 173 | return $this; 174 | } 175 | 176 | /** 177 | * Remove authorizationCode 178 | * 179 | * @param AuthorizationCode $authorizationCode 180 | */ 181 | public function removeAuthorizationCode(AuthorizationCode $authorizationCode) 182 | { 183 | $this->authorizationCode->removeElement($authorizationCode); 184 | } 185 | 186 | /** 187 | * Get authorizationCode 188 | * 189 | * @return \Doctrine\Common\Collections\Collection 190 | */ 191 | public function getAuthorizationCode() 192 | { 193 | return $this->authorizationCode; 194 | } 195 | 196 | /** 197 | * Add refreshToken 198 | * 199 | * @param RefreshToken $refreshToken 200 | * @return Scope 201 | */ 202 | public function addRefreshToken(RefreshToken $refreshToken) 203 | { 204 | $this->refreshToken[] = $refreshToken; 205 | 206 | return $this; 207 | } 208 | 209 | /** 210 | * Remove refreshToken 211 | * 212 | * @param RefreshToken $refreshToken 213 | */ 214 | public function removeRefreshToken(RefreshToken $refreshToken) 215 | { 216 | $this->refreshToken->removeElement($refreshToken); 217 | } 218 | 219 | /** 220 | * Get refreshToken 221 | * 222 | * @return \Doctrine\Common\Collections\Collection 223 | */ 224 | public function getRefreshToken() 225 | { 226 | return $this->refreshToken; 227 | } 228 | 229 | /** 230 | * Add accessToken 231 | * 232 | * @param AccessToken $accessToken 233 | * @return Scope 234 | */ 235 | public function addAccessToken(AccessToken $accessToken) 236 | { 237 | $this->accessToken[] = $accessToken; 238 | 239 | return $this; 240 | } 241 | 242 | /** 243 | * Remove accessToken 244 | * 245 | * @param AccessToken $accessToken 246 | */ 247 | public function removeAccessToken(AccessToken $accessToken) 248 | { 249 | $this->accessToken->removeElement($accessToken); 250 | } 251 | 252 | /** 253 | * Get accessToken 254 | * 255 | * @return \Doctrine\Common\Collections\Collection 256 | */ 257 | public function getAccessToken() 258 | { 259 | return $this->accessToken; 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /src/Entity/UserInterface.php: -------------------------------------------------------------------------------- 1 | config = $config; 28 | $this->mapping = $mapping; 29 | } 30 | 31 | public function getConfig() 32 | { 33 | return $this->config; 34 | } 35 | 36 | public function getMapping() 37 | { 38 | return $this->mapping; 39 | } 40 | 41 | /** 42 | * {@inheritDoc} 43 | */ 44 | public function getSubscribedEvents() 45 | { 46 | return [ 47 | Events::loadClassMetadata, 48 | ]; 49 | } 50 | 51 | /** 52 | * @param LoadClassMetadataEventArgs $eventArgs 53 | */ 54 | public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) 55 | { 56 | $this->setObjectManager($eventArgs->getObjectManager()); 57 | 58 | // the $metadata is the whole mapping info for this class 59 | $metadata = $eventArgs->getClassMetadata(); 60 | 61 | switch ($metadata->getName()) { 62 | case $this->getConfig()->user_entity->entity: 63 | $metadata->mapOneToMany([ 64 | 'targetEntity' => $this->getConfig()->client_entity->entity, 65 | 'fieldName' => $this->getConfig()->client_entity->field, 66 | 'mappedBy' => $this->getConfig()->user_entity->field, 67 | ]); 68 | 69 | $metadata->mapOneToMany([ 70 | 'targetEntity' => $this->getConfig()->access_token_entity->entity, 71 | 'fieldName' => $this->getConfig()->access_token_entity->field, 72 | 'mappedBy' => $this->getConfig()->user_entity->field, 73 | ]); 74 | 75 | $metadata->mapOneToMany([ 76 | 'targetEntity' => $this->getConfig()->authorization_code_entity->entity, 77 | 'fieldName' => $this->getConfig()->authorization_code_entity->field, 78 | 'mappedBy' => $this->getConfig()->user_entity->field, 79 | ]); 80 | 81 | $metadata->mapOneToMany([ 82 | 'targetEntity' => $this->getConfig()->refresh_token_entity->entity, 83 | 'fieldName' => $this->getConfig()->refresh_token_entity->field, 84 | 'mappedBy' => $this->getConfig()->user_entity->field, 85 | ]); 86 | break; 87 | 88 | case $this->getConfig()->client_entity->entity: 89 | // Add unique constriant for clientId based on column 90 | // See https://github.com/TomHAnderson/zf-oauth2-doctrine/issues/24 91 | $clientIdField = $this->getMapping()->Client->mapping->client_id->name; 92 | 93 | $clientIdColumn = $metadata->columnNames[$clientIdField]; 94 | $indexName = $this->generateIdentifierName( 95 | array_merge([$metadata->table['name']], ['clientId']), 96 | "uniq", 97 | $this->getMaxIdentifierLength() 98 | ); 99 | $metadata->table['uniqueConstraints'][$indexName]['columns'][] = $clientIdColumn; 100 | 101 | $joinMap = [ 102 | 'targetEntity' => $this->getConfig()->user_entity->entity, 103 | 'fieldName' => $this->getConfig()->user_entity->field, 104 | 'inversedBy' => $this->getConfig()->client_entity->field, 105 | ]; 106 | if (isset($this->getConfig()->client_entity->additional_mapping_data)) { 107 | $joinMap = array_merge( 108 | $joinMap, 109 | $this->getConfig()->client_entity->additional_mapping_data->toArray() 110 | ); 111 | } 112 | $metadata->mapManyToOne($joinMap); 113 | break; 114 | 115 | case $this->getConfig()->access_token_entity->entity: 116 | $joinMap = [ 117 | 'targetEntity' => $this->getConfig()->user_entity->entity, 118 | 'fieldName' => $this->getConfig()->user_entity->field, 119 | 'inversedBy' => $this->getConfig()->access_token_entity->field, 120 | ]; 121 | if (isset($this->getConfig()->access_token_entity->additional_mapping_data)) { 122 | $joinMap = array_merge( 123 | $joinMap, 124 | $this->getConfig()->access_token_entity->additional_mapping_data->toArray() 125 | ); 126 | } 127 | $metadata->mapManyToOne($joinMap); 128 | break; 129 | 130 | case $this->getConfig()['authorization_code_entity']['entity']: 131 | $joinMap = [ 132 | 'targetEntity' => $this->getConfig()->user_entity->entity, 133 | 'fieldName' => $this->getConfig()->user_entity->field, 134 | 'inversedBy' => $this->getConfig()->authorization_code_entity->field, 135 | ]; 136 | if (isset($this->getConfig()->authorization_code_entity->additional_mapping_data)) { 137 | $joinMap = array_merge( 138 | $joinMap, 139 | $this->getConfig()->authorization_code_entity->additional_mapping_data->toArray() 140 | ); 141 | } 142 | $metadata->mapManyToOne($joinMap); 143 | break; 144 | 145 | case $this->getConfig()->refresh_token_entity->entity: 146 | $joinMap = [ 147 | 'targetEntity' => $this->getConfig()->user_entity->entity, 148 | 'fieldName' => $this->getConfig()->user_entity->field, 149 | 'inversedBy' => $this->getConfig()->refresh_token_entity->field, 150 | ]; 151 | if (isset($this->getConfig()->refresh_token_entity->additional_mapping_data)) { 152 | $joinMap = array_merge( 153 | $joinMap, 154 | $this->getConfig()->refresh_token_entity->additional_mapping_data->toArray() 155 | ); 156 | } 157 | $metadata->mapManyToOne($joinMap); 158 | break; 159 | 160 | case $this->getConfig()->scope_entity->entity: 161 | // Add unique constriant for clientId based on column 162 | // See https://github.com/TomHAnderson/zf-oauth2-doctrine/issues/24 163 | $nameField = $this->getMapping()->Scope->mapping->scope->name; 164 | $nameColumn = $metadata->columnNames[$nameField]; 165 | $indexName = $this->generateIdentifierName( 166 | array_merge([$metadata->table['name']], ['scope']), 167 | "uniq", 168 | $this->getMaxIdentifierLength() 169 | ); 170 | $metadata->table['uniqueConstraints'][$indexName]['columns'][] = $nameColumn; 171 | break; 172 | 173 | default: 174 | break; 175 | } 176 | } 177 | 178 | // Copied from Doctrine DBAL\Schema\Table 179 | protected function generateIdentifierName($columnNames, $prefix = '', $maxSize = 30) 180 | { 181 | $hash = implode("", array_map(function ($column) { 182 | return dechex(crc32($column)); 183 | }, $columnNames)); 184 | 185 | return substr(strtoupper($prefix . "_" . $hash), 0, $maxSize); 186 | } 187 | 188 | protected function getMaxIdentifierLength() 189 | { 190 | return $this->getObjectManager() 191 | ->getConnection() 192 | ->getSchemaManager() 193 | ->getDatabasePlatform() 194 | ->getMaxIdentifierLength() 195 | ; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/Mapper/AbstractMapper.php: -------------------------------------------------------------------------------- 1 | mapperManager = $mapperManager; 43 | 44 | return $this; 45 | } 46 | 47 | public function getMapperManager() 48 | { 49 | return $this->mapperManager; 50 | } 51 | 52 | protected function getOauth2Data() 53 | { 54 | return $this->oAuth2Data; 55 | } 56 | 57 | protected function setOauth2Data(array $data) 58 | { 59 | $this->oAuth2Data = $data; 60 | 61 | return $this; 62 | } 63 | 64 | protected function getDoctrineData() 65 | { 66 | return $this->doctrineData; 67 | } 68 | 69 | protected function setDoctrineData(array $data) 70 | { 71 | $this->doctrineData = $data; 72 | 73 | return $this; 74 | } 75 | 76 | /** 77 | * Set the mapping config 78 | * 79 | * @param array 80 | * @return this 81 | */ 82 | public function setConfig(Config $config) 83 | { 84 | $this->config = $config; 85 | 86 | return $this; 87 | } 88 | 89 | /** 90 | * Return the current config 91 | * 92 | * @return array 93 | */ 94 | public function getConfig() 95 | { 96 | return $this->config; 97 | } 98 | 99 | /** 100 | * Pass data formatted for the oauth2 server 101 | * and populate both oauth2 and doctrine data 102 | */ 103 | public function exchangeOauth2Array(array $array) 104 | { 105 | $oAuth2Data = $this->getOauth2Data(); 106 | $doctrineData = $this->getDoctrineData(); 107 | $config = $this->getConfig(); 108 | 109 | foreach ($array as $key => $value) { 110 | if (! isset($this->getConfig()->mapping->$key)) { 111 | continue; 112 | } 113 | 114 | switch ($this->getConfig()->mapping->$key->type) { 115 | // Set the value in data 116 | case 'field': 117 | switch ($this->getConfig()->mapping->$key->datatype) { 118 | case 'datetime': 119 | // Dates coming from OAuth2 are timestamps 120 | $oAuth2Data[$key] = $value; 121 | $date = new DateTime(); 122 | $date->setTimestamp($value); 123 | $doctrineData[$this->getConfig()->mapping->$key->name] = $date; 124 | break; 125 | case 'boolean': 126 | $oAuth2Data[$key] = (int)(bool)$value; 127 | $doctrineData[$this->getConfig()->mapping->$key->name] = (bool)$value; 128 | break; 129 | default: 130 | $oAuth2Data[$key] = $value; 131 | $doctrineData[$this->getConfig()->mapping->$key->name] = $value; 132 | break; 133 | } 134 | break; 135 | case 'collection': 136 | $oAuth2String = []; 137 | $fieldValues = explode(' ', $value); 138 | /** @var QueryBuilder $queryBuilder */ 139 | $queryBuilder = $this->getObjectManager()->createQueryBuilder(); 140 | $queryBuilder->select('row') 141 | ->from($this->getConfig()->mapping->$key->entity, 'row'); 142 | 143 | $queryBuilder->andwhere( 144 | $queryBuilder->expr()->in( 145 | 'row.' 146 | . $this->getConfig()->mapping->$key->name, 147 | $fieldValues 148 | ) 149 | ); 150 | 151 | $oAuth2Data[$key] = $value; 152 | $doctrineData[$this->getConfig()->mapping->$key->name] = $queryBuilder->getQuery()->getResult(); 153 | break; 154 | // Find the relation for the given value and assign to data 155 | case 'relation': 156 | // die($this->getConfig()->mapping->$key->entity); 157 | $relation = $this->getObjectManager()->getRepository($this->getConfig()->mapping->$key->entity) 158 | ->findOneBy( 159 | [ 160 | $this->getConfig()->mapping->$key->entity_field_name => $value, 161 | ] 162 | ); 163 | 164 | if (! $relation) { 165 | if (isset($this->getConfig()->mapping->$key->allow_null) 166 | && $this->getConfig()->mapping->$key->allow_null 167 | ) { 168 | } else { 169 | throw new Exception("Relation was not found: $key: $value"); 170 | } 171 | } 172 | 173 | if ($relation) { 174 | $oAuth2Data[$key] = $value; 175 | $doctrineData[$this->getConfig()->mapping->$key->name] = $relation; 176 | } else { 177 | $oAuth2Data[$key] = null; 178 | $doctrineData[$this->getConfig()->mapping->$key->name] = null; 179 | } 180 | 181 | break; 182 | default: 183 | break; 184 | } 185 | } 186 | 187 | $this->setOauth2Data($oAuth2Data); 188 | $this->setDoctrineData($doctrineData); 189 | 190 | return $this; 191 | } 192 | 193 | /** 194 | * Pass data formatted for the oauth2 server 195 | * and populate both oauth2 and doctrine data 196 | */ 197 | public function exchangeDoctrineArray(array $array) 198 | { 199 | $oAuth2Data = $this->getOauth2Data(); 200 | $doctrineData = $this->getDoctrineData(); 201 | $config = $this->getConfig(); 202 | 203 | foreach ($array as $doctrineKey => $value) { 204 | // Find the field config key from doctrine field name 205 | $key = ''; 206 | 207 | foreach ($this->getConfig()->mapping as $oAuth2FieldName => $oAuth2Config) { 208 | if ($oAuth2Config->name == $doctrineKey) { 209 | $key = $oAuth2FieldName; 210 | break; 211 | } 212 | } 213 | 214 | if (! $key) { 215 | continue; 216 | } 217 | 218 | switch ($this->getConfig()->mapping->$key->type) { 219 | // Set the value in data 220 | case 'field': 221 | switch ($this->getConfig()->mapping->$key->datatype) { 222 | case 'datetime': 223 | // Dates coming from Doctrine are datetimes 224 | $oAuth2Data[$key] = $value->format('U'); 225 | $doctrineData[$this->getConfig()->mapping->$key->name] = $value; 226 | break; 227 | case 'boolean': 228 | $oAuth2Data[$key] = (int)$value; 229 | $doctrineData[$this->getConfig()->mapping->$key->name] = (bool)$value; 230 | break; 231 | default: 232 | $oAuth2Data[$key] = $value; 233 | $doctrineData[$this->getConfig()->mapping->$key->name] = $value; 234 | break; 235 | } 236 | break; 237 | case 'collection': 238 | $oAuth2String = []; 239 | foreach ($value as $entity) { 240 | $mapper = $this->getMapperManager()->get($this->getConfig()->mapping->$key->mapper); 241 | 242 | $mapper->exchangeDoctrineArray($entity->getArrayCopy()); 243 | $data = $mapper->getOauth2ArrayCopy(); 244 | 245 | $oAuth2String[] = $data[$this->getConfig()->mapping->$key->name]; 246 | } 247 | $oAuth2Data[$key] = implode(' ', $oAuth2String); 248 | $doctrineData[$this->getConfig()->mapping->$key->name] = $value; 249 | break; 250 | // Find the relation for the given value and assign to data 251 | case 'relation': 252 | $entity = $this->getConfig()->mapping->$key->entity; 253 | 254 | if ($value instanceof $entity) { 255 | $relation = $value; 256 | $doctrineArray = $relation->getArrayCopy(); 257 | $oAuth2Value = $doctrineArray[$this->getConfig()->mapping->$key->entity_field_name]; 258 | } else { 259 | $relation = $this->getObjectManager() 260 | ->getRepository($this->getConfig()->mapping->$key->entity) 261 | ->findOneBy( 262 | [ 263 | $this->getConfig()->mapping->$key->entity_field_name => $value, 264 | ] 265 | ); 266 | } 267 | 268 | if (! $relation) { 269 | if (isset($this->getConfig()->mapping->$key->allow_null) 270 | && $this->getConfig()->mapping->$key->allow_null 271 | ) { 272 | } else { 273 | throw new Exception( 274 | "Null value found for " . $key . " in mapper. Should the reference be allow_null?" 275 | ); 276 | } 277 | } 278 | 279 | if ($relation) { 280 | $oAuth2Data[$key] = $oAuth2Value; 281 | $doctrineData[$this->getConfig()->mapping->$key->name] = $relation; 282 | 283 | // Recursively map relation data. This should handle the user_id 284 | // whenever the client_id is included. 285 | foreach ($this->getMapperManager()->getAll() as $mapper) { 286 | $entityClass = $mapper->getConfig()->entity; 287 | if ($relation instanceof $entityClass) { 288 | foreach ($mapper->getConfig()->mapping as $oAuth2Field => $mapperFieldConfig) { 289 | if ($mapperFieldConfig->type == 'relation') { 290 | $foundRecursiveMapping = true; 291 | $doctrineData = $relation->getArrayCopy(); 292 | $recursiveEntity = $doctrineData[$mapperFieldConfig->name]; 293 | 294 | if ($recursiveEntity) { 295 | $recursiveEntityData = $recursiveEntity->getArrayCopy(); 296 | $oAuth2Data[$oAuth2Field] = 297 | $recursiveEntityData[$mapperFieldConfig->entity_field_name]; 298 | 299 | $doctrineData[$mapperFieldConfig->name] = $recursiveEntity; 300 | } 301 | 302 | $doctrineData[$mapperFieldConfig->name] = $recursiveEntity; 303 | } 304 | } 305 | } 306 | } 307 | 308 | 309 | // If the relation entity is the dynamically mapped client entity then 310 | } else { 311 | $oAuth2Data[$key] = null; 312 | $doctrineData[$this->getConfig()->mapping->$key->name] = null; 313 | } 314 | break; 315 | default: 316 | break; 317 | } 318 | } 319 | 320 | $this->setOauth2Data($oAuth2Data); 321 | $this->setDoctrineData($doctrineData); 322 | 323 | return $this; 324 | } 325 | 326 | public function getOauth2ArrayCopy() 327 | { 328 | return $this->getOauth2Data(); 329 | } 330 | 331 | public function getDoctrineArrayCopy() 332 | { 333 | return $this->getDoctrineData(); 334 | } 335 | } 336 | -------------------------------------------------------------------------------- /src/Mapper/AccessToken.php: -------------------------------------------------------------------------------- 1 | 'ZF\OAuth2\Doctrine\Mapper\User', 31 | 'client' => 'ZF\OAuth2\Doctrine\Mapper\Client', 32 | 'accesstoken' => 'ZF\OAuth2\Doctrine\Mapper\AccessToken', 33 | 'refreshtoken' => 'ZF\OAuth2\Doctrine\Mapper\RefreshToken', 34 | 'authorizationcode' => 'ZF\OAuth2\Doctrine\Mapper\AuthorizationCode', 35 | 'jwt' => 'ZF\OAuth2\Doctrine\Mapper\Jwt', 36 | 'jti' => 'ZF\OAuth2\Doctrine\Mapper\Jti', 37 | 'scope' => 'ZF\OAuth2\Doctrine\Mapper\Scope', 38 | 'publickey' => 'ZF\OAuth2\Doctrine\Mapper\PublicKey', 39 | ]; 40 | 41 | /** 42 | * @param Config $config 43 | * @return $this 44 | */ 45 | public function setConfig(Config $config) 46 | { 47 | $this->config = $config; 48 | 49 | return $this; 50 | } 51 | 52 | /** 53 | * @return Config 54 | */ 55 | public function getConfig() 56 | { 57 | return $this->config; 58 | } 59 | 60 | /** 61 | * @param string $name 62 | * @param array $options 63 | * @param bool $usePeeringServiceManagers 64 | * @return AbstractMapper 65 | */ 66 | public function get($name, $options = [], $usePeeringServiceManagers = true) 67 | { 68 | /** @var AbstractMapper $instance */ 69 | $instance = new $this->invokableClasses[strtolower($name)]; 70 | $instance->setConfig($this->getConfig()->$name); 71 | $instance->setObjectManager($this->getObjectManager()); 72 | $instance->setMapperManager($this); 73 | 74 | return $instance; 75 | } 76 | 77 | public function getAll() 78 | { 79 | $resources = []; 80 | foreach ($this->getConfig() as $resourceName => $config) { 81 | $resources[] = $this->get($resourceName); 82 | } 83 | 84 | return $resources; 85 | } 86 | 87 | /** 88 | * @param mixed $command 89 | * 90 | * @return void 91 | * @throws Exception\InvalidServiceException 92 | */ 93 | public function validatePlugin($command) 94 | { 95 | if ($command instanceof AbstractMapper) { 96 | // we're okay 97 | return; 98 | } 99 | 100 | // @codeCoverageIgnoreStart 101 | throw new Exception\InvalidServiceException(sprintf( 102 | 'Plugin of type %s is invalid; must implement ZF\OAuth2\Doctrine\Mapper\AbstractMapper', 103 | (is_object($command) ? get_class($command) : gettype($command)) 104 | )); 105 | // @codeCoverageIgnoreEnd 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/Mapper/PublicKey.php: -------------------------------------------------------------------------------- 1 | ['namespaces' => [ 26 | __NAMESPACE__ => __DIR__, 27 | ] 28 | ] 29 | ]; 30 | } 31 | 32 | /** 33 | * Retrieve module configuration 34 | * 35 | * @return array 36 | */ 37 | public function getConfig() 38 | { 39 | $provider = new ConfigProvider(); 40 | 41 | return [ 42 | 'service_manager' => $provider->getDependencyConfig(), 43 | 'zf-apigility-doctrine-query-create-filter' => $provider->getQueryCreateFilterConfig(), 44 | 'zf-apigility-doctrine-query-provider' => $provider->getQueryProviderConfig(), 45 | ]; 46 | } 47 | 48 | public function onBootstrap(MvcEvent $e) 49 | { 50 | /** @var ServiceLocatorInterface $serviceManager */ 51 | $serviceManager = $e->getParam('application')->getServiceManager(); 52 | $serviceManager->get('oauth2.doctrineadapter.default')->bootstrap($e); 53 | } 54 | 55 | public function getServiceConfig() 56 | { 57 | return [ 58 | 'factories' => [ 59 | 'oauth2.doctrineadapter.default' => function ($serviceManager) { 60 | /** @var ServiceLocatorInterface | ContainerInterface $serviceManager */ 61 | $globalConfig = $serviceManager->get('Config'); 62 | $config = new Config($globalConfig['zf-oauth2-doctrine']['default']); 63 | /** @var DoctrineAdapterFactory $factory */ 64 | $factory = $serviceManager->get(DoctrineAdapterFactory::class); 65 | $factory->setConfig($config); 66 | 67 | return $factory->createService($serviceManager); 68 | } 69 | ], 70 | ]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Query/OAuth2ServerInitializer.php: -------------------------------------------------------------------------------- 1 | internalInitialize($container, $instance); 22 | } 23 | 24 | /** 25 | * @param mixed $instance 26 | * @param ServiceLocatorInterface $serviceLocator 27 | * @return \ZF\OAuth2\Doctrine\Query\OAuth2ServerInterface 28 | */ 29 | public function initialize($instance, ServiceLocatorInterface $serviceLocator) 30 | { 31 | if ($serviceLocator instanceof AbstractPluginManager) { 32 | $serviceLocator = $serviceLocator->getServiceLocator() ?: $serviceLocator; 33 | } 34 | 35 | return $this->internalInitialize($serviceLocator, $instance); 36 | } 37 | 38 | /** 39 | * @param ContainerInterface | ServiceLocatorInterface $container 40 | * @param mixed $instance 41 | * @return OAuth2ServerInterface 42 | * @throws InvalidArgumentException 43 | */ 44 | protected function internalInitialize($container, $instance) 45 | { 46 | if (! $instance instanceof OAuth2ServerInterface) { 47 | return $instance; 48 | } 49 | 50 | if (! $container instanceof ContainerInterface && ! $container instanceof ServiceLocatorInterface) { 51 | throw new InvalidArgumentException('Invalid container'); 52 | } 53 | 54 | $oAuth2ServerFactory = $container->get('ZF\OAuth2\Service\OAuth2Server'); 55 | $oAuth2Server = $oAuth2ServerFactory(); 56 | $instance->setOAuth2Server($oAuth2Server); 57 | 58 | return $instance; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Query/OAuth2ServerInterface.php: -------------------------------------------------------------------------------- 1 | oAuth2Server = $server; 16 | 17 | return $this; 18 | } 19 | 20 | public function getOauth2Server() 21 | { 22 | return $this->oAuth2Server; 23 | } 24 | 25 | public function validateOauth2($scope = null) 26 | { 27 | if (! $this->getOAuth2Server()->verifyResourceRequest( 28 | OAuth2Request::createFromGlobals(), 29 | $response = null, 30 | $scope 31 | )) { 32 | $error = $this->getOAuth2Server()->getResponse(); 33 | $parameters = $error->getParameters(); 34 | $detail = isset($parameters['error_description']) ? 35 | $parameters['error_description']: $error->getStatusText(); 36 | 37 | return new ApiProblem($error->getStatusCode(), $detail); 38 | } 39 | 40 | return true; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/Bootstrap.php: -------------------------------------------------------------------------------- 1 | add('Zend', $zf2Path . '/Zend'); 52 | } else { 53 | include $zf2Path . '/Zend/Loader/AutoloaderFactory.php'; 54 | AutoloaderFactory::factory(array( 55 | 'Zend\Loader\StandardAutoloader' => array( 56 | 'autoregister_zf' => true, 57 | 'namespaces' => array( 58 | 'ZF\OAuth2' => __DIR__ . '/../src/', 59 | __NAMESPACE__ => __DIR__, 60 | ), 61 | ), 62 | )); 63 | } 64 | } 65 | 66 | protected static function findParentPath($path) 67 | { 68 | $dir = __DIR__; 69 | $previousDir = '.'; 70 | while (!is_dir($dir . '/' . $path)) { 71 | $dir = dirname($dir); 72 | if ($previousDir === $dir) return false; 73 | $previousDir = $dir; 74 | } 75 | return $dir . '/' . $path; 76 | } 77 | } 78 | 79 | Bootstrap::init(); 80 | -------------------------------------------------------------------------------- /test/ORM/AbstractTest.php: -------------------------------------------------------------------------------- 1 | setUp(); 17 | 18 | $serviceManager = $this->getApplication()->getServiceManager(); 19 | $config = $this->getApplication()->getConfig(); 20 | $doctrineAdapter = $serviceManager->get('oauth2.doctrineadapter.default'); 21 | 22 | return [[$doctrineAdapter]]; 23 | } 24 | 25 | protected function tearDown() 26 | { 27 | } 28 | 29 | protected function setUp() 30 | { 31 | $this->setApplicationConfig( 32 | include __DIR__ . '/../asset/orm.config.php' 33 | ); 34 | 35 | parent::setUp(); 36 | 37 | $serviceManager = $this->getApplication()->getServiceManager(); 38 | $objectManager = $serviceManager->get('doctrine.entitymanager.orm_default'); 39 | 40 | try { 41 | $objectManager->getRepository('ZF\OAuth2\Doctrine\Entity\Scope')->findAll(); 42 | } catch (Exception $e) { 43 | $bcrypt = new Bcrypt(); 44 | $bcrypt->setCost(10); 45 | 46 | // Create database 47 | $tool = new SchemaTool($objectManager); 48 | $res = $tool->createSchema($objectManager->getMetadataFactory()->getAllMetadata()); 49 | 50 | // Fixtures 51 | $scope = new Entity\Scope(); 52 | $scope->setId(1); 53 | $scope->setScope('clientscope1'); 54 | 55 | $scope2 = new Entity\Scope(); 56 | $scope2->setId(2); 57 | $scope2->setScope('supportedscope1'); 58 | 59 | $scope3 = new Entity\Scope(); 60 | $scope3->setId(3); 61 | $scope3->setScope('supportedscope2'); 62 | 63 | $scope4 = new Entity\Scope(); 64 | $scope4->setId(4); 65 | $scope4->setScope('supportedscope3'); 66 | 67 | $scope5 = new Entity\Scope(); 68 | $scope5->setId(5); 69 | $scope5->setScope('defaultscope1'); 70 | $scope5->setIsDefault(true); 71 | 72 | $scope6 = new Entity\Scope(); 73 | $scope6->setId(6); 74 | $scope6->setScope('defaultscope2'); 75 | $scope6->setIsDefault(true); 76 | 77 | $objectManager->persist($scope); 78 | $objectManager->persist($scope2); 79 | $objectManager->persist($scope3); 80 | $objectManager->persist($scope4); 81 | $objectManager->persist($scope5); 82 | $objectManager->persist($scope6); 83 | 84 | $user = new User(); 85 | $user->setUsername('oauth_test_user'); 86 | $user->setPassword($bcrypt->create('testpass')); 87 | $user->setProfile('profile'); 88 | $user->setCountry('US'); 89 | $user->setPhoneNumber('phone'); 90 | $user->setEmail('doctrine@zfcampus'); 91 | 92 | $user2 = new User(); 93 | 94 | $objectManager->persist($user); 95 | $objectManager->persist($user2); 96 | 97 | $client = new Entity\Client(); 98 | $client->setClientId('oauth_test_client'); 99 | $client->setSecret($bcrypt->create('testpass')); 100 | $client->setGrantType([ 101 | 'implicit', 102 | ]); 103 | $client->setUser($user); 104 | $client->addScope($scope); 105 | $scope->addClient($client); 106 | 107 | $client2 = new Entity\Client(); 108 | $client2->setClientId('oauth_test_client2'); 109 | $client2->setSecret($bcrypt->create('testpass')); 110 | $client2->setGrantType([ 111 | 'implicit', 112 | ]); 113 | $client2->setUser($user2); 114 | 115 | $client3 = new Entity\Client(); 116 | $client3->setClientId('oauth_test_client3'); 117 | $client3->setUser($user2); 118 | 119 | $objectManager->persist($client); 120 | $objectManager->persist($client2); 121 | $objectManager->persist($client3); 122 | 123 | $accessToken = new Entity\AccessToken(); 124 | $accessToken->setClient($client); 125 | $accessToken->setExpires(DateTime::createFromFormat('Y-m-d', '2050-01-01')); 126 | $accessToken->setAccessToken('testtoken'); 127 | $accessToken->setUser($user); 128 | 129 | $objectManager->persist($accessToken); 130 | 131 | 132 | $authorizationCode = new Entity\AuthorizationCode(); 133 | $authorizationCode->setAuthorizationCode('testtoken'); 134 | $authorizationCode->setClient($client); 135 | $authorizationCode->setRedirectUri('http://redirect'); 136 | $authorizationCode->setExpires(DateTime::createFromFormat('Y-m-d', '2050-01-01')); 137 | $authorizationCode->setUser($user); 138 | 139 | $objectManager->persist($authorizationCode); 140 | 141 | $refreshToken = new Entity\RefreshToken(); 142 | $refreshToken->setClient($client); 143 | $refreshToken->setExpires(DateTime::createFromFormat('Y-m-d', '2050-01-01')); 144 | $refreshToken->setRefreshToken('testtoken'); 145 | $refreshToken->setUser($user); 146 | 147 | $objectManager->persist($refreshToken); 148 | 149 | $jwt = new Entity\Jwt; 150 | $jwt->setClient($client); 151 | $jwt->setSubject('test_subject'); 152 | $jwt->setPublicKey("-----BEGIN PUBLIC KEY----- 153 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvfF+Cw8nzsc9Twam37SYpAW3+ 154 | lRGUle/hYnd9obfBvDHKBvgb1WfGCblwjwImGL9u0rEIW2sspkwBEsGGFFBmSaqq 155 | fvEER7Yr++VIidOUHkas3cHO1TVoERO3s0THOobw0OzghPnMJL6ayelYOESwfnqR 156 | WfuEMSaWaW0G38QPzwIDAQAB 157 | -----END PUBLIC KEY----- 158 | "); 159 | 160 | $objectManager->persist($jwt); 161 | 162 | $publicKey = new Entity\PublicKey(); 163 | $publicKey->setPublicKey("-----BEGIN PUBLIC KEY----- 164 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvfF+Cw8nzsc9Twam37SYpAW3+ 165 | lRGUle/hYnd9obfBvDHKBvgb1WfGCblwjwImGL9u0rEIW2sspkwBEsGGFFBmSaqq 166 | fvEER7Yr++VIidOUHkas3cHO1TVoERO3s0THOobw0OzghPnMJL6ayelYOESwfnqR 167 | WfuEMSaWaW0G38QPzwIDAQAB 168 | -----END PUBLIC KEY----- 169 | "); 170 | 171 | $publicKey->setPrivateKey("-----BEGIN RSA PRIVATE KEY----- 172 | MIICXAIBAAKBgQCvfF+Cw8nzsc9Twam37SYpAW3+lRGUle/hYnd9obfBvDHKBvgb 173 | 1WfGCblwjwImGL9u0rEIW2sspkwBEsGGFFBmSaqqfvEER7Yr++VIidOUHkas3cHO 174 | 1TVoERO3s0THOobw0OzghPnMJL6ayelYOESwfnqRWfuEMSaWaW0G38QPzwIDAQAB 175 | AoGAYHtBB+QdZJ6eHq6bYURBdsoSb6YFxGurN3+rsqb3IM0XkrvCLYtnQrqV+gym 176 | Ycu5dHTiYHXitum3X9+wBseka692RYcYuQbBIeT64H91kiFKLBy1vy/g8cmUyI0X 177 | TmabVBnFgS6JGL26C3zC71k3xmd0OQAEpAKg/vYaz2gTwAECQQDYiaEcS29aFsxm 178 | vT3/IvNV17nGvH5sJAuOkKzf6P6TyE2NmAqSjqngm0wSwRdlARcWM+v6H2R/0qdF 179 | 6azDItuBAkEAz3eCWygU7pLOtw4VfrX1ppWBIw6qLNF2lKdKPnFqFk5c3GK9ek2G 180 | tTn6NI3LT5NnKu2/YFTR4tr4hgBbdJfTTwJAWWQfxZ2Cn49P3I39PQmBqQuAnwGL 181 | szsCJl2lcF4wUnPbSDvfCXepu5aAxjE+Zi0YCctvfHdfNsGQ2nTIJFqMgQJBAL5L 182 | D/YsvYZWgeTFtlGS9M7nMpvFR7H0LqALEb5UqMns9p/usX0MvxJbK3Qo2uMSgP6P 183 | M4pYQmuiDXJbwYcf+2ECQCB3s5z9niG6oxVicCfK/l6VJNPifhtr8N48jO0ejWeB 184 | 1OYsqgH36dp0vjhmtUZip0ikLOxdOueHeOZEjwlt2l8= 185 | -----END RSA PRIVATE KEY----- 186 | "); 187 | $publicKey->setEncryptionAlgorithm('rsa'); 188 | $publicKey->setClient($client); 189 | 190 | $objectManager->persist($publicKey); 191 | $objectManager->flush(); 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /test/ORM/AccessTokenTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 14 | 15 | return; 16 | } 17 | 18 | // assert token we are about to add does not exist 19 | $token = $storage->getAccessToken('newtoken'); 20 | $this->assertFalse($token); 21 | 22 | // add new token; get user from previous token 23 | $testToken = $storage->getAccessToken('testtoken'); 24 | 25 | 26 | $expires = time() + 20; 27 | $success = $storage->setAccessToken('newtoken', 'oauth_test_client', $testToken['user_id'], $expires); 28 | $this->assertTrue($success); 29 | 30 | $token = $storage->getAccessToken('newtoken'); 31 | $this->assertNotNull($token); 32 | $this->assertArrayHasKey('access_token', $token); 33 | $this->assertArrayHasKey('client_id', $token); 34 | $this->assertArrayHasKey('user_id', $token); 35 | $this->assertArrayHasKey('expires', $token); 36 | $this->assertEquals($token['access_token'], 'newtoken'); 37 | $this->assertEquals($token['client_id'], 'oauth_test_client'); 38 | $this->assertEquals($token['user_id'], $testToken['user_id']); 39 | $this->assertEquals($token['expires'], $expires); 40 | 41 | // change existing token 42 | $expires = time() + 42; 43 | $success = $storage->setAccessToken('newtoken', 'oauth_test_client2', $testToken['user_id'], $expires); 44 | $this->assertTrue($success); 45 | 46 | $token = $storage->getAccessToken('newtoken'); 47 | $this->assertNotNull($token); 48 | $this->assertArrayHasKey('access_token', $token); 49 | $this->assertArrayHasKey('client_id', $token); 50 | $this->assertArrayHasKey('user_id', $token); 51 | $this->assertArrayHasKey('expires', $token); 52 | $this->assertEquals($token['access_token'], 'newtoken'); 53 | $this->assertEquals($token['client_id'], 'oauth_test_client2'); 54 | $this->assertEquals($token['user_id'], $testToken['user_id']); 55 | $this->assertEquals($token['expires'], $expires); 56 | 57 | $this->assertTrue($storage->setAccessToken('event_stop_propagation', '', '', '', '')); 58 | $this->assertTrue($storage->getAccessToken('event_stop_propagation')); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/ORM/AuthorizationCodeTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 15 | 16 | return; 17 | } 18 | 19 | // nonexistant client_id 20 | $details = $storage->getAuthorizationCode('faketoken'); 21 | $this->assertFalse($details); 22 | 23 | // valid client_id 24 | $details = $storage->getAuthorizationCode('testtoken'); 25 | $this->assertTrue(is_array($details->getArrayCopy())); 26 | $this->assertEquals('testtoken', $details->getAuthorizationCode()); 27 | $this->assertEquals('http://redirect', $details->getRedirectUri()); 28 | $this->assertNotNull($details->getClientId()); 29 | $this->assertNotNull($details->getUserId()); 30 | 31 | $this->assertTrue($storage->getAuthorizationCode('event_stop_propagation')); 32 | } 33 | 34 | /** @dataProvider provideStorage */ 35 | public function testSetAuthorizationCode(AuthorizationCodeInterface $storage) 36 | { 37 | if ($storage instanceof NullStorage) { 38 | $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 39 | 40 | return; 41 | } 42 | 43 | // assert code we are about to add does not exist 44 | $code = $storage->getAuthorizationCode('newcode'); 45 | $this->assertFalse($code); 46 | 47 | // base new code on existing for user 48 | $testToken = $storage->getAuthorizationCode('testtoken'); 49 | 50 | // add new code 51 | $expires = time() + 20; 52 | $success = $storage->setAuthorizationCode( 53 | 'newcode', 54 | 'oauth_test_client', 55 | $testToken['user_id'], 56 | 'http://example.com', 57 | $expires 58 | ); 59 | $this->assertTrue($success); 60 | 61 | $code = $storage->getAuthorizationCode('newcode'); 62 | $this->assertNotNull($code); 63 | $this->assertArrayHasKey('authorization_code', $code); 64 | $this->assertArrayHasKey('client_id', $code); 65 | $this->assertArrayHasKey('user_id', $code); 66 | $this->assertArrayHasKey('redirect_uri', $code); 67 | $this->assertArrayHasKey('expires', $code); 68 | $this->assertEquals($code['authorization_code'], 'newcode'); 69 | $this->assertEquals($code['client_id'], 'oauth_test_client'); 70 | $this->assertEquals($code['user_id'], $testToken['user_id']); 71 | $this->assertEquals($code['redirect_uri'], 'http://example.com'); 72 | $this->assertEquals($code['expires'], $expires); 73 | 74 | // change existing code 75 | $expires = time() + 42; 76 | $success = $storage->setAuthorizationCode( 77 | 'newcode', 78 | 'oauth_test_client2', 79 | $testToken['user_id'], 80 | 'http://example.org', 81 | $expires 82 | ); 83 | $this->assertTrue($success); 84 | 85 | $code = $storage->getAuthorizationCode('newcode'); 86 | $this->assertNotNull($code); 87 | $this->assertArrayHasKey('authorization_code', $code); 88 | $this->assertArrayHasKey('client_id', $code); 89 | $this->assertArrayHasKey('user_id', $code); 90 | $this->assertArrayHasKey('redirect_uri', $code); 91 | $this->assertArrayHasKey('expires', $code); 92 | $this->assertEquals($code['authorization_code'], 'newcode'); 93 | $this->assertEquals($code['client_id'], 'oauth_test_client2'); 94 | $this->assertEquals($code['user_id'], $testToken['user_id']); 95 | $this->assertEquals($code['redirect_uri'], 'http://example.org'); 96 | $this->assertEquals($code['expires'], $expires); 97 | 98 | $this->assertTrue($storage->setAuthorizationCode('event_stop_propagation', '', '', '', '')); 99 | } 100 | 101 | /** @dataProvider provideStorage */ 102 | public function testExpireAccessToken(AccessTokenInterface $storage) 103 | { 104 | if ($storage instanceof NullStorage) { 105 | $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 106 | 107 | return; 108 | } 109 | 110 | // base new code on existing for user 111 | $testToken = $storage->getAuthorizationCode('testtoken'); 112 | 113 | // create a valid code 114 | $expires = time() + 20; 115 | $success = $storage->setAuthorizationCode( 116 | 'code-to-expire', 117 | 'oauth_test_client', 118 | $testToken['user_id'], 119 | 'http://example.com', 120 | time() + 20 121 | ); 122 | 123 | $this->assertTrue($success); 124 | 125 | // verify the new code exists 126 | $code = $storage->getAuthorizationCode('code-to-expire'); 127 | $this->assertNotNull($code); 128 | 129 | $this->assertArrayHasKey('authorization_code', $code); 130 | $this->assertEquals($code['authorization_code'], 'code-to-expire'); 131 | 132 | // now expire the code and ensure it's no longer available 133 | $storage->expireAuthorizationCode('code-to-expire'); 134 | $code = $storage->getAuthorizationCode('code-to-expire'); 135 | $this->assertFalse($code); 136 | 137 | $this->assertTrue($storage->expireAuthorizationCode('event_stop_propagation')); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /test/ORM/ClientCredentialsTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 14 | 15 | return; 16 | } 17 | 18 | // nonexistant client_id 19 | $pass = $storage->checkClientCredentials('fakeclient', 'testpass'); 20 | $this->assertFalse($pass); 21 | 22 | // invalid password 23 | $pass = $storage->checkClientCredentials('oauth_test_client', 'invalidcredentials'); 24 | $this->assertFalse($pass); 25 | 26 | // valid credentials 27 | $pass = $storage->checkClientCredentials('oauth_test_client', 'testpass'); 28 | $this->assertTrue($pass); 29 | 30 | $this->assertTrue($storage->checkClientCredentials('event_stop_propagation', '')); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/ORM/ClientTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 14 | 15 | return; 16 | } 17 | 18 | // nonexistant client_id 19 | $details = $storage->getClientDetails('fakeclient'); 20 | $this->assertFalse($details); 21 | 22 | // valid client_id 23 | $details = $storage->getClientDetails('oauth_test_client'); 24 | $this->assertNotNull($details); 25 | $this->assertArrayHasKey('client_id', $details); 26 | $this->assertArrayHasKey('client_secret', $details); 27 | $this->assertArrayHasKey('redirect_uri', $details); 28 | 29 | $this->assertTrue($storage->getClientDetails('event_stop_propagation')); 30 | } 31 | 32 | /** @dataProvider provideStorage */ 33 | public function testCheckRestrictedGrantType(ClientInterface $storage) 34 | { 35 | if ($storage instanceof NullStorage) { 36 | $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 37 | 38 | return; 39 | } 40 | 41 | // Check invalid 42 | $pass = $storage->checkRestrictedGrantType('oauth_test_client', 'authorization_code'); 43 | $this->assertFalse($pass); 44 | 45 | // Check valid 46 | $pass = $storage->checkRestrictedGrantType('oauth_test_client', 'implicit'); 47 | $this->assertTrue($pass); 48 | 49 | $this->assertFalse($storage->checkRestrictedGrantType('invalidclient', 'implicit')); 50 | 51 | $this->assertTrue($storage->checkRestrictedGrantType('event_stop_propagation', '')); 52 | } 53 | 54 | /** @dataProvider provideStorage */ 55 | public function testGetAccessToken(ClientInterface $storage) 56 | { 57 | if ($storage instanceof NullStorage) { 58 | $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 59 | 60 | return; 61 | } 62 | 63 | // nonexistant client_id 64 | $details = $storage->getAccessToken('faketoken'); 65 | $this->assertFalse($details); 66 | 67 | // valid client_id 68 | $details = $storage->getAccessToken('testtoken'); 69 | $this->assertNotNull($details); 70 | 71 | $this->assertTrue($storage->getAccessToken('event_stop_propagation')); 72 | } 73 | 74 | /** @dataProvider provideStorage */ 75 | public function testSaveClient(ClientInterface $storage) 76 | { 77 | if ($storage instanceof NullStorage) { 78 | $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 79 | 80 | return; 81 | } 82 | 83 | $clientId = 'some-client-'. rand(); 84 | 85 | // create a new client 86 | $success = $storage->setClientDetails( 87 | $clientId, 88 | 'somesecret', 89 | 'http://test.com', 90 | 'client_credentials', 91 | 'clientscope1' 92 | ); 93 | $this->assertTrue($success); 94 | 95 | // valid client_id 96 | $details = $storage->getClientDetails($clientId); 97 | $this->assertEquals($details['client_secret'], 'somesecret'); 98 | $this->assertEquals($details['redirect_uri'], 'http://test.com'); 99 | $this->assertEquals($details['grant_types'], 'client_credentials'); 100 | $this->assertEquals($details['scope'], 'clientscope1'); 101 | 102 | $this->assertTrue($storage->setClientDetails('event_stop_propagation', '', '', '', '')); 103 | } 104 | 105 | /** @dataProvider provideStorage */ 106 | public function testIsPublicClient(ClientInterface $storage) 107 | { 108 | $this->assertFalse($storage->isPublicClient('oauth_test_client')); 109 | $this->assertTrue($storage->isPublicClient('oauth_test_client3')); 110 | $this->assertFalse($storage->isPublicClient('invalidclient')); 111 | 112 | $this->assertTrue($storage->isPublicClient('event_stop_propagation')); 113 | } 114 | 115 | /** @dataProvider provideStorage */ 116 | public function testGetClientScope(ClientInterface $storage) 117 | { 118 | $this->assertEquals('clientscope1', $storage->getClientScope('oauth_test_client')); 119 | $this->assertFalse($storage->getClientScope('invalidclient')); 120 | 121 | $this->assertTrue($storage->getClientScope('event_stop_propagation')); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /test/ORM/JwtAccessTokenTest.php: -------------------------------------------------------------------------------- 1 | format('U'); 15 | 16 | $client_id = 'oauth_test_client'; 17 | $subject = 'jtisubject'; 18 | $audience = 'http://unittest'; 19 | $jti = 'jti'; 20 | 21 | $this->assertTrue($storage->setJti($client_id, $subject, $audience, $expires, $jti)); 22 | 23 | $storage->getJti($client_id, $subject, $audience, $expires, $jti); 24 | 25 | $this->assertFalse($storage->getJti($client_id, $subject, $audience, $expires, 'invlalid')); 26 | 27 | $this->assertTrue($storage->setJti('event_stop_propagation', '', '', '', '')); 28 | $this->assertTrue($storage->getJti('event_stop_propagation', '', '', '', '')); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/ORM/JwtBearerTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 14 | 15 | return; 16 | } 17 | 18 | // nonexistant client_id 19 | $key = $storage->getClientKey('this-is-not-real', 'nor-is-this'); 20 | $this->assertFalse($key); 21 | 22 | // valid client_id invalid subject 23 | $key = $storage->getClientKey('oauth_test_client', 'nor-is-this'); 24 | $this->assertFalse($key); 25 | 26 | // valid client_id and subject 27 | $key = $storage->getClientKey('oauth_test_client', 'test_subject'); 28 | $this->assertNotNull($key); 29 | $this->assertEquals($key, "-----BEGIN PUBLIC KEY----- 30 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvfF+Cw8nzsc9Twam37SYpAW3+ 31 | lRGUle/hYnd9obfBvDHKBvgb1WfGCblwjwImGL9u0rEIW2sspkwBEsGGFFBmSaqq 32 | fvEER7Yr++VIidOUHkas3cHO1TVoERO3s0THOobw0OzghPnMJL6ayelYOESwfnqR 33 | WfuEMSaWaW0G38QPzwIDAQAB 34 | -----END PUBLIC KEY----- 35 | "); 36 | 37 | $this->assertTrue($storage->getClientKey('event_stop_propagation', '')); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/ORM/PublicKeyTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($globalPublicKey, $storage->getPublicKey('oauth_test_client')); 39 | $this->assertEquals($globalPrivateKey, $storage->getPrivateKey('oauth_test_client')); 40 | $this->assertEquals('rsa', $storage->getEncryptionAlgorithm('oauth_test_client')); 41 | 42 | $this->assertFalse($storage->getPublicKey('invalidclient')); 43 | $this->assertFalse($storage->getPublicKey('oauth_test_client2')); 44 | 45 | $this->assertFalse($storage->getPrivateKey('invalidclient')); 46 | $this->assertFalse($storage->getPrivateKey('oauth_test_client2')); 47 | 48 | $this->assertFalse($storage->getEncryptionAlgorithm('invalidclient')); 49 | $this->assertFalse($storage->getEncryptionAlgorithm('oauth_test_client2')); 50 | 51 | $this->assertTrue($storage->getPublicKey('event_stop_propagation')); 52 | $this->assertTrue($storage->getPrivateKey('event_stop_propagation')); 53 | $this->assertTrue($storage->getEncryptionAlgorithm('event_stop_propagation')); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test/ORM/RefreshTokenTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 14 | 15 | return; 16 | } 17 | 18 | // assert token we are about to add does not exist 19 | $token = $storage->getRefreshToken('refreshtoken'); 20 | $this->assertFalse($token); 21 | 22 | // base new code on existing for user 23 | $testRefreshToken = $storage->getRefreshToken('testtoken'); 24 | 25 | // add new token 26 | $expires = time() + 20; 27 | $success = $storage->setRefreshToken( 28 | 'refreshtoken', 29 | 'oauth_test_client', 30 | $testRefreshToken['user_id'], 31 | $expires, 32 | 'supportedscope1 supportedscope2' 33 | ); 34 | $this->assertTrue($success); 35 | 36 | $token = $storage->getRefreshToken('refreshtoken'); 37 | $this->assertNotNull($token); 38 | $this->assertArrayHasKey('refresh_token', $token); 39 | $this->assertArrayHasKey('client_id', $token); 40 | $this->assertArrayHasKey('user_id', $token); 41 | $this->assertArrayHasKey('expires', $token); 42 | $this->assertEquals($token['refresh_token'], 'refreshtoken'); 43 | $this->assertEquals($token['client_id'], 'oauth_test_client'); 44 | $this->assertEquals($token['user_id'], $testRefreshToken['user_id']); 45 | $this->assertEquals($token['expires'], $expires); 46 | 47 | $this->assertTrue($storage->unsetRefreshToken('refreshtoken')); 48 | 49 | $this->assertTrue($storage->setRefreshToken('event_stop_propagation', '', '', '', '')); 50 | $this->assertTrue($storage->getRefreshToken('event_stop_propagation')); 51 | $this->assertTrue($storage->unsetRefreshToken('event_stop_propagation')); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/ORM/ScopeTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 15 | 16 | return; 17 | } 18 | 19 | if (! $storage instanceof ScopeInterface) { 20 | // incompatible storage 21 | return; 22 | } 23 | 24 | //Test getting scopes 25 | $scopeUtil = new Scope($storage); 26 | $this->assertTrue($scopeUtil->scopeExists('supportedscope1')); 27 | $this->assertTrue($scopeUtil->scopeExists('supportedscope1 supportedscope2 supportedscope3')); 28 | $this->assertFalse($scopeUtil->scopeExists('fakescope')); 29 | $this->assertFalse($scopeUtil->scopeExists('supportedscope1 supportedscope2 supportedscope3 fakescope')); 30 | 31 | $this->assertTrue($storage->scopeExists('event_stop_propagation')); 32 | } 33 | 34 | /** @dataProvider provideStorage */ 35 | public function testGetDefaultScope($storage) 36 | { 37 | if ($storage instanceof NullStorage) { 38 | $this->markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 39 | 40 | return; 41 | } 42 | 43 | if (! $storage instanceof ScopeInterface) { 44 | // incompatible storage 45 | return; 46 | } 47 | 48 | // test getting default scope 49 | $scopeUtil = new Scope($storage); 50 | $expected = explode(' ', $scopeUtil->getDefaultScope()); 51 | $actual = explode(' ', 'defaultscope1 defaultscope2'); 52 | sort($expected); 53 | sort($actual); 54 | $this->assertEquals($expected, $actual); 55 | 56 | $this->assertTrue($storage->getDefaultScope('event_stop_propagation')); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test/ORM/UserCredentialsTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped('Skipped Storage: ' . $storage->getMessage()); 14 | 15 | return; 16 | } 17 | 18 | // correct credentials 19 | $this->assertTrue($storage->checkUserCredentials('oauth_test_user', 'testpass')); 20 | // invalid password 21 | $this->assertFalse($storage->checkUserCredentials('oauth_test_user', 'wronpass')); 22 | // invalid username 23 | $this->assertFalse($storage->checkUserCredentials('wrongusername', 'testpass')); 24 | 25 | // delegator 26 | $this->assertTrue($storage->checkUserCredentials('test_event_true', '')); 27 | $this->assertFalse($storage->checkUserCredentials('test_event_false', '')); 28 | 29 | // invalid username 30 | $this->assertFalse($storage->getUserDetails('wrongusername')); 31 | 32 | // ensure all properties are set 33 | $user = $storage->getUserDetails('oauth_test_user'); 34 | $this->assertTrue($user !== false); 35 | $this->assertArrayHasKey('user_id', $user); 36 | $this->assertEquals($user['user_id'], '1'); 37 | } 38 | 39 | /** @dataProvider provideStorage */ 40 | public function testUserClaims(UserCredentialsInterface $storage) 41 | { 42 | $profile = $storage->getUserClaims('oauth_test_user', 'profile'); 43 | $this->assertEquals(['profile' => 'profile'], $profile); 44 | 45 | $email = $storage->getUserClaims('oauth_test_user', 'email'); 46 | $this->assertEquals(['email' => 'doctrine@zfcampus'], $email); 47 | 48 | $address = $storage->getUserClaims('oauth_test_user', 'address'); 49 | $this->assertEquals(['country' => 'US'], $address); 50 | 51 | $phone = $storage->getUserClaims('oauth_test_user', 'phone'); 52 | $this->assertEquals(['phone_number' => 'phone'], $phone); 53 | 54 | $this->assertFalse($storage->getUserClaims('oauth_test_user', 'invalid')); 55 | $this->assertFalse($storage->getUserClaims('invalid', 'invalid')); 56 | 57 | $this->assertTrue($storage->getUserClaims('event_stop_propagation', '')); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /test/asset/data/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQCvfF+Cw8nzsc9Twam37SYpAW3+lRGUle/hYnd9obfBvDHKBvgb 3 | 1WfGCblwjwImGL9u0rEIW2sspkwBEsGGFFBmSaqqfvEER7Yr++VIidOUHkas3cHO 4 | 1TVoERO3s0THOobw0OzghPnMJL6ayelYOESwfnqRWfuEMSaWaW0G38QPzwIDAQAB 5 | AoGAYHtBB+QdZJ6eHq6bYURBdsoSb6YFxGurN3+rsqb3IM0XkrvCLYtnQrqV+gym 6 | Ycu5dHTiYHXitum3X9+wBseka692RYcYuQbBIeT64H91kiFKLBy1vy/g8cmUyI0X 7 | TmabVBnFgS6JGL26C3zC71k3xmd0OQAEpAKg/vYaz2gTwAECQQDYiaEcS29aFsxm 8 | vT3/IvNV17nGvH5sJAuOkKzf6P6TyE2NmAqSjqngm0wSwRdlARcWM+v6H2R/0qdF 9 | 6azDItuBAkEAz3eCWygU7pLOtw4VfrX1ppWBIw6qLNF2lKdKPnFqFk5c3GK9ek2G 10 | tTn6NI3LT5NnKu2/YFTR4tr4hgBbdJfTTwJAWWQfxZ2Cn49P3I39PQmBqQuAnwGL 11 | szsCJl2lcF4wUnPbSDvfCXepu5aAxjE+Zi0YCctvfHdfNsGQ2nTIJFqMgQJBAL5L 12 | D/YsvYZWgeTFtlGS9M7nMpvFR7H0LqALEb5UqMns9p/usX0MvxJbK3Qo2uMSgP6P 13 | M4pYQmuiDXJbwYcf+2ECQCB3s5z9niG6oxVicCfK/l6VJNPifhtr8N48jO0ejWeB 14 | 1OYsqgH36dp0vjhmtUZip0ikLOxdOueHeOZEjwlt2l8= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /test/asset/data/pubkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvfF+Cw8nzsc9Twam37SYpAW3+ 3 | lRGUle/hYnd9obfBvDHKBvgb1WfGCblwjwImGL9u0rEIW2sspkwBEsGGFFBmSaqq 4 | fvEER7Yr++VIidOUHkas3cHO1TVoERO3s0THOobw0OzghPnMJL6ayelYOESwfnqR 5 | WfuEMSaWaW0G38QPzwIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /test/asset/module/Doctrine/Module.php: -------------------------------------------------------------------------------- 1 | ['namespaces' => [ 22 | __NAMESPACE__ => __DIR__ . '/src/', 23 | ] 24 | ] 25 | ]; 26 | } 27 | 28 | /** 29 | * Retrieve module configuration 30 | * 31 | * @return array 32 | */ 33 | public function getConfig() 34 | { 35 | return include __DIR__ . '/config/module.config.php'; 36 | } 37 | 38 | public function onBootstrap(MvcEvent $e) 39 | { 40 | $doctrineAdapter = $serviceManager = $e->getParam('application') 41 | ->getServiceManager() 42 | ->get('oauth2.doctrineadapter.default') 43 | ; 44 | 45 | $listenerAggregate = new \ZFTest\OAuth2\Doctrine\Listener\TestEvents($doctrineAdapter); 46 | /** @var ServiceManager $serviceManager */ 47 | $serviceManager = $e->getParam('application')->getServiceManager(); 48 | /** @var EventManager $eventManager */ 49 | $eventManager = $serviceManager->get('oauth2.doctrineadapter.default')->getEventManager(); 50 | $listenerAggregate->attach($eventManager); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/asset/module/Doctrine/config/module.config.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'invokables' => [ 6 | 'ZFTest\OAuth2\Doctrine\Listener\TestEvents' 7 | => 'ZFTest\OAuth2\Doctrine\Listener\TestEvents', 8 | ], 9 | ], 10 | 'doctrine' => [ 11 | 'driver' => [ 12 | 'orm_driver' => [ 13 | 'class' => 'Doctrine\\ORM\\Mapping\\Driver\\XmlDriver', 14 | 'paths' => [ 15 | 0 => __DIR__ . '/orm', 16 | ], 17 | ], 18 | 'orm_default' => [ 19 | 'class' => 'Doctrine\\ORM\\Mapping\\Driver\\DriverChain', 20 | 'drivers' => [ 21 | 'ZFTest\\OAuth2\\Doctrine\\Entity' => 'orm_driver', 22 | ], 23 | ], 24 | ], 25 | ], 26 | ]; 27 | -------------------------------------------------------------------------------- /test/asset/module/Doctrine/config/orm/ZFTest.OAuth2.Doctrine.Entity.User.dcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/asset/module/Doctrine/src/Entity/User.php: -------------------------------------------------------------------------------- 1 | $value) { 27 | switch ($key) { 28 | case 'username': 29 | $this->setUsername($value); 30 | break; 31 | case 'password': 32 | $this->setPassword($value); 33 | break; 34 | case 'profile': 35 | $this->setProfile($value); 36 | break; 37 | case 'email': 38 | $this->setEmail($value); 39 | break; 40 | case 'country': 41 | $this->setAddress($value); 42 | break; 43 | case 'phone_number': 44 | case 'phoneNumber': 45 | $this->setPhone($value); 46 | break; 47 | default: 48 | break; 49 | } 50 | } 51 | 52 | return $this; 53 | } 54 | 55 | public function getArrayCopy() 56 | { 57 | return [ 58 | 'id' => $this->getId(), 59 | 'username' => $this->getUsername(), 60 | 'password' => $this->getPassword(), 61 | 'profile' => $this->getProfile(), 62 | 'email' => $this->getEmail(), 63 | 'country' => $this->getCountry(), 64 | 'phone_number' => $this->getPhoneNumber(), // underscore formatting for openid 65 | 'phoneNumber' => $this->getPhoneNumber(), 66 | ]; 67 | } 68 | 69 | public function getId() 70 | { 71 | return $this->id; 72 | } 73 | 74 | public function getPhoneNumber() 75 | { 76 | return $this->phone_number; 77 | } 78 | 79 | public function setPhoneNumber($value) 80 | { 81 | $this->phone_number = $value; 82 | 83 | return $this; 84 | } 85 | 86 | public function getCountry() 87 | { 88 | return $this->country; 89 | } 90 | 91 | public function setCountry($value) 92 | { 93 | $this->country = $value; 94 | 95 | return $this; 96 | } 97 | 98 | public function getEmail() 99 | { 100 | return $this->email; 101 | } 102 | 103 | public function setEmail($value) 104 | { 105 | $this->email = $value; 106 | 107 | return $this; 108 | } 109 | 110 | public function getProfile() 111 | { 112 | return $this->profile; 113 | } 114 | 115 | public function setProfile($value) 116 | { 117 | $this->profile = $value; 118 | 119 | return $this; 120 | } 121 | 122 | public function getUsername() 123 | { 124 | return $this->username; 125 | } 126 | 127 | public function setUsername($value) 128 | { 129 | $this->username = $value; 130 | 131 | return $this; 132 | } 133 | 134 | public function getPassword() 135 | { 136 | return $this->password; 137 | } 138 | 139 | public function setPassword($value) 140 | { 141 | $this->password = $value; 142 | 143 | return $this; 144 | } 145 | 146 | public function getClient() 147 | { 148 | return $this->client; 149 | } 150 | 151 | public function getAccessToken() 152 | { 153 | return $this->accessToken; 154 | } 155 | 156 | public function getAuthorizationCode() 157 | { 158 | return $this->authorizationCode; 159 | } 160 | 161 | public function getRefreshToken() 162 | { 163 | return $this->refreshToken; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /test/asset/module/Doctrine/src/Listener/TestEvents.php: -------------------------------------------------------------------------------- 1 | doctrineAdapter = $doctrineAdapter; 19 | } 20 | 21 | public function attach(EventManagerInterface $events, $priority = 1) 22 | { 23 | $this->handlers[] = $events->attach('checkUserCredentials', [$this, 'checkUserCredentials']); 24 | $this->handlers[] = $events->attach('checkClientCredentials', [$this, 'emptyEvent']); 25 | $this->handlers[] = $events->attach('isPublicClient', [$this, 'emptyEvent']); 26 | $this->handlers[] = $events->attach('getClientDetails', [$this, 'emptyEvent']); 27 | $this->handlers[] = $events->attach('setClientDetails', [$this, 'emptyEvent']); 28 | $this->handlers[] = $events->attach('checkRestrictedGrantType', [$this, 'emptyEvent']); 29 | $this->handlers[] = $events->attach('getClientScope', [$this, 'emptyEvent']); 30 | $this->handlers[] = $events->attach('getAccessToken', [$this, 'emptyEvent']); 31 | $this->handlers[] = $events->attach('setAccessToken', [$this, 'emptyEvent']); 32 | $this->handlers[] = $events->attach('getAuthorizationCode', [$this, 'emptyEvent']); 33 | $this->handlers[] = $events->attach('setAuthorizationCode', [$this, 'emptyEvent']); 34 | $this->handlers[] = $events->attach('expireAuthorizationCode', [$this, 'emptyEvent']); 35 | $this->handlers[] = $events->attach('checkUserCredentials', [$this, 'emptyEvent']); 36 | $this->handlers[] = $events->attach('getUserDetails', [$this, 'emptyEvent']); 37 | $this->handlers[] = $events->attach('getUserClaims', [$this, 'emptyEvent']); 38 | $this->handlers[] = $events->attach('getRefreshToken', [$this, 'emptyEvent']); 39 | $this->handlers[] = $events->attach('setRefreshToken', [$this, 'emptyEvent']); 40 | $this->handlers[] = $events->attach('unsetRefreshToken', [$this, 'emptyEvent']); 41 | $this->handlers[] = $events->attach('scopeExists', [$this, 'emptyEvent']); 42 | $this->handlers[] = $events->attach('getDefaultScope', [$this, 'emptyEvent']); 43 | $this->handlers[] = $events->attach('getClientKey', [$this, 'emptyEvent']); 44 | $this->handlers[] = $events->attach('getJti', [$this, 'emptyEvent']); 45 | $this->handlers[] = $events->attach('setJti', [$this, 'emptyEvent']); 46 | $this->handlers[] = $events->attach('getPublicKey', [$this, 'emptyEvent']); 47 | $this->handlers[] = $events->attach('getPrivateKey', [$this, 'emptyEvent']); 48 | $this->handlers[] = $events->attach('getEncryptionAlgorithm', [$this, 'emptyEvent']); 49 | } 50 | 51 | public function emptyEvent(Event $e) 52 | { 53 | $params = $e->getParams(); 54 | $checkStopPropagation = reset($params); 55 | if ($checkStopPropagation == 'event_stop_propagation') { 56 | $e->stopPropagation(); 57 | 58 | return true; 59 | } 60 | } 61 | 62 | public function checkUserCredentials(Event $e) 63 | { 64 | if ($e->getParams()['username'] == 'test_event_true') { 65 | $e->stopPropagation(); 66 | 67 | return true; 68 | } 69 | 70 | if ($e->getParams()['username'] == 'test_event_false') { 71 | $e->stopPropagation(); 72 | 73 | return false; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /test/asset/orm-autoload/local.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'authentication' => [ 6 | 'adapters' => [ 7 | 'oauth2_doctrine' => [ 8 | 'adapter' => 'ZF\\MvcAuth\\Authentication\\OAuth2Adapter', 9 | 'storage' => [ 10 | 'storage' => 'oauth2.doctrineadapter.default', 11 | ], 12 | ], 13 | ], 14 | 'map' => [ 15 | 'Api\\V1' => 'oauth2_doctrine', 16 | ], 17 | ], 18 | ], 19 | 20 | 'doctrine' => [ 21 | 'connection' => [ 22 | 'orm_default' => [ 23 | 'driverClass' => 'Doctrine\DBAL\Driver\PDOSqlite\Driver', 24 | 'params' => [ 25 | 'memory' => 'true', 26 | ], 27 | ], 28 | ], 29 | ], 30 | ]; 31 | -------------------------------------------------------------------------------- /test/asset/orm.config.php: -------------------------------------------------------------------------------- 1 | $modules, 21 | 22 | // These are various options for the listeners attached to the ModuleManager 23 | 'module_listener_options' => [ 24 | // This should be an array of paths in which modules reside. 25 | // If a string key is provided, the listener will consider that a module 26 | // namespace, the value of that key the specific path to that module's 27 | // Module class. 28 | 'module_paths' => [ 29 | __DIR__ . '/../../../../..', 30 | __DIR__ . '/../../../../../vendor', 31 | __DIR__ . '/module', 32 | 'ZFTest\\OAuth2\\Doctrine' => __DIR__ . '/module/Doctrine', 33 | ], 34 | 35 | // An array of paths from which to glob configuration files after 36 | // modules are loaded. These effectively override configuration 37 | // provided by modules themselves. Paths may use GLOB_BRACE notation. 38 | 'config_glob_paths' => [ 39 | __DIR__ . '/orm-autoload/{,*.}{global,local}.php', 40 | ], 41 | 42 | ], 43 | ]; 44 | --------------------------------------------------------------------------------