1   /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.providers.encoding;
17  
18  import junit.framework.TestCase;
19  
20  import org.springframework.dao.DataAccessException;
21  
22  
23  /**
24   * <p>TestCase for BasePasswordEncoder.</p>
25   *
26   * @author Ben Alex
27   * @version $Id: BasePasswordEncoderTests.java 1496 2006-05-23 13:38:33Z benalex $
28   */
29  public class BasePasswordEncoderTests extends TestCase {
30      //~ Methods ========================================================================================================
31  
32      public void testDemergeHandlesEmptyAndNullSalts() {
33          MockPasswordEncoder pwd = new MockPasswordEncoder();
34  
35          String merged = pwd.nowMergePasswordAndSalt("password", null, true);
36  
37          String[] demerged = pwd.nowDemergePasswordAndSalt(merged);
38          assertEquals("password", demerged[0]);
39          assertEquals("", demerged[1]);
40  
41          merged = pwd.nowMergePasswordAndSalt("password", "", true);
42  
43          demerged = pwd.nowDemergePasswordAndSalt(merged);
44          assertEquals("password", demerged[0]);
45          assertEquals("", demerged[1]);
46      }
47  
48      public void testDemergeWithEmptyStringIsRejected() {
49          MockPasswordEncoder pwd = new MockPasswordEncoder();
50  
51          try {
52              pwd.nowDemergePasswordAndSalt("");
53              fail("Should have thrown IllegalArgumentException");
54          } catch (IllegalArgumentException expected) {
55              assertEquals("Cannot pass a null or empty String", expected.getMessage());
56          }
57      }
58  
59      public void testDemergeWithNullIsRejected() {
60          MockPasswordEncoder pwd = new MockPasswordEncoder();
61  
62          try {
63              pwd.nowDemergePasswordAndSalt(null);
64              fail("Should have thrown IllegalArgumentException");
65          } catch (IllegalArgumentException expected) {
66              assertEquals("Cannot pass a null or empty String", expected.getMessage());
67          }
68      }
69  
70      public void testMergeDemerge() {
71          MockPasswordEncoder pwd = new MockPasswordEncoder();
72  
73          String merged = pwd.nowMergePasswordAndSalt("password", "foo", true);
74          assertEquals("password{foo}", merged);
75  
76          String[] demerged = pwd.nowDemergePasswordAndSalt(merged);
77          assertEquals("password", demerged[0]);
78          assertEquals("foo", demerged[1]);
79      }
80  
81      public void testMergeDemergeWithDelimitersInPassword() {
82          MockPasswordEncoder pwd = new MockPasswordEncoder();
83  
84          String merged = pwd.nowMergePasswordAndSalt("p{ass{w{o}rd", "foo", true);
85          assertEquals("p{ass{w{o}rd{foo}", merged);
86  
87          String[] demerged = pwd.nowDemergePasswordAndSalt(merged);
88  
89          assertEquals("p{ass{w{o}rd", demerged[0]);
90          assertEquals("foo", demerged[1]);
91      }
92  
93      public void testMergeDemergeWithNullAsPassword() {
94          MockPasswordEncoder pwd = new MockPasswordEncoder();
95  
96          String merged = pwd.nowMergePasswordAndSalt(null, "foo", true);
97          assertEquals("{foo}", merged);
98  
99          String[] demerged = pwd.nowDemergePasswordAndSalt(merged);
100         assertEquals("", demerged[0]);
101         assertEquals("foo", demerged[1]);
102     }
103 
104     public void testStrictMergeRejectsDelimitersInSalt1() {
105         MockPasswordEncoder pwd = new MockPasswordEncoder();
106 
107         try {
108             pwd.nowMergePasswordAndSalt("password", "f{oo", true);
109             fail("Should have thrown IllegalArgumentException");
110         } catch (IllegalArgumentException expected) {
111             assertEquals("Cannot use { or } in salt.toString()", expected.getMessage());
112         }
113     }
114 
115     public void testStrictMergeRejectsDelimitersInSalt2() {
116         MockPasswordEncoder pwd = new MockPasswordEncoder();
117 
118         try {
119             pwd.nowMergePasswordAndSalt("password", "f}oo", true);
120             fail("Should have thrown IllegalArgumentException");
121         } catch (IllegalArgumentException expected) {
122             assertEquals("Cannot use { or } in salt.toString()", expected.getMessage());
123         }
124     }
125 
126     //~ Inner Classes ==================================================================================================
127 
128     private class MockPasswordEncoder extends BasePasswordEncoder {
129         public String encodePassword(String rawPass, Object salt)
130             throws DataAccessException {
131             throw new UnsupportedOperationException("mock method not implemented");
132         }
133 
134         public boolean isPasswordValid(String encPass, String rawPass, Object salt)
135             throws DataAccessException {
136             throw new UnsupportedOperationException("mock method not implemented");
137         }
138 
139         public String[] nowDemergePasswordAndSalt(String password) {
140             return demergePasswordAndSalt(password);
141         }
142 
143         public String nowMergePasswordAndSalt(String password, Object salt, boolean strict) {
144             return mergePasswordAndSalt(password, salt, strict);
145         }
146     }
147 }