Skip to content

Commit 0314667

Browse files
author
Glenn Jones
committed
PA-757 - added function to get LE cert for new-style web app. by: Glenn, Filip, Nina
1 parent f61c0b8 commit 0314667

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

pythonanywhere_core/website.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import getpass
22

33
from pythonanywhere_core.base import call_api, get_api_endpoint
4+
from pythonanywhere_core.exceptions import PythonAnywhereApiException
5+
46

57

68
class Website:
@@ -70,6 +72,26 @@ def reload(self, domain_name: str) -> dict:
7072
)
7173
return response.json()
7274

75+
def auto_ssl(self, domain_name: str) -> dict:
76+
"""Creates and applies a Let's Encrypt certificate for ``domain_name``.
77+
:param domain_name: domain name for website to apply the certificate to
78+
:return: dictionary with response"""
79+
response = call_api(
80+
f"{self.api_endpoint}{domain_name}/ssl/",
81+
"post",
82+
json={"cert_type": "letsencrypt-auto-renew"}
83+
)
84+
return response.json()
85+
86+
def get_ssl_info(self, domain_name) -> dict:
87+
"""Get SSL certificate info"""
88+
url = f"{self.api_endpoint}{domain_name}/ssl/"
89+
response = call_api(url, "get")
90+
if not response.ok:
91+
raise PythonAnywhereApiException(f"GET SSL details via API failed, got {response}:{response.text}")
92+
93+
return response.json()
94+
7395
def delete(self, domain_name: str) -> dict:
7496
"""Deletes website with ``domain_name``.
7597
:param domain_name: domain name for website to delete

tests/test_website.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import responses
66

77
from pythonanywhere_core.base import get_api_endpoint
8+
from pythonanywhere_core.exceptions import PythonAnywhereApiException
89
from pythonanywhere_core.website import Website
910

1011

@@ -112,3 +113,44 @@ def test_deletes_website(api_responses, domain_name, webapps_base_url):
112113
)
113114

114115
assert Website().delete(domain_name=domain_name) == {}
116+
117+
118+
def test_sets_lets_encrypt_cert(api_responses, domain_name, webapps_base_url):
119+
api_responses.add(
120+
responses.POST,
121+
url=f"{webapps_base_url}{domain_name}/ssl/",
122+
body=json.dumps({"status": "OK"}),
123+
status=200
124+
)
125+
126+
127+
assert Website().auto_ssl(domain_name=domain_name) == {"status": "OK"}
128+
129+
assert json.loads(api_responses.calls[0].request.body.decode()) == {
130+
"cert_type": "letsencrypt-auto-renew"
131+
}
132+
133+
134+
def test_returns_ssl_info(api_responses, domain_name, webapps_base_url):
135+
api_responses.add(
136+
responses.GET,
137+
url=f"{webapps_base_url}{domain_name}/ssl/",
138+
body=json.dumps({"status": "OK"}),
139+
status=200
140+
)
141+
142+
assert Website().get_ssl_info(domain_name=domain_name) == {"status": "OK"}
143+
144+
145+
def test_raises_if_ssl_info_does_not_return_200(api_responses, domain_name, webapps_base_url):
146+
api_responses.add(
147+
responses.GET,
148+
url=f"{webapps_base_url}{domain_name}/ssl/",
149+
status=404, body="nope"
150+
)
151+
152+
with pytest.raises(PythonAnywhereApiException) as e:
153+
Website().get_ssl_info(domain_name=domain_name)
154+
155+
assert "GET SSL details via API failed, got" in str(e.value)
156+
assert "nope" in str(e.value)

0 commit comments

Comments
 (0)