Skip to content

Commit 6922cc8

Browse files
woodruffwdi
andauthored
[OIDC] Pending provider views, routes, forms (#12646)
* accounts/models: initial permissions helper Signed-off-by: William Woodruff <[email protected]> * warehouse: initial view/route skeleton for pending publishers Signed-off-by: William Woodruff <[email protected]> * templates/manage: devolve common OIDC components Signed-off-by: William Woodruff <[email protected]> * HTML, form work Signed-off-by: William Woodruff <[email protected]> * warehouse: `make translations` Signed-off-by: William Woodruff <[email protected]> * warehouse: stamp the new pending publisher form out Signed-off-by: William Woodruff <[email protected]> * warehouse: more pending OIDC provider scaffolding, deletions, ratelimiting Signed-off-by: William Woodruff <[email protected]> * migrations: rebase Signed-off-by: William Woodruff <[email protected]> * oidc/forms: handle connection errors against GitHub's API Signed-off-by: William Woodruff <[email protected]> * warehouse: pending provider events Signed-off-by: William Woodruff <[email protected]> * warehouse: `make translations` Signed-off-by: William Woodruff <[email protected]> * tests: make the tests pass ...coverage needs to be brought back up. Signed-off-by: William Woodruff <[email protected]> * tests: add another OIDC form test Signed-off-by: William Woodruff <[email protected]> * warehouse: reintroduce UniqueConstraint Signed-off-by: William Woodruff <[email protected]> * templates: initial help text for OIDC, restrict add form Signed-off-by: William Woodruff <[email protected]> * accounts/views: more constraints on pending registration Signed-off-by: William Woodruff <[email protected]> * accounts/views: warn the user if the OIDC provider has already been registered ...potentially by someone else. Signed-off-by: William Woodruff <[email protected]> * warehouse/local: `make translations` Signed-off-by: William Woodruff <[email protected]> * tests: some more account model tests for pending providers Signed-off-by: William Woodruff <[email protected]> * tests: more pending provider qualification tests Signed-off-by: William Woodruff <[email protected]> * tests: more form tests Signed-off-by: William Woodruff <[email protected]> * tests: round out form coverage Signed-off-by: William Woodruff <[email protected]> * tests, warehouse: more coverage Signed-off-by: William Woodruff <[email protected]> * tests, warehouse: more coverage Signed-off-by: William Woodruff <[email protected]> * warehouse/local: `make translations` Signed-off-by: William Woodruff <[email protected]> * tests, warehouse: round out coverage Signed-off-by: William Woodruff <[email protected]> * tests, warehouse: lintage Signed-off-by: William Woodruff <[email protected]> * warehouse/locale: `make translations` Signed-off-by: William Woodruff <[email protected]> * Apply suggestions from code review Co-authored-by: Dustin Ingram <[email protected]> * warehouse: `make translations` Signed-off-by: William Woodruff <[email protected]> * accounts/views: reformat Signed-off-by: William Woodruff <[email protected]> * tests, warehouse: fixups, fix tests Signed-off-by: William Woodruff <[email protected]> * tests, warehouse: remove some OIDC restrictions Signed-off-by: William Woodruff <[email protected]> * pages/help: remove talk of OIDC "flavors" Too confusing. Signed-off-by: William Woodruff <[email protected]> * warehouse, tests: better error flashes Signed-off-by: William Woodruff <[email protected]> * warehouse: dedupe project name regexps Signed-off-by: William Woodruff <[email protected]> * warehouse: `make translations` Signed-off-by: William Woodruff <[email protected]> * Update warehouse/accounts/views.py Co-authored-by: Dustin Ingram <[email protected]> * warehouse, tests: tweak OIDC limit message Signed-off-by: William Woodruff <[email protected]> * warehouse, tests: drop OIDC helper Signed-off-by: William Woodruff <[email protected]> Signed-off-by: William Woodruff <[email protected]> Co-authored-by: Dustin Ingram <[email protected]>
1 parent 21efc90 commit 6922cc8

File tree

18 files changed

+2178
-565
lines changed

18 files changed

+2178
-565
lines changed

tests/unit/accounts/test_views.py

Lines changed: 910 additions & 1 deletion
Large diffs are not rendered by default.

tests/unit/manage/test_views.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9959,10 +9959,9 @@ def test_add_github_oidc_provider_oidc_not_enabled(self):
99599959

99609960
def test_add_github_oidc_provider_admin_disabled(self, monkeypatch):
99619961
project = pretend.stub()
9962-
metrics = pretend.stub(increment=pretend.call_recorder(lambda *a, **kw: None))
99639962
request = pretend.stub(
99649963
registry=pretend.stub(settings={"warehouse.oidc.enabled": True}),
9965-
find_service=lambda *a, **kw: metrics,
9964+
find_service=lambda *a, **kw: None,
99669965
flags=pretend.stub(enabled=pretend.call_recorder(lambda f: True)),
99679966
session=pretend.stub(flash=pretend.call_recorder(lambda *a, **kw: None)),
99689967
_=lambda s: s,
@@ -9975,11 +9974,6 @@ def test_add_github_oidc_provider_admin_disabled(self, monkeypatch):
99759974
)
99769975

99779976
assert view.add_github_oidc_provider() == default_response
9978-
assert view.metrics.increment.calls == [
9979-
pretend.call(
9980-
"warehouse.oidc.add_provider.attempt", tags=["provider:GitHub"]
9981-
),
9982-
]
99839977
assert request.session.flash.calls == [
99849978
pretend.call(
99859979
(
@@ -10336,10 +10330,9 @@ def test_delete_oidc_provider_oidc_not_enabled(self):
1033610330

1033710331
def test_delete_oidc_provider_admin_disabled(self, monkeypatch):
1033810332
project = pretend.stub()
10339-
metrics = pretend.stub(increment=pretend.call_recorder(lambda *a, **kw: None))
1034010333
request = pretend.stub(
1034110334
registry=pretend.stub(settings={"warehouse.oidc.enabled": True}),
10342-
find_service=lambda *a, **kw: metrics,
10335+
find_service=lambda *a, **kw: None,
1034310336
flags=pretend.stub(enabled=pretend.call_recorder(lambda f: True)),
1034410337
session=pretend.stub(flash=pretend.call_recorder(lambda *a, **kw: None)),
1034510338
)
@@ -10351,11 +10344,6 @@ def test_delete_oidc_provider_admin_disabled(self, monkeypatch):
1035110344
)
1035210345

1035310346
assert view.delete_oidc_provider() == default_response
10354-
assert view.metrics.increment.calls == [
10355-
pretend.call(
10356-
"warehouse.oidc.delete_provider.attempt",
10357-
),
10358-
]
1035910347
assert request.session.flash.calls == [
1036010348
pretend.call(
1036110349
(

tests/unit/oidc/test_forms.py

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,51 @@
1414
import pytest
1515
import wtforms
1616

17-
from requests import HTTPError, Timeout
17+
from requests import ConnectionError, HTTPError, Timeout
1818
from webob.multidict import MultiDict
1919

2020
from warehouse.oidc import forms
2121

2222

23+
class TestPendingGitHubProviderForm:
24+
def test_creation(self):
25+
project_factory = pretend.stub()
26+
form = forms.PendingGitHubProviderForm(
27+
api_token="fake-token", project_factory=project_factory
28+
)
29+
30+
assert form._project_factory == project_factory
31+
32+
def test_validate_project_name_already_in_use(self):
33+
project_factory = ["some-project"]
34+
form = forms.PendingGitHubProviderForm(
35+
api_token="fake-token", project_factory=project_factory
36+
)
37+
38+
field = pretend.stub(data="some-project")
39+
with pytest.raises(wtforms.validators.ValidationError):
40+
form.validate_project_name(field)
41+
42+
def test_validate(self, monkeypatch):
43+
data = MultiDict(
44+
{
45+
"owner": "some-owner",
46+
"repository": "some-repo",
47+
"workflow_filename": "some-workflow.yml",
48+
"project_name": "some-project",
49+
}
50+
)
51+
form = forms.PendingGitHubProviderForm(
52+
MultiDict(data), api_token=pretend.stub(), project_factory=[]
53+
)
54+
55+
# We're testing only the basic validation here.
56+
owner_info = {"login": "fake-username", "id": "1234"}
57+
monkeypatch.setattr(form, "_lookup_owner", lambda o: owner_info)
58+
59+
assert form.validate()
60+
61+
2362
class TestGitHubProviderForm:
2463
@pytest.mark.parametrize(
2564
"token, headers",
@@ -138,6 +177,7 @@ def test_lookup_owner_http_timeout(self, monkeypatch):
138177
get=pretend.raiser(Timeout),
139178
Timeout=Timeout,
140179
HTTPError=HTTPError,
180+
ConnectionError=ConnectionError,
141181
)
142182
monkeypatch.setattr(forms, "requests", requests)
143183

@@ -152,6 +192,28 @@ def test_lookup_owner_http_timeout(self, monkeypatch):
152192
pretend.call("Timeout from GitHub user lookup API (possibly offline)")
153193
]
154194

195+
def test_lookup_owner_connection_error(self, monkeypatch):
196+
requests = pretend.stub(
197+
get=pretend.raiser(ConnectionError),
198+
Timeout=Timeout,
199+
HTTPError=HTTPError,
200+
ConnectionError=ConnectionError,
201+
)
202+
monkeypatch.setattr(forms, "requests", requests)
203+
204+
sentry_sdk = pretend.stub(capture_message=pretend.call_recorder(lambda s: None))
205+
monkeypatch.setattr(forms, "sentry_sdk", sentry_sdk)
206+
207+
form = forms.GitHubProviderForm(api_token="fake-token")
208+
with pytest.raises(wtforms.validators.ValidationError):
209+
form._lookup_owner("some-owner")
210+
211+
assert sentry_sdk.capture_message.calls == [
212+
pretend.call(
213+
"Connection error from GitHub user lookup API (possibly offline)"
214+
)
215+
]
216+
155217
def test_lookup_owner_succeeds(self, monkeypatch):
156218
fake_owner_info = pretend.stub()
157219
response = pretend.stub(

tests/unit/test_routes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ def add_policy(name, filename):
197197
domain=warehouse,
198198
),
199199
pretend.call("manage.account", "/manage/account/", domain=warehouse),
200+
pretend.call(
201+
"manage.account.publishing", "/manage/account/publishing/", domain=warehouse
202+
),
200203
pretend.call(
201204
"manage.account.two-factor",
202205
"/manage/account/two-factor/",

0 commit comments

Comments
 (0)