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

66 statements  

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 

6 

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) 

11 

12from odsclient.core import KR_DEFAULT_USERNAME, ODSClient 

13from odsclient.shortcuts import store_apikey_in_keyring, get_apikey_from_keyring, remove_apikey_from_keyring 

14 

15 

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: 

21 

22 odskeys <cmd> --help 

23 

24 """ 

25 pass 

26 

27 

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 

35 

36 

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, )) 

60 

61 

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,)) 

94 

95 

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,)) 

128 

129 

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. 

138 

139 Currently supported backends and alternatives: 

140 

141 Windows WinVaultKeyring: 

142 - (alt 0, default) control.exe /name Microsoft.CredentialManager 

143 - (alt 1) rundll32.exe keymgr.dll, KRShowKeyMgr 

144 

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 

157 

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) 

168 

169 

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()) 

184 

185 

186if __name__ == '__main__': 186 ↛ 187line 186 didn't jump to line 187, because the condition on line 186 was never true

187 odskeys()