1   package com.atlassian.user.impl.ldap.search.query;
2   
3   import com.atlassian.user.EntityException;
4   import com.atlassian.user.User;
5   import com.atlassian.user.UserManager;
6   import com.atlassian.user.impl.ldap.AbstractLdapTest;
7   import com.atlassian.user.impl.ldap.DefaultLDAPUserFactory;
8   import com.atlassian.user.impl.ldap.adaptor.LDAPGroupAdaptor;
9   import com.atlassian.user.impl.ldap.properties.LdapMembershipProperties;
10  import com.atlassian.user.impl.ldap.properties.LdapSearchProperties;
11  import com.atlassian.user.impl.ldap.repository.LdapContextFactory;
12  import com.atlassian.user.impl.ldap.search.LdapFilterFactory;
13  import com.atlassian.user.repository.RepositoryIdentifier;
14  import com.atlassian.user.search.SearchResult;
15  import com.atlassian.user.search.page.Pager;
16  import com.atlassian.user.search.page.PagerUtils;
17  import com.atlassian.user.search.query.BooleanQuery;
18  import com.atlassian.user.search.query.DefaultQueryContext;
19  import com.atlassian.user.search.query.EmailTermQuery;
20  import com.atlassian.user.search.query.EntityQueryParser;
21  import com.atlassian.user.search.query.FullNameTermQuery;
22  import com.atlassian.user.search.query.GroupNameTermQuery;
23  import com.atlassian.user.search.query.MultiTermBooleanQuery;
24  import com.atlassian.user.search.query.Query;
25  import com.atlassian.user.search.query.QueryContext;
26  import com.atlassian.user.search.query.TermQuery;
27  import com.atlassian.user.search.query.UserNameTermQuery;
28  
29  import java.util.List;
30  
31  /**
32   * NOTE - Membership queries will not work with substring matching on LDAP systems using groups objectClasses that
33   * specify a DN membership attribute. So, for now, we are not using or testing MembershipQueries.
34   */
35  public class TestLDAPEntityQueryParser extends AbstractLdapTest
36  {
37      private static final String USERNAME_1 = "user1";
38      private static final String USERNAME_2 = "user2";
39      private static final String GROUP_NAME_1 = "group1";
40  
41      private RepositoryIdentifier ldapIdentifier;
42      private LdapSearchProperties ldapSearchProperties;
43      private LdapMembershipProperties ldapMembershipProperties;
44      private LdapFilterFactory ldapFilterFactory;
45  
46      private LdapContextFactory ldapContextFactory;
47      private UserManager ldapUserManager;
48      private LDAPGroupAdaptor ldapGroupAdaptor;
49      private EntityQueryParser queryParser;
50      private DefaultQueryContext context;
51  
52      protected void onSetUp() throws Exception
53      {
54          super.onSetUp();
55  
56          queryParser = new LDAPEntityQueryParser(ldapContextFactory, ldapGroupAdaptor, ldapIdentifier,
57              new DefaultLDAPUserFactory(ldapSearchProperties), ldapSearchProperties,
58              ldapMembershipProperties, ldapFilterFactory);
59  
60          context = new DefaultQueryContext();
61          context.addRepositoryKey(ldapIdentifier.getKey());
62      }
63  
64  
65      protected void onTearDown() throws Exception
66      {
67          context = null;
68          queryParser = null;
69          super.onTearDown();
70      }
71  
72      public void testNoMatchingQueryContextNoSearch() throws EntityException
73      {
74          context = new DefaultQueryContext();
75          context.addRepositoryKey("dontrun");
76  
77          UserNameTermQuery query = new UserNameTermQuery(USERNAME_1);
78  
79          SearchResult searchResults = queryParser.findUsers(query, context);
80          assertNull("ldapEntityQueryParser is processing queries which are not meant for its repository",
81              searchResults);
82  
83          searchResults = queryParser.findGroups(query, context);
84          assertNull("ldapEntityQueryParser is processing queries which are not meant for its repository",
85              searchResults);
86  
87          context = new DefaultQueryContext();
88          context.addRepositoryKey(QueryContext.ALL_REPOSITORIES);
89  
90          searchResults = queryParser.findUsers(query, context);
91          assertNotNull("ldapEntityQueryParser is ignoring universal queries", searchResults);
92  
93          GroupNameTermQuery query2 = new GroupNameTermQuery(GROUP_NAME_1);
94  
95          context = new DefaultQueryContext();
96          context.addRepositoryKey(QueryContext.ALL_REPOSITORIES);
97  
98          searchResults = queryParser.findUsers(query2, context);
99          assertNotNull("ldapEntityQueryParser is ignoring universal queries", searchResults);
100     }
101 
102     public void testUserNameTermQuery() throws EntityException
103     {
104         UserNameTermQuery query = new UserNameTermQuery("user1");
105 
106         Pager pager = queryParser.findUsers(query, context).pager();
107 
108         assertEquals(PagerUtils.count(pager), 1);
109         List list = pager.getCurrentPage();
110         User u = (User) list.get(0);
111         User u2 = ldapUserManager.getUser("user1");
112         assertEquals(u2, u);
113 
114         UserNameTermQuery query2 = new UserNameTermQuery("user", TermQuery.SUBSTRING_STARTS_WITH);
115 
116         Pager iter2 = queryParser.findUsers(query2, context).pager();
117         Pager<String> allUsers = ldapUserManager.getUserNames();
118         assertEquals(PagerUtils.count(allUsers), PagerUtils.count(iter2));
119     }
120 
121     public void testParseSingleUserQuery() throws EntityException
122     {
123         UserNameTermQuery query = new UserNameTermQuery(USERNAME_1);
124         String finalQuery = "(" + ldapSearchProperties.getUsernameAttribute() + "=" + USERNAME_1 + ")";
125 
126         assertEquals("parserEntity is not rendering ldap query correctly",
127             finalQuery, ((LDAPEntityQueryParser) queryParser).parseQuery(query).toString());
128 
129         Pager iter = queryParser.findUsers(query, context).pager();
130         List list = PagerUtils.toList(iter);
131         assertEquals(1, list.size());
132         assertEquals(ldapUserManager.getUser(USERNAME_1), list.get(0));
133     }
134 
135     public void testParseSingleUserQuerySubstringMatch() throws EntityException
136     {
137         UserNameTermQuery query = new UserNameTermQuery("bob", TermQuery.SUBSTRING_STARTS_WITH);
138         String finalQuery = "(" + ldapSearchProperties.getUsernameAttribute() + "=" + "bob*)";
139 
140         assertEquals("parserEntity is not rendering ldap query correctly",
141             finalQuery, ((LDAPEntityQueryParser) queryParser).parseQuery(query).toString());
142 
143         query = new UserNameTermQuery("fred", TermQuery.SUBSTRING_ENDS_WITH);
144 
145         finalQuery = "(" + ldapSearchProperties.getUsernameAttribute() + "=" + "*fred)";
146 
147         assertEquals("parserEntity is not rendering ldap query correctly",
148             finalQuery, ((LDAPEntityQueryParser) queryParser).parseQuery(query).toString());
149 
150         query = new UserNameTermQuery("mary", TermQuery.SUBSTRING_CONTAINS);
151 
152         finalQuery = "(" + ldapSearchProperties.getUsernameAttribute() + "=" + "*mary*)";
153 
154         assertEquals("parserEntity is not rendering ldap query correctly",
155             finalQuery, ((LDAPEntityQueryParser) queryParser).parseQuery(query).toString());
156 
157         query = new UserNameTermQuery("user", TermQuery.SUBSTRING_STARTS_WITH);
158         Pager iter = queryParser.findUsers(query, context).pager();
159         List list = PagerUtils.toList(iter);
160 
161         assertEquals(8, list.size());
162     }
163 
164     public void testParseTwoUserORQuery() throws EntityException
165     {
166         UserNameTermQuery query1 = new UserNameTermQuery(USERNAME_1);
167         UserNameTermQuery query2 = new UserNameTermQuery(USERNAME_2);
168 
169         BooleanQuery query = new MultiTermBooleanQuery(new Query[]{query1, query2}, false);
170 
171         String finalQuery = "(|(" + ldapSearchProperties.getUsernameAttribute() + "=" + USERNAME_1 + ")"
172             + "(" + ldapSearchProperties.getUsernameAttribute() + "=" + USERNAME_2 + "))";
173 
174         assertEquals("parserEntity is not rendering ldap query correctly",
175             finalQuery, ((LDAPEntityQueryParser) queryParser).parseQuery(query).toString());
176 
177         Pager iter = queryParser.findUsers(query, context).pager();
178         List list = PagerUtils.toList(iter);
179 
180         assertEquals(2, list.size());
181 
182         boolean ldapuseraFound = false;
183         boolean ldapuserbFound = false;
184 
185         for (int i = 0; i < list.size(); i++)
186         {
187             User u = (User) list.get(i);
188 
189             if (!ldapuseraFound)
190             {
191                 if (u.equals(ldapUserManager.getUser(USERNAME_1)))
192                 {
193                     ldapuseraFound = true;
194                 }
195 
196                 continue;
197             }
198 
199             if (!ldapuserbFound && u.equals(ldapUserManager.getUser(USERNAME_2)))
200             {
201                 ldapuserbFound = true;
202             }
203         }
204 
205         assertTrue(ldapuseraFound);
206         assertTrue(ldapuserbFound);
207     }
208 
209     public void testFullNameTermQuery() throws Exception
210     {
211         FullNameTermQuery query = new FullNameTermQuery("sn1");
212 
213         String finalQuery = "(|(" + ldapSearchProperties.getFirstnameAttribute() + "=" + "sn1" + ")(" +
214             ldapSearchProperties.getSurnameAttribute() + "=" + "sn1" + "))";
215 
216         assertEquals("parserEntity is not rendering ldap query correctly",
217             finalQuery, ((LDAPEntityQueryParser) queryParser).parseQuery(query).toString());
218 
219         Pager iter = queryParser.findUsers(query, context).pager();
220         List list = PagerUtils.toList(iter);
221         assertEquals(1, list.size());
222         assertEquals(ldapUserManager.getUser(USERNAME_1), list.get(0));
223     }
224 
225     public void testEmailTermQuery() throws EntityException
226     {
227         EmailTermQuery query = new EmailTermQuery("user1@example.com");
228 
229         String finalQuery = "(" + ldapSearchProperties.getEmailAttribute() + "=user1@example.com)";
230 
231         assertEquals("parserEntity is not rendering ldap query correctly",
232             finalQuery, ((LDAPEntityQueryParser) queryParser).parseQuery(query).toString());
233 
234         Pager iter = queryParser.findUsers(query, context).pager();
235         List list = PagerUtils.toList(iter);
236         assertEquals(1, list.size());
237         assertEquals(ldapUserManager.getUser(USERNAME_1), list.get(0));
238     }
239 
240     public void testEmailTermQuerySubstringMatching() throws EntityException
241     {
242         EmailTermQuery query = new EmailTermQuery("user1@", TermQuery.SUBSTRING_CONTAINS);
243 
244         String finalQuery = "(" + ldapSearchProperties.getEmailAttribute() + "=*user1@*)";
245 
246         assertEquals("parserEntity is not rendering ldap query correctly",
247             finalQuery, ((LDAPEntityQueryParser) queryParser).parseQuery(query).toString());
248 
249         Pager iter = queryParser.findUsers(query, context).pager();
250         List list = PagerUtils.toList(iter);
251         assertEquals(1, list.size());
252         assertEquals(ldapUserManager.getUser(USERNAME_1), list.get(0));
253     }
254 
255     protected String getLdapConfigLocation()
256     {
257         return "classpath:com/atlassian/user/impl/ldap/static/flat/ldapTestStaticFlatContext.xml";
258     }
259 
260     public void setLdapUserManager(UserManager ldapUserManager)
261     {
262         this.ldapUserManager = ldapUserManager;
263     }
264 
265     public void setLdapIdentifier(RepositoryIdentifier ldapIdentifier)
266     {
267         this.ldapIdentifier = ldapIdentifier;
268     }
269 
270     public void setLdapSearchProperties(LdapSearchProperties ldapSearchProperties)
271     {
272         this.ldapSearchProperties = ldapSearchProperties;
273     }
274 
275     public void setLdapGroupAdaptor(LDAPGroupAdaptor ldapGroupAdaptor)
276     {
277         this.ldapGroupAdaptor = ldapGroupAdaptor;
278     }
279 
280     public void setLdapContextFactory(LdapContextFactory ldapContextFactory)
281     {
282         this.ldapContextFactory = ldapContextFactory;
283     }
284 
285     public void setLdapMembershipProperties(LdapMembershipProperties ldapMembershipProperties)
286     {
287         this.ldapMembershipProperties = ldapMembershipProperties;
288     }
289 
290     public void setLdapFilterFactory(LdapFilterFactory ldapFilterFactory)
291     {
292         this.ldapFilterFactory = ldapFilterFactory;
293     }
294 }