Add Juju Public Key
[osm/N2VC.git] / modules / libjuju / tests / integration / test_macaroon_auth.py
1 import logging
2 import os
3
4 import macaroonbakery.bakery as bakery
5 import macaroonbakery.httpbakery as httpbakery
6 import macaroonbakery.httpbakery.agent as agent
7 from juju.errors import JujuAPIError
8 from juju.model import Model
9
10 import pytest
11
12 from .. import base
13
14 log = logging.getLogger(__name__)
15
16
17 @base.bootstrapped
18 @pytest.mark.asyncio
19 @pytest.mark.xfail
20 async def test_macaroon_auth(event_loop):
21 auth_info, username = agent_auth_info()
22 # Create a bakery client that can do agent authentication.
23 client = httpbakery.Client(
24 key=auth_info.key,
25 interaction_methods=[agent.AgentInteractor(auth_info)],
26 )
27
28 async with base.CleanModel(bakery_client=client) as m:
29 async with await m.get_controller() as c:
30 await c.grant_model(username, m.info.uuid, 'admin')
31 async with Model(
32 jujudata=NoAccountsJujuData(m._connector.jujudata),
33 bakery_client=client,
34 ):
35 pass
36
37
38 @base.bootstrapped
39 @pytest.mark.asyncio
40 @pytest.mark.xfail
41 async def test_macaroon_auth_with_bad_key(event_loop):
42 auth_info, username = agent_auth_info()
43 # Use a random key rather than the correct key.
44 auth_info = auth_info._replace(key=bakery.generate_key())
45 # Create a bakery client can do agent authentication.
46 client = httpbakery.Client(
47 key=auth_info.key,
48 interaction_methods=[agent.AgentInteractor(auth_info)],
49 )
50
51 async with base.CleanModel(bakery_client=client) as m:
52 async with await m.get_controller() as c:
53 await c.grant_model(username, m.info.uuid, 'admin')
54 try:
55 async with Model(
56 jujudata=NoAccountsJujuData(m._connector.jujudata),
57 bakery_client=client,
58 ):
59 pytest.fail('Should not be able to connect with invalid key')
60 except httpbakery.BakeryException:
61 # We're expecting this because we're using the
62 # wrong key.
63 pass
64
65
66 @base.bootstrapped
67 @pytest.mark.asyncio
68 async def test_macaroon_auth_with_unauthorized_user(event_loop):
69 auth_info, username = agent_auth_info()
70 # Create a bakery client can do agent authentication.
71 client = httpbakery.Client(
72 key=auth_info.key,
73 interaction_methods=[agent.AgentInteractor(auth_info)],
74 )
75 async with base.CleanModel(bakery_client=client) as m:
76 # Note: no grant of rights to the agent user.
77 try:
78 async with Model(
79 jujudata=NoAccountsJujuData(m._connector.jujudata),
80 bakery_client=client,
81 ):
82 pytest.fail('Should not be able to connect without grant')
83 except (JujuAPIError, httpbakery.DischargeError):
84 # We're expecting this because we're using the
85 # wrong user name.
86 pass
87
88
89 def agent_auth_info():
90 agent_data = os.environ.get('TEST_AGENTS')
91 if agent_data is None:
92 pytest.skip('skipping macaroon_auth because no TEST_AGENTS '
93 'environment variable is set')
94 auth_info = agent.read_auth_info(agent_data)
95 if len(auth_info.agents) != 1:
96 raise Exception('TEST_AGENTS agent data requires exactly one agent')
97 return auth_info, auth_info.agents[0].username
98
99
100 class NoAccountsJujuData:
101 def __init__(self, jujudata):
102 self.__jujudata = jujudata
103
104 def __getattr__(self, name):
105 return getattr(self.__jujudata, name)
106
107 def accounts(self):
108 return {}