1
# Copyright 2012-2016 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""MAAS CLI authentication."""
10
from getpass import getpass
13
from urllib.parse import urljoin
15
from apiclient.creds import convert_string_to_tuple
16
from maascli.api import (
22
class UnexpectedResponse(Exception):
23
"""Unexpected API response."""
26
def try_getpass(prompt):
27
"""Call `getpass`, ignoring EOF errors."""
29
return getpass(prompt)
34
def obtain_credentials(credentials):
35
"""Prompt for credentials if possible.
37
If the credentials are "-" then read from stdin without interactive
40
if credentials == "-":
41
credentials = sys.stdin.readline().strip()
42
elif credentials is None:
43
credentials = try_getpass(
44
"API key (leave empty for anonymous access): ")
45
# Ensure that the credentials have a valid form.
46
if credentials and not credentials.isspace():
47
return convert_string_to_tuple(credentials)
52
def check_valid_apikey(url, credentials, insecure=False):
53
"""Check for valid apikey.
55
:param credentials: A 3-tuple of credentials.
58
check_url = urljoin(url, "nodegroups/")
59
uri, body, headers = Action.prepare_payload(
60
op="list", method="GET", uri=check_url, data=[])
62
check_url = urljoin(url, "users/")
63
uri, body, headers = Action.prepare_payload(
64
op="whoami", method="GET", uri=check_url, data=[])
66
# Headers are returned as a list, but they must be a dict for
67
# the signing machinery.
68
headers = dict(headers)
70
Action.sign(uri, headers, credentials)
72
response, content = http_request(
73
uri, method="GET", body=body, headers=headers,
76
status = int(response['status'])
77
if status == http.client.UNAUTHORIZED:
79
elif status == http.client.OK:
82
raise UnexpectedResponse(
83
"The MAAS server gave an unexpected response: %s" % status)