async def test_ps_all_exits(): expected = RsEmpty() rs = await PsAll( [ PsFixed(IdentitySimple("urn:test:1")), ], identity=0, ).exit(expected, IdentitySimple("whatever")) assert rs is expected
async def test_ps_all_fail(): idt = await PsAll( [ PsFixed(IdentitySimple("urn:test:1")), PsFixed(IdentitySimple("urn:test:2")), PsFixed(None), PsFixed(IdentitySimple("urn:test:4")), ], identity=0, ).enter(RqFake()) assert idt is None
async def test_ps_all_success_entry(): idt = await PsAll( [ PsFixed(IdentitySimple("urn:test:1")), PsFixed(IdentitySimple("urn:test:2")), PsFixed(IdentitySimple("urn:test:3")), PsFixed(IdentitySimple("urn:test:4")), ], identity=2, ).enter(RqFake()) assert await idt.urn() == "urn:test:3"
async def test_ps_cookie_sets_cookie(): rs = await PsCookie(CcPlain(), name="foo").exit( RsFake("200 OK"), identity=IdentitySimple(urn="urn:test:99")) assert await rs.headers() == { "Set-Cookie": "foo=urn%3Atest%3A99;Path=/;HttpOnly;Expires=Mon, 13 Feb 2012 03:21:34 GMT;" }
async def test_ps_token_returns_token(): signature = SiHmac("foo") rs = await PsToken.from_signature(signature).exit( RsFake("200 OK"), IdentitySimple("urn:john-gold")) assert await rs.headers() == {"Content-Type": "application/json"} assert await whole_body_of(rs) == ( b'{"jwt_token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJleHAiOiAxMzI2NTk3' b"Njk0LjAsICJpYXQiOiAxMzI2NTExMjk0LjAsICJzdWIiOiAidXJuOmpvaG4tZ29sZCJ9.FKuDBgE" b'lsZhhXR1RWClEpq8plv7tJWPTeQDQSL-cG-o="}')
async def test_ps_token_encode_decode(): signature = SiHmac("foo") token = await EntrySimple(signature).new_token( IdentitySimple("urn: john-gold")) identity = await PsToken.from_signature(signature).enter( RqFake(headers={ "authorization": f"Bearer {(await token.encoded()).decode()}" })) assert await identity.properties() == {} assert await identity.urn() == "urn: john-gold"
async def test_jwt_entry_access_enter(): datetime.utcnow().timestamp() token = await EntryAccess(SiHmac("foo")).new_token(IdentitySimple("urn:john-gold")) idt = await EntryAccess(SiHmac("foo")).enter(token) assert await VdSignature(signature=SiHmac("foo")).passes_for(token) assert await VdPayload(VdSignature(signature=SiHmac("foo"))).passes_for(token) assert await idt.urn() == "urn:john-gold"
async def test_jwt_entry_refresh_data(): datetime.utcnow().timestamp() token = await EntryRefresh(SiHmac("foo") ).new_token(IdentitySimple("urn:john-gold")) assert await token.header() == {"alg": "HS256", "typ": "JWT"} payload = dict(await token.payload()) assert (datetime.utcnow().timestamp() - 1 < payload["iat"] < datetime.utcnow().timestamp()) assert payload["exp"] == payload["iat"] + 604800 del payload["exp"], payload["iat"] assert payload == {"sub": "urn:john-gold", "dest": "refresh"}
def __init__( self, identity: Union[str, Identity], rq: Request, header: str, ): self._identity: Identity = ( IdentitySimple(urn=identity) if isinstance(identity, str) else identity ) self._rq: Request = rq self._header: str = header super(RqWithAuth, self).__init__(rq)
async def decode(self, bts: bytes) -> Identity: """Decodes an identity from url-encoded plain text bytes. :param bts: an identity to be decoded :type bts: bytes :raises: :class:`muggle.facets.auth.codecs.decoding_exception.DecodingException`: if anything goes wrong :return: An identity decoded from the input bytes :rtype: :class:`muggle.facets.auth.identity.Identity` """ try: props: Dict[str, str] = {} parts: List[str] = bts.decode().split(";") for p in parts[1:]: k, v = p.split("=") props[k] = unquote_plus(v) return IdentitySimple(unquote_plus(parts[0]), MappingProxyType(props)) except Exception as e: raise DecodingException(*e.args)
import pytest from muggle.facets.auth.identity import IdentitySimple from muggle.facets.auth.ps_all import PsAll from muggle.facets.auth.ps_fixed import PsFixed from muggle.rq.rq_fake import RqFake from muggle.rs.rs_empty import RsEmpty @pytest.mark.asyncio @pytest.mark.parametrize( "passes, index", [ [[PsFixed(IdentitySimple("urn:test:1"))], 1], [[PsFixed(IdentitySimple("urn:test:1"))], -1], [[], 0], ], ) async def test_ps_all_index_check(passes, index): with pytest.raises(ValueError): PsAll(passes, index) @pytest.mark.asyncio async def test_ps_all_success_entry(): idt = await PsAll( [ PsFixed(IdentitySimple("urn:test:1")), PsFixed(IdentitySimple("urn:test:2")), PsFixed(IdentitySimple("urn:test:3")), PsFixed(IdentitySimple("urn:test:4")),
async def enter(self, user: str, password: str) -> Optional[Identity]: identity: Optional[Identity] = None if self._condition: identity = IdentitySimple(f"urn:basic:{user}") return identity
async def test_mg_auth_logs_in(): mg_fake = Mock(act=AsyncMock()) await MgAuth(mg_fake, PsFixed(IdentitySimple("urn:test:1"))).act(RqFake()) assert mg_fake.act.call_count == 1 rq = mg_fake.act.call_args.args[0] assert await rq.headers() == {"Foo": "bar", "MgAuth": "urn%3Atest%3A1"}
async def test_cc_safe_encodes(): assert (await CcSafe(CcPlain() ).encode(IdentitySimple("urn:test:3", {"name": "John Doe"}) ) == b"urn%3Atest%3A3;name=John+Doe")
async def test_cc_signed_encodes(): assert ( await CcSigned(CcPlain(), SiHmac("foo", 256)).encode( IdentitySimple("urn:test:3", {"name": "John Doe"})) == b"urn%3Atest%3A3;name=John+DoeM|\x92^\xe3}\x0cz\xf3\x93\xa2gl\x83\x13\x18\xce\x08C\x8e\xf5\x87\xd4A\x0e((\xd2\x06N@\xa5" )
async def enter(self, token: Jwt) -> Optional[Identity]: if await self._validation.passes_for(token): return IdentitySimple((await token.payload())["sub"]) return None