Coverage for odsclient/keyring_cmds.py: 72%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Authors: Sylvain MARIE <sylvain.marie@se.com>
2# + All contributors to <https://github.com/smarie/python-odsclient>
3#
4# License: 3-clause BSD, <https://github.com/smarie/python-odsclient/blob/master/LICENSE>
5from subprocess import call
7try:
8 import click
9except ImportError as e:
10 raise Exception("`click` is required for `odskeys` to work. Please `pip install click`. Caught: %r" % e)
12from odsclient.core import KR_DEFAULT_USERNAME, ODSClient
13from odsclient.shortcuts import store_apikey_in_keyring, get_apikey_from_keyring, remove_apikey_from_keyring
16@click.group()
17def odskeys():
18 """
19 Commandline utility to get/set/remove api keys from the OS keyring using the `keyring` library.
20 To get help on each command use:
22 odskeys <cmd> --help
24 """
25 pass
28def _get_url_used(platform_id, # type: str
29 base_url, # type: str
30 ):
31 # type: (...) -> str
32 """ returns the url actually used by the ODSClient """
33 client = ODSClient(platform_id=platform_id, base_url=base_url)
34 return client.base_url
37@odskeys.command(name="get")
38@click.option('-p', '--platform_id', default='public', help="Specific ODS platform id. Default 'public'")
39@click.option('-b', '--base_url', default=None, help="Specific ODS base url. Default: "
40 "https://<platform_id>.opendatasoft.com/")
41@click.option('-u', '--username', default=KR_DEFAULT_USERNAME, help='Custom username to use in the keyring entry. '
42 'Default: %s' % KR_DEFAULT_USERNAME)
43def get_ods_apikey(platform_id, # type: str
44 base_url, # type: str
45 username=KR_DEFAULT_USERNAME, # type: str
46 ):
47 """
48 Looks up an ODS apikey entry in the keyring. Custom ODS platform id or base url can be provided through options.
49 """
50 apikey = get_apikey_from_keyring(platform_id=platform_id,
51 base_url=base_url,
52 keyring_entries_username=username,
53 )
54 # actual url used, for message prints
55 url_used = _get_url_used(platform_id=platform_id, base_url=base_url)
56 if apikey is not None:
57 click.echo("Api key found for platform url '%s': %s" % (url_used, apikey))
58 else:
59 click.echo("No api key registered for platform url '%s'" % (url_used, ))
62@odskeys.command(name="remove")
63@click.option('-p', '--platform_id', default='public', help="Specific ODS platform id. Default 'public'")
64@click.option('-b', '--base_url', default=None, help="Specific ODS base url. Default: "
65 "https://<platform_id>.opendatasoft.com/")
66@click.option('-u', '--username', default=KR_DEFAULT_USERNAME, help='Custom username to use in the keyring entry. '
67 'Default: %s' % KR_DEFAULT_USERNAME)
68def remove_ods_apikey(platform_id='public', # type: str
69 base_url=None, # type: str
70 username=KR_DEFAULT_USERNAME, # type: str
71 ):
72 """
73 Removes an ODS apikey entry from the keyring. Custom ODS platform id or base url can be provided through options.
74 """
75 apikey = get_apikey_from_keyring(platform_id=platform_id,
76 base_url=base_url,
77 keyring_entries_username=username,
78 )
79 # actual url used, for message prints
80 url_used = _get_url_used(platform_id=platform_id, base_url=base_url)
81 if apikey is None:
82 click.echo("No api key registered for platform url '%s'" % (url_used,))
83 else:
84 remove_apikey_from_keyring(platform_id=platform_id,
85 base_url=base_url,
86 keyring_entries_username=username,
87 )
88 apikey = get_apikey_from_keyring(platform_id=platform_id,
89 base_url=base_url,
90 keyring_entries_username=username,
91 )
92 assert apikey is None
93 click.echo("Api key removed successfully for platform url '%s'" % (url_used,))
96@odskeys.command(name="set")
97@click.option('-p', '--platform_id', default='public', help="Specific ODS platform id. Default 'public'")
98@click.option('-b', '--base_url', default=None, help="Specific ODS base url. Default: "
99 "https://<platform_id>.opendatasoft.com/")
100@click.option('-u', '--username', default=KR_DEFAULT_USERNAME, help='Custom username to use in the keyring entry. '
101 'Default: %s' % KR_DEFAULT_USERNAME)
102@click.option('-k', '--apikey', help="apikey to register. If none is provided, you will be prompted for it.")
103def set_ods_apikey(platform_id='public', # type: str
104 base_url=None, # type: str
105 username=KR_DEFAULT_USERNAME, # type: str
106 apikey=None # type: str
107 ):
108 """
109 Creates an ODS apikey entry in the keyring. Custom ODS platform id or base url can be provided through options.
110 """
111 store_apikey_in_keyring(platform_id=platform_id,
112 base_url=base_url,
113 keyring_entries_username=username,
114 apikey=apikey
115 )
116 gotapikey = get_apikey_from_keyring(platform_id=platform_id,
117 base_url=base_url,
118 keyring_entries_username=username,
119 )
120 if apikey is not None: 120 ↛ 124line 120 didn't jump to line 124, because the condition on line 120 was never false
121 assert apikey == gotapikey
122 else:
123 # api key provided through getpass() - we do not have access to it
124 assert gotapikey is not None
125 # actual url used, for message print
126 url_used = _get_url_used(platform_id=platform_id, base_url=base_url)
127 click.echo("Api key defined successfully for platform url '%s'" % (url_used,))
130@odskeys.command(name="show")
131@click.option('-a', '--alt', default=0, help='Alternative #id (the number of available alternatives is '
132 'platform dependent)')
133def show_os_mgr(alt=0, # type: int
134 ):
135 """
136 Shows the OS credentials manager associated with current keyring backend.
137 When several alternatives exist, the `--alt` option can be used to switch from 0 (default) to others.
139 Currently supported backends and alternatives:
141 Windows WinVaultKeyring:
142 - (alt 0, default) control.exe /name Microsoft.CredentialManager
143 - (alt 1) rundll32.exe keymgr.dll, KRShowKeyMgr
145 """
146 import keyring
147 kr = keyring.get_keyring()
148 if 'Windows WinVaultKeyring' in kr.name:
149 alts = {
150 0: ["control.exe", "/name", "Microsoft.CredentialManager"],
151 1: ["cmd.exe", "/c", "start", "/B", "rundll32.exe", "keymgr.dll,KRShowKeyMgr"]
152 }
153 else:
154 click.echo("This command is not supported for keyring backend '%s', please report it here:"
155 " https://github.com/smarie/python-odsclient/issues/" % (kr.name, ))
156 return
158 # execute the alternative
159 try:
160 cmd = alts[alt]
161 except KeyError:
162 click.echo("Invalid alternative #: %s. Only [0-%s] are supported with keyring backend %s"
163 % (alt, len(alts)-1, kr.name))
164 return
165 else:
166 click.echo("Keyring backend is '%s'. Runnning command for alternative %s: '%s'" % (kr.name, alt, ' '.join(cmd)))
167 call(cmd)
170# @odskeys.command(name="list")
171# @click.option('-p', '--platform_id', default='public', help='Filter on a specific ODS platform id.')
172# @click.option('-b', '--base_url', default=1, help='Filter on a specific ODS base url')
173# def list_ods_keys(platform_id, # type: str
174# base_url # type: str
175# ):
176# """
177# Lists the
178# """
179# click.echo('Filtering: %s, %s!' % (platform_id, base_url))
180# # list with https://github.com/jaraco/keyring/issues/151
181# # but this does not work with windows backend
182# for item in keyring.get_keyring().get_preferred_collection().get_all_items():
183# print(item.get_label(), item.get_attributes())
186if __name__ == '__main__': 186 ↛ 187line 186 didn't jump to line 187, because the condition on line 186 was never true
187 odskeys()