Skip to content

Commit adc3931

Browse files
committed
Support NSS authentication
authenticate by POST username/password.
1 parent a8aa42f commit adc3931

File tree

4 files changed

+69
-6
lines changed

4 files changed

+69
-6
lines changed

src/solid/auth.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import httpx
2+
3+
4+
class Auth:
5+
def __init__(self):
6+
self.client = httpx.Client()
7+
8+
@property
9+
def is_login(self) -> bool:
10+
return self.client.cookies.get('nssidp.sid') is not None
11+
12+
def login(self, idp, username, password):
13+
# NSS only
14+
url = '/'.join((idp, 'login/password'))
15+
16+
data = {
17+
'username': username,
18+
'password': password
19+
}
20+
21+
self.client.post(url, data=data)
22+
23+
if not self.is_login:
24+
raise Exception('Cannot login.')

src/solid/solid_api.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import httpx
55
from httpx import Response, HTTPStatusError
66

7+
from solid.auth import Auth
78
from solid.utils.api_util import get_root_url, LINK, get_parent_url, get_item_name
89
from solid.utils.folder_utils import parse_folder_response
910

@@ -76,15 +77,18 @@ def __init__(self):
7677

7778

7879
class SolidAPI:
79-
def __init__(self, fetch: Callable[[str, Dict], Response], options=None):
80-
pass
80+
def __init__(self, auth=None):
81+
if not auth:
82+
auth = Auth()
83+
self.auth = auth
8184

8285
def fetch(self, method, url, options: Dict = None) -> Response:
8386
if not options:
8487
options = {}
85-
options['verify'] = False
88+
# options['verify'] = False
8689

87-
r = httpx.request(method, url, **options)
90+
r = self.auth.client.request(method, url, **options)
91+
# r= httpx.request(method, url, **options)
8892
r.raise_for_status()
8993
return r
9094

tests/test_auth.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import os
2+
3+
from solid.auth import Auth
4+
5+
IDP = os.getenv('IDP')
6+
USERNAME = os.getenv('USERNAME')
7+
PASSWORD = os.getenv('PASSWORD')
8+
9+
10+
def test_login():
11+
auth = Auth()
12+
assert not auth.is_login
13+
auth.login(IDP, USERNAME, PASSWORD)
14+
assert auth.is_login

tests/test_solid_api.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import io
2+
import os
23
import uuid
34

45
import pytest
56
from httpx import HTTPStatusError
67

8+
from solid.auth import Auth
79
from solid.solid_api import SolidAPI
810
from solid.utils.api_util import append_slashes_at_end
911

@@ -12,8 +14,27 @@ def gen_random_str() -> str:
1214
return uuid.uuid4().hex
1315

1416

15-
# base_url = 'https://dahanhsi.solidcommunity.net/'
16-
POD_ENDPOINT = 'https://pod.inrupt.com/petertc/'
17+
POD_ENDPOINT = 'https://dahanhsi.solidcommunity.net/'
18+
# POD_ENDPOINT = 'https://pod.inrupt.com/petertc/'
19+
20+
IDP = os.getenv('IDP')
21+
USERNAME = os.getenv('USERNAME')
22+
PASSWORD = os.getenv('PASSWORD')
23+
PRIVATE_RES = 'https://dahanhsi.solidcommunity.net/private/test.md.md'
24+
25+
26+
def test_private_access():
27+
auth = Auth()
28+
api = SolidAPI(auth)
29+
30+
# not login
31+
with pytest.raises(HTTPStatusError) as e:
32+
api.get(PRIVATE_RES)
33+
assert e.value.response.status_code == 401
34+
35+
# login
36+
auth.login(IDP, USERNAME, PASSWORD)
37+
api.get(PRIVATE_RES)
1738

1839

1940
def test_folder():

0 commit comments

Comments
 (0)