Repository: Kinto/kinto

Issue:
Exposed providers in openid capabilities are not filtered by `multiauth.policies`
For example, with:

```ini

kinto.includes = kinto.plugins.openid

multiauth.policies = google

multiauth.policy.google.use = kinto.plugins.openid.OpenIDConnectPolicy
multiauth.policy.google.issuer_url = https://accounts.google.com
multiauth.policy.google.client_id = a
multiauth.policy.google.client_secret = b

multiauth.policy.fxa.use = kinto.plugins.openid.OpenIDConnectPolicy
multiauth.policy.fxa.issuer_url = https://accounts.mozilla.org
multiauth.policy.fxa.client_id = a
multiauth.policy.fxa.client_secret = b
```

`fxa` provider should not be shown in capability.

See misbehaving code (OMG a `print()` statement!)

https://github.com/Kinto/kinto/blob/bf60689ae016a31b8c5bb1955397be46d7b4acca/kinto/plugins/openid/__init__.py#L89-L95


Discussion:
First Timer here. Could I take up this bug?
Welcome! Yes, of course! Don't hesitate to ask if something is unclear, and don't hesitate to push some draft code as a pull-request if you need early feedback.
Enjoy!
So only the users with multiauth policies assigned should be appended to openid_poilicies?
for example if `multiauth.policies = google`, then only google should be appended.
I am sorry what do you mean by capability?
The capabilities are some metadata shown in the JSON on the root URL http://localhost:8888/v1/

As you can see in the faulty code pointed above, we iterate on every settings without looking at the multiauth.policies setting at all. It should be the other way around :)
@leplatrem So from what I understand, if `multiauth.policies = foo`, `m = re.match('multiauth\.policy\.foo\.use', k)`. And if `multiauth.policies = [foo, bar]` then m will be generated for only foo and bar.
Exactly. Something like (*untested*):

```py
for policy in aslist(settings['multiauth.policies']):
    v = settings.get('multiauth.policy.%s.use' % policy, '')
    if v.endswith('OpenIDConnectPolicy'): 
        ....
```
Got it. Thanks a lot @leplatrem
@bhaveshpoddar94 Do you need any help?
@bhaveshpoddar94 ping :) Let us know if we can help or if someone should take over!
Hi, new here. Does this need to be resolved even now? The last comment was three months back
I don't think it's resolved, and seeing the lack of activity I believe you can take it!

Resolving patch:
diff --git a/kinto/plugins/openid/__init__.py b/kinto/plugins/openid/__init__.py
--- a/kinto/plugins/openid/__init__.py
+++ b/kinto/plugins/openid/__init__.py
@@ -1,7 +1,7 @@
-import re
 
 import requests
 from pyramid import authentication as base_auth
+from pyramid.settings import aslist
 from pyramid.interfaces import IAuthenticationPolicy
 from zope.interface import implementer
 
@@ -87,11 +87,10 @@ def includeme(config):
     settings = config.get_settings()
 
     openid_policies = []
-    for k, v in settings.items():
-        m = re.match('multiauth\.policy\.(.*)\.use', k)
-        if m:
-            if v.endswith('OpenIDConnectPolicy'):
-                openid_policies.append(m.group(1))
+    for policy in aslist(settings['multiauth.policies']):
+        v = settings.get('multiauth.policy.%s.use' % policy, '')
+        if v.endswith('OpenIDConnectPolicy'):
+            openid_policies.append(policy)
 
     if len(openid_policies) == 0:
         # Do not add the capability if no policy is configured.


Test patch:
diff --git a/tests/plugins/test_openid.py b/tests/plugins/test_openid.py
--- a/tests/plugins/test_openid.py
+++ b/tests/plugins/test_openid.py
@@ -46,6 +46,12 @@ def get_app_settings(cls, extras=None):
         settings["multiauth.policy.google.userid_field"] = 'email'
         return settings
 
+    def test_openid_multiple_providers(self):
+        resp = self.app.get('/')
+        capabilities = resp.json['capabilities']
+        providers = capabilities['openid']['providers']
+        assert len(providers) == 2
+
 
 class OpenIDWithoutPolicyTest(support.BaseWebTest, unittest.TestCase):
 
@@ -61,6 +67,33 @@ def test_openid_capability_is_not_added(self):
         assert 'openid' not in capabilities
 
 
+class OpenIDOnePolicyTest(support.BaseWebTest, unittest.TestCase):
+
+    @classmethod
+    def get_app_settings(cls, extras=None):
+        settings = super().get_app_settings(extras)
+        openid_policy = 'kinto.plugins.openid.OpenIDConnectPolicy'
+        settings['includes'] = 'kinto.plugins.openid'
+        settings['multiauth.policies'] = 'google'
+        settings['multiauth.policy.auth0.use'] = openid_policy
+        settings['multiauth.policy.auth0.issuer'] = 'https://auth.mozilla.auth0.com'
+        settings['multiauth.policy.auth0.client_id'] = 'abc'
+        settings["multiauth.policy.auth0.client_secret"] = 'xyz'
+
+        settings['multiauth.policy.google.use'] = openid_policy
+        settings['multiauth.policy.google.issuer'] = 'https://accounts.google.com'
+        settings['multiauth.policy.google.client_id'] = '123'
+        settings["multiauth.policy.google.client_secret"] = '789'
+        settings["multiauth.policy.google.userid_field"] = 'email'
+        return settings
+
+    def test_openid_one_provider(self):
+        resp = self.app.get('/')
+        capabilities = resp.json['capabilities']
+        providers = capabilities['openid']['providers']
+        assert len(providers) == 1
+
+
 class HelloViewTest(OpenIDWebTest):
 
     def test_openid_capability_if_enabled(self):