1212import gitlab .config
1313import gitlab .const
1414import gitlab .exceptions
15- from gitlab import _backends , utils
15+ from gitlab import _backends , oauth , utils
1616
1717REDIRECT_MSG = (
1818 "python-gitlab detected a {status_code} ({reason!r}) redirection. You must update "
@@ -41,8 +41,8 @@ class Gitlab:
4141 the value is a string, it is the path to a CA file used for
4242 certificate validation.
4343 timeout: Timeout to use for requests to the GitLab server.
44- http_username: Username for HTTP authentication
45- http_password: Password for HTTP authentication
44+ http_username: Username for OAuth ROPC flow (deprecated, use oauth_credentials)
45+ http_password: Password for OAuth ROPC flow (deprecated, use oauth_credentials)
4646 api_version: Gitlab API version to use (support for 4 only)
4747 pagination: Can be set to 'keyset' to use keyset pagination
4848 order_by: Set order_by globally
@@ -51,6 +51,7 @@ class Gitlab:
5151 or 52x responses. Defaults to False.
5252 keep_base_url: keep user-provided base URL for pagination if it
5353 differs from response headers
54+ oauth_credentials: Password credentials for authenticating via OAuth ROPC flow
5455
5556 Keyword Args:
5657 requests.Session session: HTTP Requests Session
@@ -74,6 +75,8 @@ def __init__(
7475 user_agent : str = gitlab .const .USER_AGENT ,
7576 retry_transient_errors : bool = False ,
7677 keep_base_url : bool = False ,
78+ * ,
79+ oauth_credentials : Optional [oauth .PasswordCredentials ] = None ,
7780 ** kwargs : Any ,
7881 ) -> None :
7982 self ._api_version = str (api_version )
@@ -96,7 +99,7 @@ def __init__(
9699 self .http_password = http_password
97100 self .oauth_token = oauth_token
98101 self .job_token = job_token
99- self ._set_auth_info ()
102+ self .oauth_credentials = oauth_credentials
100103
101104 #: Create a session object for requests
102105 _backend : Type [_backends .DefaultBackend ] = kwargs .pop (
@@ -105,6 +108,7 @@ def __init__(
105108 self ._backend = _backend (** kwargs )
106109 self .session = self ._backend .client
107110
111+ self ._set_auth_info ()
108112 self .per_page = per_page
109113 self .pagination = pagination
110114 self .order_by = order_by
@@ -522,22 +526,48 @@ def _set_auth_info(self) -> None:
522526 self .headers .pop ("Authorization" , None )
523527 self .headers ["PRIVATE-TOKEN" ] = self .private_token
524528 self .headers .pop ("JOB-TOKEN" , None )
529+ return
530+
531+ if not self .oauth_credentials and (self .http_username and self .http_password ):
532+ utils .warn (
533+ "Passing http_username and http_password is deprecated and will be "
534+ "removed in a future version.\n Please use the OAuth ROPC flow with"
535+ "(gitlab.oauth.PasswordCredentials) if you need password-based"
536+ "authentication. See https://docs.gitlab.com/ee/api/oauth2.html"
537+ "#resource-owner-password-credentials-flow for more details." ,
538+ category = DeprecationWarning ,
539+ )
540+ self .oauth_credentials = oauth .PasswordCredentials (
541+ self .http_username , self .http_password
542+ )
543+
544+ if self .oauth_credentials :
545+ post_data = {
546+ "grant_type" : self .oauth_credentials .grant_type ,
547+ "scope" : self .oauth_credentials .scope ,
548+ "username" : self .oauth_credentials .username ,
549+ "password" : self .oauth_credentials .password ,
550+ }
551+ response = self .http_post (
552+ f"{ self ._base_url } /oauth/token" , post_data = post_data
553+ )
554+ if isinstance (response , dict ):
555+ self .oauth_token = response ["access_token" ]
556+ else :
557+ self .oauth_token = response .json ()["access_token" ]
558+ self ._http_auth = self .oauth_credentials .basic_auth
525559
526560 if self .oauth_token :
527561 self .headers ["Authorization" ] = f"Bearer { self .oauth_token } "
528562 self .headers .pop ("PRIVATE-TOKEN" , None )
529563 self .headers .pop ("JOB-TOKEN" , None )
564+ return
530565
531566 if self .job_token :
532567 self .headers .pop ("Authorization" , None )
533568 self .headers .pop ("PRIVATE-TOKEN" , None )
534569 self .headers ["JOB-TOKEN" ] = self .job_token
535570
536- if self .http_username :
537- self ._http_auth = requests .auth .HTTPBasicAuth (
538- self .http_username , self .http_password
539- )
540-
541571 @staticmethod
542572 def enable_debug () -> None :
543573 import logging
0 commit comments