Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaf781c1

Browse files
authored
Merge pull request#1359 from klorenz/feat_token_lookup
feat(config): allow using a credential helper to lookup tokens
2 parentsd236267 +91ffb8e commitaf781c1

File tree

3 files changed

+132
-1
lines changed

3 files changed

+132
-1
lines changed

‎docs/cli-usage.rst‎

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ example:
4848
4949
[elsewhere]
5050
url = http://else.whe.re:8080
51-
private_token =CkqsjqcQSFH5FQKDccu4
51+
private_token =helper: path/to/helper.sh
5252
timeout = 1
5353
5454
The ``default`` option of the ``[global]`` section defines the GitLab server to
@@ -93,6 +93,8 @@ Only one of ``private_token``, ``oauth_token`` or ``job_token`` should be
9393
defined. If neither are defined an anonymous request will be sent to the Gitlab
9494
server, with very limited permissions.
9595

96+
We recommend that you use `Credential helpers`_ to securely store your tokens.
97+
9698
..list-table::GitLab server options
9799
:header-rows: 1
98100

@@ -119,6 +121,56 @@ server, with very limited permissions.
119121
* - ``http_password``
120122
- Password for optional HTTP authentication
121123

124+
125+
Credential helpers
126+
------------------
127+
128+
For all configuration options that contain secrets (``http_password``,
129+
``personal_token``, ``oauth_token``, ``job_token``), you can specify
130+
a helper program to retrieve the secret indicated by a ``helper:``
131+
prefix. This allows you to fetch values from a local keyring store
132+
or cloud-hosted vaults such as Bitwarden. Environment variables are
133+
expanded if they exist and ``~`` expands to your home directory.
134+
135+
It is expected that the helper program prints the secret to standard output.
136+
To use shell features such as piping to retrieve the value, you will need
137+
to use a wrapper script; see below.
138+
139+
Example for a `keyring<https://github.com/jaraco/keyring>`_ helper:
140+
141+
..code-block::ini
142+
143+
[global]
144+
default = somewhere
145+
ssl_verify = true
146+
timeout = 5
147+
148+
[somewhere]
149+
url = http://somewhe.re
150+
private_token = helper: keyring get Service Username
151+
timeout = 1
152+
153+
Example for a `pass<https://www.passwordstore.org>`_ helper with a wrapper script:
154+
155+
..code-block::ini
156+
157+
[global]
158+
default = somewhere
159+
ssl_verify = true
160+
timeout = 5
161+
162+
[somewhere]
163+
url = http://somewhe.re
164+
private_token = helper: /path/to/helper.sh
165+
timeout = 1
166+
167+
In `/path/to/helper.sh`:
168+
169+
..code-block::bash
170+
171+
#!/bin/bash
172+
pass show path/to/password| head -n 1
173+
122174
CLI
123175
===
124176

‎gitlab/config.py‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
importos
1919
importconfigparser
20+
importshlex
21+
importsubprocess
2022
fromtypingimportList,Optional,Union
23+
fromos.pathimportexpanduser,expandvars
2124

2225
fromgitlab.constimportUSER_AGENT
2326

@@ -33,6 +36,10 @@ def _env_config() -> List[str]:
3336
os.path.expanduser("~/.python-gitlab.cfg"),
3437
]
3538

39+
HELPER_PREFIX="helper:"
40+
41+
HELPER_ATTRIBUTES= ["job_token","http_password","private_token","oauth_token"]
42+
3643

3744
classConfigError(Exception):
3845
pass
@@ -50,6 +57,10 @@ class GitlabConfigMissingError(ConfigError):
5057
pass
5158

5259

60+
classGitlabConfigHelperError(ConfigError):
61+
pass
62+
63+
5364
classGitlabConfigParser(object):
5465
def__init__(
5566
self,gitlab_id:Optional[str]=None,config_files:Optional[List[str]]=None
@@ -150,6 +161,8 @@ def __init__(
150161
exceptException:
151162
pass
152163

164+
self._get_values_from_helper()
165+
153166
self.api_version="4"
154167
try:
155168
self.api_version=self._config.get("global","api_version")
@@ -192,3 +205,31 @@ def __init__(
192205
self.user_agent=self._config.get(self.gitlab_id,"user_agent")
193206
exceptException:
194207
pass
208+
209+
def_get_values_from_helper(self):
210+
"""Update attributes that may get values from an external helper program"""
211+
forattrinHELPER_ATTRIBUTES:
212+
value=getattr(self,attr)
213+
ifnotisinstance(value,str):
214+
continue
215+
216+
ifnotvalue.lower().strip().startswith(HELPER_PREFIX):
217+
continue
218+
219+
helper=value[len(HELPER_PREFIX) :].strip()
220+
commmand= [expanduser(expandvars(token))fortokeninshlex.split(helper)]
221+
222+
try:
223+
value= (
224+
subprocess.check_output(commmand,stderr=subprocess.PIPE)
225+
.decode("utf-8")
226+
.strip()
227+
)
228+
exceptsubprocess.CalledProcessErrorase:
229+
stderr=e.stderr.decode().strip()
230+
raiseGitlabConfigHelperError(
231+
f"Failed to read{attr} value from helper "
232+
f"for{self.gitlab_id}:\n{stderr}"
233+
)frome
234+
235+
setattr(self,attr,value)

‎gitlab/tests/test_config.py‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
importos
1919
importunittest
20+
fromtextwrapimportdedent
2021

2122
importmock
2223
importio
@@ -193,6 +194,43 @@ def test_valid_data(m_open, path_exists):
193194
assertTrue==cp.ssl_verify
194195

195196

197+
@mock.patch("os.path.exists")
198+
@mock.patch("builtins.open")
199+
deftest_data_from_helper(m_open,path_exists,tmp_path):
200+
helper=tmp_path/"helper.sh"
201+
helper.write_text(
202+
dedent(
203+
"""\
204+
#!/bin/sh
205+
echo "secret"
206+
"""
207+
)
208+
)
209+
helper.chmod(0o755)
210+
211+
fd=io.StringIO(
212+
dedent(
213+
"""\
214+
[global]
215+
default = helper
216+
217+
[helper]
218+
url = https://helper.url
219+
oauth_token = helper: %s
220+
"""
221+
)
222+
%helper
223+
)
224+
225+
fd.close=mock.Mock(return_value=None)
226+
m_open.return_value=fd
227+
cp=config.GitlabConfigParser(gitlab_id="helper")
228+
assert"helper"==cp.gitlab_id
229+
assert"https://helper.url"==cp.url
230+
assertNone==cp.private_token
231+
assert"secret"==cp.oauth_token
232+
233+
196234
@mock.patch("os.path.exists")
197235
@mock.patch("builtins.open")
198236
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp