vendor/hwi/oauth-bundle/DependencyInjection/Configuration.php line 148

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the HWIOAuthBundle package.
  4.  *
  5.  * (c) Hardware.Info <opensource@hardware.info>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace HWI\Bundle\OAuthBundle\DependencyInjection;
  11. use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
  12. use Symfony\Component\Config\Definition\Builder\TreeBuilder;
  13. use Symfony\Component\Config\Definition\ConfigurationInterface;
  14. /**
  15.  * Configuration for the extension.
  16.  *
  17.  * @author Alexander <iam.asm89@gmail.com>
  18.  */
  19. class Configuration implements ConfigurationInterface
  20. {
  21.     /**
  22.      * Array of supported resource owners, indentation is intentional to easily notice
  23.      * which resource is of which type.
  24.      *
  25.      * @var array
  26.      */
  27.     private static $resourceOwners = array(
  28.         'oauth2' => array(
  29.             'amazon',
  30.             'asana',
  31.             'auth0',
  32.             'azure',
  33.             'bitbucket2',
  34.             'bitly',
  35.             'box',
  36.             'bufferapp',
  37.             'clever',
  38.             'dailymotion',
  39.             'deviantart',
  40.             'deezer',
  41.             'disqus',
  42.             'eve_online',
  43.             'eventbrite',
  44.             'facebook',
  45.             'fiware',
  46.             'foursquare',
  47.             'github',
  48.             'gitlab',
  49.             'google',
  50.             'youtube',
  51.             'hubic',
  52.             'instagram',
  53.             'jawbone',
  54.             'linkedin',
  55.             'mailru',
  56.             'odnoklassniki',
  57.             'office365',
  58.             'paypal',
  59.             'qq',
  60.             'reddit',
  61.             'runkeeper',
  62.             'salesforce',
  63.             'sensio_connect',
  64.             'sina_weibo',
  65.             'slack',
  66.             'spotify',
  67.             'soundcloud',
  68.             'stack_exchange',
  69.             'strava',
  70.             'toshl',
  71.             'trakt',
  72.             'twitch',
  73.             'vkontakte',
  74.             'windows_live',
  75.             'wordpress',
  76.             'wunderlist',
  77.             'yandex',
  78.             '37signals',
  79.             'itembase',
  80.         ),
  81.         'oauth1' => array(
  82.             'bitbucket',
  83.             'discogs',
  84.             'dropbox',
  85.             'flickr',
  86.             'jira',
  87.             'stereomood',
  88.             'trello',
  89.             'twitter',
  90.             'xing',
  91.             'yahoo',
  92.         ),
  93.     );
  94.     /**
  95.      * Return the type (OAuth1 or OAuth2) of given resource owner.
  96.      *
  97.      * @param string $resourceOwner
  98.      *
  99.      * @return string
  100.      */
  101.     public static function getResourceOwnerType($resourceOwner)
  102.     {
  103.         $resourceOwner strtolower($resourceOwner);
  104.         if ('oauth1' === $resourceOwner || 'oauth2' === $resourceOwner) {
  105.             return $resourceOwner;
  106.         }
  107.         if (in_array($resourceOwner, static::$resourceOwners['oauth1'], true)) {
  108.             return 'oauth1';
  109.         }
  110.         return 'oauth2';
  111.     }
  112.     /**
  113.      * Checks that given resource owner is supported by this bundle.
  114.      *
  115.      * @param string $resourceOwner
  116.      *
  117.      * @return bool
  118.      */
  119.     public static function isResourceOwnerSupported($resourceOwner)
  120.     {
  121.         $resourceOwner strtolower($resourceOwner);
  122.         if ('oauth1' === $resourceOwner || 'oauth2' === $resourceOwner) {
  123.             return true;
  124.         }
  125.         if (in_array($resourceOwner, static::$resourceOwners['oauth1'], true)) {
  126.             return true;
  127.         }
  128.         return in_array($resourceOwner, static::$resourceOwners['oauth2'], true);
  129.     }
  130.     /**
  131.      * Generates the configuration tree builder.
  132.      *
  133.      * @return TreeBuilder $builder The tree builder
  134.      */
  135.     public function getConfigTreeBuilder()
  136.     {
  137.         $builder = new TreeBuilder();
  138.         $rootNode $builder->root('hwi_oauth');
  139.         $rootNode
  140.             ->fixXmlConfig('firewall_name')
  141.             ->children()
  142.                 ->arrayNode('firewall_names')
  143.                     ->isRequired()
  144.                     ->requiresAtLeastOneElement()
  145.                     ->prototype('scalar')->end()
  146.                 ->end()
  147.                 ->scalarNode('target_path_parameter')->defaultNull()->end()
  148.                 ->booleanNode('use_referer')->defaultFalse()->end()
  149.                 ->booleanNode('failed_use_referer')->defaultFalse()->end()
  150.                 ->scalarNode('failed_auth_path')->defaultValue('hwi_oauth_connect')->end()
  151.                 ->scalarNode('grant_rule')
  152.                     ->defaultValue('IS_AUTHENTICATED_REMEMBERED')
  153.                     ->validate()
  154.                         ->ifTrue(function ($role) {
  155.                             return !('IS_AUTHENTICATED_REMEMBERED' === $role || 'IS_AUTHENTICATED_FULLY' === $role);
  156.                         })
  157.                         ->thenInvalid('Unknown grant role set "%s".')
  158.                     ->end()
  159.                 ->end()
  160.             ->end()
  161.         ;
  162.         $this->addHttpClientConfiguration($rootNode);
  163.         $this->addConnectConfiguration($rootNode);
  164.         $this->addFosubConfiguration($rootNode);
  165.         $this->addResourceOwnersConfiguration($rootNode);
  166.         return $builder;
  167.     }
  168.     private function addResourceOwnersConfiguration(ArrayNodeDefinition $node)
  169.     {
  170.         $node
  171.             ->fixXmlConfig('resource_owner')
  172.             ->children()
  173.                 ->arrayNode('resource_owners')
  174.                     ->isRequired()
  175.                     ->useAttributeAsKey('name')
  176.                     ->prototype('array')
  177.                         ->ignoreExtraKeys()
  178.                         ->children()
  179.                             ->scalarNode('base_url')->end()
  180.                             ->scalarNode('access_token_url')
  181.                                 ->validate()
  182.                                     ->ifTrue(function ($v) {
  183.                                         return empty($v);
  184.                                     })
  185.                                     ->thenUnset()
  186.                                 ->end()
  187.                             ->end()
  188.                             ->scalarNode('authorization_url')
  189.                                 ->validate()
  190.                                     ->ifTrue(function ($v) {
  191.                                         return empty($v);
  192.                                     })
  193.                                     ->thenUnset()
  194.                                 ->end()
  195.                             ->end()
  196.                             ->scalarNode('request_token_url')
  197.                                 ->validate()
  198.                                     ->ifTrue(function ($v) {
  199.                                         return empty($v);
  200.                                     })
  201.                                     ->thenUnset()
  202.                                 ->end()
  203.                             ->end()
  204.                             ->scalarNode('revoke_token_url')
  205.                                 ->validate()
  206.                                     ->ifTrue(function ($v) {
  207.                                         return empty($v);
  208.                                     })
  209.                                     ->thenUnset()
  210.                                 ->end()
  211.                             ->end()
  212.                             ->scalarNode('infos_url')
  213.                                 ->validate()
  214.                                     ->ifTrue(function ($v) {
  215.                                         return empty($v);
  216.                                     })
  217.                                     ->thenUnset()
  218.                                 ->end()
  219.                             ->end()
  220.                             ->scalarNode('client_id')->cannotBeEmpty()->end()
  221.                             ->scalarNode('client_secret')->cannotBeEmpty()->end()
  222.                             ->scalarNode('realm')
  223.                                 ->validate()
  224.                                     ->ifTrue(function ($v) {
  225.                                         return empty($v);
  226.                                     })
  227.                                     ->thenUnset()
  228.                                 ->end()
  229.                             ->end()
  230.                             ->scalarNode('scope')
  231.                                 ->validate()
  232.                                     ->ifTrue(function ($v) {
  233.                                         return empty($v);
  234.                                     })
  235.                                     ->thenUnset()
  236.                                 ->end()
  237.                             ->end()
  238.                             ->scalarNode('user_response_class')
  239.                                 ->validate()
  240.                                     ->ifTrue(function ($v) {
  241.                                         return empty($v);
  242.                                     })
  243.                                     ->thenUnset()
  244.                                 ->end()
  245.                             ->end()
  246.                             ->scalarNode('service')
  247.                                 ->validate()
  248.                                     ->ifTrue(function ($v) {
  249.                                         return empty($v);
  250.                                     })
  251.                                     ->thenUnset()
  252.                                 ->end()
  253.                             ->end()
  254.                             ->scalarNode('class')
  255.                                 ->validate()
  256.                                     ->ifTrue(function ($v) {
  257.                                         return empty($v);
  258.                                     })
  259.                                     ->thenUnset()
  260.                                 ->end()
  261.                             ->end()
  262.                             ->scalarNode('type')
  263.                                 ->validate()
  264.                                     ->ifTrue(function ($type) {
  265.                                         return !Configuration::isResourceOwnerSupported($type);
  266.                                     })
  267.                                     ->thenInvalid('Unknown resource owner type "%s".')
  268.                                 ->end()
  269.                                 ->validate()
  270.                                     ->ifTrue(function ($v) {
  271.                                         return empty($v);
  272.                                     })
  273.                                     ->thenUnset()
  274.                                 ->end()
  275.                             ->end()
  276.                             ->arrayNode('paths')
  277.                                 ->useAttributeAsKey('name')
  278.                                 ->prototype('variable')
  279.                                     ->validate()
  280.                                         ->ifTrue(function ($v) {
  281.                                             if (null === $v) {
  282.                                                 return true;
  283.                                             }
  284.                                             if (is_array($v)) {
  285.                                                 return === count($v);
  286.                                             }
  287.                                             if (is_string($v)) {
  288.                                                 return empty($v);
  289.                                             }
  290.                                             return !is_numeric($v);
  291.                                         })
  292.                                         ->thenInvalid('Path can be only string or array type.')
  293.                                     ->end()
  294.                                 ->end()
  295.                             ->end()
  296.                             ->arrayNode('options')
  297.                                 ->useAttributeAsKey('name')
  298.                                 ->prototype('scalar')->end()
  299.                             ->end()
  300.                         ->end()
  301.                         ->validate()
  302.                             ->ifTrue(function ($c) {
  303.                                 // skip if this contains a service
  304.                                 if (isset($c['service'])) {
  305.                                     return false;
  306.                                 }
  307.                                 // for each type at least these have to be set
  308.                                 foreach (array('type''client_id''client_secret') as $child) {
  309.                                     if (!isset($c[$child])) {
  310.                                         return true;
  311.                                     }
  312.                                 }
  313.                                 return false;
  314.                             })
  315.                             ->thenInvalid("You should set at least the 'type', 'client_id' and the 'client_secret' of a resource owner.")
  316.                         ->end()
  317.                         ->validate()
  318.                             ->ifTrue(function ($c) {
  319.                                 // Skip if this contains a service or a class
  320.                                 if (isset($c['service']) || isset($c['class'])) {
  321.                                     return false;
  322.                                 }
  323.                                 // Only validate the 'oauth2' and 'oauth1' type
  324.                                 if ('oauth2' !== $c['type'] && 'oauth1' !== $c['type']) {
  325.                                     return false;
  326.                                 }
  327.                                 $children = array('authorization_url''access_token_url''request_token_url''infos_url');
  328.                                 foreach ($children as $child) {
  329.                                     // This option exists only for OAuth1.0a
  330.                                     if ('request_token_url' === $child && 'oauth2' === $c['type']) {
  331.                                         continue;
  332.                                     }
  333.                                     if (!isset($c[$child])) {
  334.                                         return true;
  335.                                     }
  336.                                 }
  337.                                 return false;
  338.                             })
  339.                             ->thenInvalid("All parameters are mandatory for types 'oauth2' and 'oauth1'. Check if you're missing one of: 'access_token_url', 'authorization_url', 'infos_url' and 'request_token_url' for 'oauth1'.")
  340.                         ->end()
  341.                         ->validate()
  342.                             ->ifTrue(function ($c) {
  343.                                 // skip if this contains a service
  344.                                 if (isset($c['service']) || isset($c['class'])) {
  345.                                     return false;
  346.                                 }
  347.                                 // Only validate the 'oauth2' and 'oauth1' type
  348.                                 if ('oauth2' !== $c['type'] && 'oauth1' !== $c['type']) {
  349.                                     return false;
  350.                                 }
  351.                                 // one of this two options must be set
  352.                                 if (=== count($c['paths'])) {
  353.                                     return !isset($c['user_response_class']);
  354.                                 }
  355.                                 foreach (array('identifier''nickname''realname') as $child) {
  356.                                     if (!isset($c['paths'][$child])) {
  357.                                         return true;
  358.                                     }
  359.                                 }
  360.                                 return false;
  361.                             })
  362.                             ->thenInvalid("At least the 'identifier', 'nickname' and 'realname' paths should be configured for 'oauth2' and 'oauth1' types.")
  363.                         ->end()
  364.                         ->validate()
  365.                             ->ifTrue(function ($c) {
  366.                                 if (isset($c['service'])) {
  367.                                     // ignore paths & options if none were set
  368.                                     return !== count($c['paths']) || !== count($c['options']) || count($c);
  369.                                 }
  370.                                 return false;
  371.                             })
  372.                             ->thenInvalid("If you're setting a 'service', no other arguments should be set.")
  373.                         ->end()
  374.                         ->validate()
  375.                             ->ifTrue(function ($c) {
  376.                                 if (!isset($c['class'])) {
  377.                                     return false;
  378.                                 }
  379.                                 return 'oauth2' !== $c['type'] && 'oauth1' !== $c['type'];
  380.                             })
  381.                             ->thenInvalid("If you're setting a 'class', you must provide a 'oauth1' or 'oauth2' type")
  382.                         ->end()
  383.                     ->end()
  384.                 ->end()
  385.             ->end()
  386.         ;
  387.     }
  388.     private function addHttpClientConfiguration(ArrayNodeDefinition $node)
  389.     {
  390.         $node
  391.             ->children()
  392.                 ->arrayNode('http')
  393.                     ->addDefaultsIfNotSet()
  394.                     ->children()
  395.                         ->scalarNode('client')->defaultValue('httplug.client.default')->end()
  396.                         ->scalarNode('message_factory')->defaultValue('httplug.message_factory.default')->end()
  397.                     ->end()
  398.                 ->end()
  399.             ->end()
  400.         ;
  401.     }
  402.     private function addConnectConfiguration(ArrayNodeDefinition $node)
  403.     {
  404.         $node
  405.             ->children()
  406.                 ->arrayNode('connect')
  407.                     ->children()
  408.                         ->booleanNode('confirmation')->defaultTrue()->end()
  409.                         ->scalarNode('account_connector')->cannotBeEmpty()->end()
  410.                         ->scalarNode('registration_form_handler')->cannotBeEmpty()->end()
  411.                         ->scalarNode('registration_form')->cannotBeEmpty()->end()
  412.                     ->end()
  413.                 ->end()
  414.             ->end()
  415.         ;
  416.     }
  417.     private function addFosubConfiguration(ArrayNodeDefinition $node)
  418.     {
  419.         $node
  420.             ->children()
  421.                 ->arrayNode('fosub')
  422.                     ->children()
  423.                         ->scalarNode('username_iterations')->defaultValue(5)->cannotBeEmpty()->end()
  424.                         ->arrayNode('properties')
  425.                             ->isRequired()
  426.                             ->useAttributeAsKey('name')
  427.                                 ->prototype('scalar')
  428.                             ->end()
  429.                         ->end()
  430.                     ->end()
  431.                 ->end()
  432.             ->end()
  433.         ;
  434.     }
  435. }