package org.apereo.cas.ticket.registry.support.kryo; import com.esotericsoftware.kryo.Serializer; import com.esotericsoftware.kryo.serializers.FieldSerializer; import net.spy.memcached.CachedData; import org.apereo.cas.authentication.AcceptUsersAuthenticationHandler; import org.apereo.cas.authentication.BasicCredentialMetaData; import org.apereo.cas.authentication.DefaultAuthenticationBuilder; import org.apereo.cas.mock.MockTicketGrantingTicket; import org.apereo.cas.services.RegisteredService; import org.apereo.cas.services.RegisteredServiceTestUtils; import org.apereo.cas.ticket.ServiceTicket; import org.apereo.cas.ticket.TicketGrantingTicket; import org.apereo.cas.authentication.AuthenticationBuilder; import org.apereo.cas.authentication.Credential; import org.apereo.cas.authentication.DefaultHandlerResult; import org.apereo.cas.authentication.HttpBasedServiceCredential; import org.apereo.cas.authentication.UsernamePasswordCredential; import org.apereo.cas.authentication.principal.DefaultPrincipalFactory; import org.apereo.cas.mock.MockServiceTicket; import org.apereo.cas.ticket.TicketGrantingTicketImpl; import org.apereo.cas.ticket.support.NeverExpiresExpirationPolicy; import org.junit.Test; import javax.security.auth.login.AccountNotFoundException; import java.net.MalformedURLException; import java.net.URL; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import static org.junit.Assert.*; /** * Unit test for {@link KryoTranscoder} class. * * @author Marvin S. Addison * @since 3.0.0 */ @SuppressWarnings("rawtypes") public class KryoTranscoderTests { private static final String ST_ID = "ST-1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890ABCDEFGHIJK"; private static final String TGT_ID = "TGT-1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890ABCDEFGHIJK-cas1"; private static final String USERNAME = "handymanbob"; private static final String PASSWORD = "foo"; private static final String NICKNAME_KEY = "nickname"; private static final String NICKNAME_VALUE = "bob"; private final KryoTranscoder transcoder; private final Map<String, Object> principalAttributes; public KryoTranscoderTests() { transcoder = new KryoTranscoder(); final Map<Class<?>, Serializer> serializerMap = new HashMap<>(); serializerMap.put( MockServiceTicket.class, new FieldSerializer(transcoder.getKryo(), MockServiceTicket.class)); serializerMap.put( MockTicketGrantingTicket.class, new FieldSerializer(transcoder.getKryo(), MockTicketGrantingTicket.class)); transcoder.setSerializerMap(serializerMap); transcoder.initialize(); this.principalAttributes = new HashMap<>(); this.principalAttributes.put(NICKNAME_KEY, NICKNAME_VALUE); } @Test public void verifyEncodeDecodeTGTImpl() throws Exception { final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); final AuthenticationBuilder bldr = new DefaultAuthenticationBuilder( new DefaultPrincipalFactory() .createPrincipal("user", new HashMap<>(this.principalAttributes))); bldr.setAttributes(new HashMap<>(this.principalAttributes)); bldr.setAuthenticationDate(ZonedDateTime.now()); bldr.addCredential(new BasicCredentialMetaData(userPassCredential)); bldr.addFailure("error", AccountNotFoundException.class); bldr.addSuccess("authn", new DefaultHandlerResult( new AcceptUsersAuthenticationHandler(""), new BasicCredentialMetaData(userPassCredential))); final TicketGrantingTicket expectedTGT = new TicketGrantingTicketImpl(TGT_ID, RegisteredServiceTestUtils.getService(), null, bldr.build(), new NeverExpiresExpirationPolicy()); final ServiceTicket ticket = expectedTGT.grantServiceTicket(ST_ID, RegisteredServiceTestUtils.getService(), new NeverExpiresExpirationPolicy(), false, true); CachedData result = transcoder.encode(expectedTGT); final TicketGrantingTicket resultTicket = (TicketGrantingTicket) transcoder.decode(result); assertEquals(expectedTGT, resultTicket); result = transcoder.encode(ticket); final ServiceTicket resultStTicket = (ServiceTicket) transcoder.decode(result); assertEquals(ticket, resultStTicket); } @Test public void verifyEncodeDecode() throws Exception { final TicketGrantingTicket tgt = new MockTicketGrantingTicket(USERNAME); final ServiceTicket expectedST = new MockServiceTicket(ST_ID, RegisteredServiceTestUtils.getService(), tgt); assertEquals(expectedST, transcoder.decode(transcoder.encode(expectedST))); final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(USERNAME); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); internalProxyTest("http://localhost"); internalProxyTest("https://localhost:8080/path/file.html?p1=v1&p2=v2#fragment"); } private void internalProxyTest(final String proxyUrl) throws MalformedURLException { final Credential proxyCredential = new HttpBasedServiceCredential(new URL(proxyUrl), RegisteredServiceTestUtils.getRegisteredService("https://.+")); final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(USERNAME); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); } @Test public void verifyEncodeDecodeTGTWithUnmodifiableMap() throws Exception { final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(TGT_ID, userPassCredential, new HashMap<>(this.principalAttributes)); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); } @Test public void verifyEncodeDecodeTGTWithUnmodifiableList() throws Exception { final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); final List<String> values = new ArrayList<>(); values.add(NICKNAME_VALUE); final Map<String, Object> newAttributes = new HashMap<>(); newAttributes.put(NICKNAME_KEY, Collections.unmodifiableList(values)); final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(TGT_ID, userPassCredential, newAttributes); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); } @Test public void verifyEncodeDecodeTGTWithLinkedHashMap() throws Exception { final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(TGT_ID, userPassCredential, new LinkedHashMap<>(this.principalAttributes)); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); } @Test public void verifyEncodeDecodeTGTWithListOrderedMap() throws Exception { final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); @SuppressWarnings("unchecked") final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(TGT_ID, userPassCredential, this.principalAttributes); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); } @Test public void verifyEncodeDecodeTGTWithUnmodifiableSet() throws Exception { final Map<String, Object> newAttributes = new HashMap<>(); final Set<String> values = new HashSet<>(); values.add(NICKNAME_VALUE); newAttributes.put(NICKNAME_KEY, Collections.unmodifiableSet(values)); final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(TGT_ID, userPassCredential, newAttributes); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); } @Test public void verifyEncodeDecodeTGTWithSingleton() throws Exception { final Map<String, Object> newAttributes = new HashMap<>(); newAttributes.put(NICKNAME_KEY, Collections.singleton(NICKNAME_VALUE)); final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(TGT_ID, userPassCredential, newAttributes); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); } @Test public void verifyEncodeDecodeTGTWithSingletonMap() throws Exception { final Map<String, Object> newAttributes = Collections.singletonMap(NICKNAME_KEY, NICKNAME_VALUE); final Credential userPassCredential = new UsernamePasswordCredential(USERNAME, PASSWORD); final TicketGrantingTicket expectedTGT = new MockTicketGrantingTicket(TGT_ID, userPassCredential, newAttributes); expectedTGT.grantServiceTicket(ST_ID, null, null, false, true); assertEquals(expectedTGT, transcoder.decode(transcoder.encode(expectedTGT))); } @Test public void verifyEncodeDecodeRegisteredService() throws Exception { final RegisteredService service = RegisteredServiceTestUtils.getRegisteredService("helloworld"); assertEquals(service, transcoder.decode(transcoder.encode(service))); } }