13
13
import gitlab .config
14
14
import gitlab .const
15
15
import gitlab .exceptions
16
- from gitlab import http_backends ,utils
16
+ from gitlab import http_backends ,oauth , utils
17
17
18
18
REDIRECT_MSG = (
19
19
"python-gitlab detected a {status_code} ({reason!r}) redirection. You must update "
@@ -42,8 +42,8 @@ class Gitlab:
42
42
the value is a string, it is the path to a CA file used for
43
43
certificate validation.
44
44
timeout: Timeout to use for requests to the GitLab server.
45
- http_username: Username forHTTP authentication
46
- http_password: Password forHTTP authentication
45
+ http_username: Username forOAuth ROPC flow (deprecated, use oauth_credentials)
46
+ http_password: Password forOAuth ROPC flow (deprecated, use oauth_credentials)
47
47
api_version: Gitlab API version to use (support for 4 only)
48
48
pagination: Can be set to 'keyset' to use keyset pagination
49
49
order_by: Set order_by globally
@@ -52,6 +52,7 @@ class Gitlab:
52
52
or 52x responses. Defaults to False.
53
53
keep_base_url: keep user-provided base URL for pagination if it
54
54
differs from response headers
55
+ oauth_credentials: Password credentials for authenticating via OAuth ROPC flow
55
56
56
57
Keyward Args:
57
58
requests.Session session: Http Requests Session
@@ -75,6 +76,8 @@ def __init__(
75
76
user_agent :str = gitlab .const .USER_AGENT ,
76
77
retry_transient_errors :bool = False ,
77
78
keep_base_url :bool = False ,
79
+ * ,
80
+ oauth_credentials :Optional [oauth .PasswordCredentials ]= None ,
78
81
** kwargs :Any ,
79
82
)-> None :
80
83
self ._api_version = str (api_version )
@@ -97,13 +100,15 @@ def __init__(
97
100
self .http_password = http_password
98
101
self .oauth_token = oauth_token
99
102
self .job_token = job_token
100
- self ._set_auth_info ()
103
+ self .oauth_credentials = oauth_credentials
101
104
102
105
#: Create a session object for requests
103
106
http_backend :Type [http_backends .DefaultBackend ]= kwargs .pop (
104
107
"http_backend" ,http_backends .DefaultBackend
105
108
)
106
109
self .http_backend = http_backend (** kwargs )
110
+
111
+ self ._set_auth_info ()
107
112
self .session = self .http_backend .client
108
113
109
114
self .per_page = per_page
@@ -513,28 +518,53 @@ def _set_auth_info(self) -> None:
513
518
"Only one of oauth authentication or http "
514
519
"authentication should be defined"
515
520
)
516
-
517
521
self ._http_auth = None
518
522
if self .private_token :
519
523
self .headers .pop ("Authorization" ,None )
520
524
self .headers ["PRIVATE-TOKEN" ]= self .private_token
521
525
self .headers .pop ("JOB-TOKEN" ,None )
526
+ return
527
+
528
+ if not self .oauth_credentials and (self .http_username and self .http_password ):
529
+ utils .warn (
530
+ "Passing http_username and http_password is deprecated and will be "
531
+ "removed in a future version.\n Please use the OAuth ROPC flow with"
532
+ "(gitlab.oauth.PasswordCredentials) if you need password-based"
533
+ "authentication. See https://docs.gitlab.com/ee/api/oauth2.html"
534
+ "#resource-owner-password-credentials-flow for more details." ,
535
+ category = DeprecationWarning ,
536
+ )
537
+ self .oauth_credentials = oauth .PasswordCredentials (
538
+ self .http_username ,self .http_password
539
+ )
540
+
541
+ if self .oauth_credentials :
542
+ post_data = {
543
+ "grant_type" :self .oauth_credentials .grant_type ,
544
+ "scope" :self .oauth_credentials .scope ,
545
+ "username" :self .oauth_credentials .username ,
546
+ "password" :self .oauth_credentials .password ,
547
+ }
548
+ response = self .http_post (
549
+ f"{ self ._base_url } /oauth/token" ,post_data = post_data
550
+ )
551
+ if isinstance (response ,dict ):
552
+ self .oauth_token = response ["access_token" ]
553
+ else :
554
+ self .oauth_token = response .json ()["access_token" ]
555
+ self ._http_auth = self .oauth_credentials .basic_auth
522
556
523
557
if self .oauth_token :
524
558
self .headers ["Authorization" ]= f"Bearer{ self .oauth_token } "
525
559
self .headers .pop ("PRIVATE-TOKEN" ,None )
526
560
self .headers .pop ("JOB-TOKEN" ,None )
561
+ return
527
562
528
563
if self .job_token :
529
564
self .headers .pop ("Authorization" ,None )
530
565
self .headers .pop ("PRIVATE-TOKEN" ,None )
531
566
self .headers ["JOB-TOKEN" ]= self .job_token
532
567
533
- if self .http_username :
534
- self ._http_auth = requests .auth .HTTPBasicAuth (
535
- self .http_username ,self .http_password
536
- )
537
-
538
568
@staticmethod
539
569
def enable_debug ()-> None :
540
570
import logging