1   package com.atlassian.security.auth.trustedapps;
2   
3   import java.io.IOException;
4   import java.io.Reader;
5   import java.io.StringReader;
6   import java.io.UnsupportedEncodingException;
7   
8   import com.atlassian.security.auth.trustedapps.ApplicationRetriever.InvalidApplicationDetailsException;
9   
10  import org.bouncycastle.util.encoders.Base64;
11  import org.junit.Test;
12  import org.mockito.Mockito;
13  
14  import static org.junit.Assert.assertEquals;
15  import static org.junit.Assert.assertNotNull;
16  import static org.junit.Assert.fail;
17  import static org.mockito.Mockito.mock;
18  import static org.mockito.Mockito.verify;
19  import static org.mockito.Mockito.when;
20  
21  public class TestReaderApplicationRetriever
22  {
23      static final String BASE64_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCySptbugHAzWUJY3ALWhuSCPhVXnwbUBfsRExYQitBCVny4V1DcU2SAx22bH9dSM0X7NdMObF74r+Wd77QoPAtaySqFLqCeRCbFmhHgVSi+pGeCipTpueefSkz2AX8Aj+9x27tqjBsX1LtNWVLDsinEhBWN68R+iEOmf/6jGWObQIDAQAB";
24      static final byte[] PUBLIC_KEY = Base64.decode(getBytes(BASE64_PUBLIC_KEY));
25      private static final String CHARSET = TrustedApplicationUtils.Constant.CHARSET_NAME;
26  
27      static byte[] getBytes(String input)
28      {
29          try
30          {
31              return input.getBytes(CHARSET);
32          }
33          catch (UnsupportedEncodingException e)
34          {
35              throw new AssertionError(e);
36          }
37      }
38  
39      static String getString(byte[] bytes)
40      {
41          try
42          {
43              return new String(bytes, CHARSET);
44          }
45          catch (UnsupportedEncodingException e)
46          {
47              throw new AssertionError(e);
48          }
49      }
50  
51      @Test
52      public void testProtocolVersion0() throws Exception
53      {
54          final String cert = "appId:11112222\n" + BASE64_PUBLIC_KEY;
55          EncryptionProvider provider = mock(EncryptionProvider.class);
56          when(provider.toPublicKey(Mockito.<byte[]>anyObject())).thenReturn(new MockKey());
57          final Application app = new ReaderApplicationRetriever(new StringReader(cert), provider).getApplication();
58          assertEquals("appId:11112222", app.getID());
59          assertNotNull(app.getPublicKey());
60          verify(provider).toPublicKey(PUBLIC_KEY);
61      }
62  
63      @Test
64      public void testProtocolVersion1() throws Exception
65      {
66          final String cert = "appId:11112222\n" + BASE64_PUBLIC_KEY + "\n" + TrustedApplicationUtils.Constant.VERSION + "\n" + TrustedApplicationUtils.Constant.MAGIC;
67          EncryptionProvider provider = mock(EncryptionProvider.class);
68          when(provider.toPublicKey(Mockito.<byte[]>anyObject())).thenReturn(new MockKey());
69          final Application app = new ReaderApplicationRetriever(new StringReader(cert), provider).getApplication();
70          assertEquals("appId:11112222", app.getID());
71          assertNotNull(app.getPublicKey());
72          verify(provider).toPublicKey(PUBLIC_KEY);
73      }
74  
75      @Test(expected = InvalidApplicationDetailsException.class)
76      public void testProtocolVersion1BadMagic() throws Exception
77      {
78          final String cert = "appId:11112222\n" + BASE64_PUBLIC_KEY + "\n" + TrustedApplicationUtils.Constant.VERSION + "\n" + TrustedApplicationUtils.Constant.MAGIC + "123";
79          EncryptionProvider provider = mock(EncryptionProvider.class);
80          final ApplicationRetriever retriever = new ReaderApplicationRetriever(new StringReader(cert), provider);
81          
82          retriever.getApplication();
83      }
84  
85      @Test
86      public void testBadReaderThrowsCtorException() throws Exception
87      {
88          Reader reader = new Reader()
89          {
90              public void close() throws IOException
91              {
92              }
93  
94              public int read(char[] cbuf, int off, int len) throws IOException
95              {
96                  throw new IOException("bad reader");
97              }
98          };
99          try
100         {
101             new ReaderApplicationRetriever(reader, mock(EncryptionProvider.class));
102             fail("Should have thrown RuntimeException");
103         }
104         catch (RuntimeException yay)
105         {
106             assertEquals("java.io.IOException: bad reader", yay.getMessage());
107         }
108     }
109 }