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
14 log
= logging
.getLogger(__name__
)
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(
25 interaction_methods
=[agent
.AgentInteractor(auth_info
)],
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')
32 jujudata
=NoAccountsJujuData(m
._connector
.jujudata
),
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(
48 interaction_methods
=[agent
.AgentInteractor(auth_info
)],
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')
56 jujudata
=NoAccountsJujuData(m
._connector
.jujudata
),
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
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(
73 interaction_methods
=[agent
.AgentInteractor(auth_info
)],
75 async with base
.CleanModel(bakery_client
=client
) as m
:
76 # Note: no grant of rights to the agent user.
79 jujudata
=NoAccountsJujuData(m
._connector
.jujudata
),
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
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
100 class NoAccountsJujuData
:
101 def __init__(self
, jujudata
):
102 self
.__jujudata
= jujudata
104 def __getattr__(self
, name
):
105 return getattr(self
.__jujudata
, name
)