-
Notifications
You must be signed in to change notification settings - Fork 643
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(client): replace basic auth with OAuth ROPC flow
- Loading branch information
Showing
7 changed files
with
181 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import dataclasses | ||
from typing import Optional | ||
|
||
|
||
@dataclasses.dataclass | ||
class PasswordCredentials: | ||
""" | ||
Resource owner password credentials modelled according to | ||
https://docs.gitlab.com/ee/api/oauth2.html#resource-owner-password-credentials-flow | ||
https://datatracker.ietf.org/doc/html/rfc6749#section-4-3. | ||
If the GitLab server has disabled the ROPC flow without client credentials, | ||
client_id and client_secret must be provided. | ||
""" | ||
|
||
username: str | ||
password: str | ||
grant_type: str = "password" | ||
scope: str = "api" | ||
client_id: Optional[str] = None | ||
client_secret: Optional[str] = None | ||
|
||
def __post_init__(self) -> None: | ||
basic_auth = (self.client_id, self.client_secret) | ||
|
||
if not any(basic_auth): | ||
self.basic_auth = None | ||
return | ||
|
||
if not all(basic_auth): | ||
raise TypeError("Both client_id and client_secret must be defined") | ||
|
||
self.basic_auth = basic_auth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import pytest | ||
|
||
from gitlab.oauth import PasswordCredentials | ||
|
||
|
||
def test_password_credentials_without_password_raises(): | ||
with pytest.raises(TypeError, match="missing 1 required positional argument"): | ||
PasswordCredentials("username") | ||
|
||
|
||
def test_password_credentials_with_client_id_without_client_secret_raises(): | ||
with pytest.raises(TypeError, match="client_id and client_secret must be defined"): | ||
PasswordCredentials( | ||
"username", | ||
"password", | ||
client_id="abcdef123456", | ||
) | ||
|
||
|
||
def test_password_credentials_with_client_credentials_sets_basic_auth(): | ||
credentials = PasswordCredentials( | ||
"username", | ||
"password", | ||
client_id="abcdef123456", | ||
client_secret="123456abcdef", | ||
) | ||
assert credentials.basic_auth == ("abcdef123456", "123456abcdef") |