1 17 package org.alfresco.repo.security.authentication; 18 19 import java.io.Serializable ; 20 import java.util.Date ; 21 import java.util.HashMap ; 22 import java.util.List ; 23 import java.util.Map ; 24 25 import net.sf.acegisecurity.GrantedAuthority; 26 import net.sf.acegisecurity.GrantedAuthorityImpl; 27 import net.sf.acegisecurity.UserDetails; 28 import net.sf.acegisecurity.providers.dao.User; 29 import net.sf.acegisecurity.providers.dao.UsernameNotFoundException; 30 import net.sf.acegisecurity.providers.encoding.PasswordEncoder; 31 32 import org.alfresco.error.AlfrescoRuntimeException; 33 import org.alfresco.model.ContentModel; 34 import org.alfresco.service.cmr.dictionary.DictionaryService; 35 import org.alfresco.service.cmr.repository.ChildAssociationRef; 36 import org.alfresco.service.cmr.repository.NodeRef; 37 import org.alfresco.service.cmr.repository.NodeService; 38 import org.alfresco.service.cmr.repository.StoreRef; 39 import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; 40 import org.alfresco.service.cmr.search.ResultSet; 41 import org.alfresco.service.cmr.search.ResultSetRow; 42 import org.alfresco.service.cmr.search.SearchParameters; 43 import org.alfresco.service.cmr.search.SearchService; 44 import org.alfresco.service.namespace.NamespacePrefixResolver; 45 import org.alfresco.service.namespace.QName; 46 import org.alfresco.service.namespace.RegexQNamePattern; 47 import org.springframework.dao.DataAccessException; 48 49 public class RepositoryAuthenticationDao implements MutableAuthenticationDao 50 { 51 private static final StoreRef STOREREF_USERS = new StoreRef("user", "alfrescoUserStore"); 52 53 private NodeService nodeService; 54 55 private NamespacePrefixResolver namespacePrefixResolver; 56 57 private DictionaryService dictionaryService; 58 59 private SearchService searchService; 60 61 private PasswordEncoder passwordEncoder; 62 63 private boolean userNamesAreCaseSensitive; 64 65 public boolean getUserNamesAreCaseSensitive() 66 { 67 return userNamesAreCaseSensitive; 68 } 69 70 public void setUserNamesAreCaseSensitive(boolean userNamesAreCaseSensitive) 71 { 72 this.userNamesAreCaseSensitive = userNamesAreCaseSensitive; 73 } 74 75 public void setDictionaryService(DictionaryService dictionaryService) 76 { 77 this.dictionaryService = dictionaryService; 78 } 79 80 public void setNamespaceService(NamespacePrefixResolver namespacePrefixResolver) 81 { 82 this.namespacePrefixResolver = namespacePrefixResolver; 83 } 84 85 public void setNodeService(NodeService nodeService) 86 { 87 this.nodeService = nodeService; 88 } 89 90 public void setPasswordEncoder(PasswordEncoder passwordEncoder) 91 { 92 this.passwordEncoder = passwordEncoder; 93 } 94 95 public void setSearchService(SearchService searchService) 96 { 97 this.searchService = searchService; 98 } 99 100 public UserDetails loadUserByUsername(String caseSensitiveUserName) throws UsernameNotFoundException, 101 DataAccessException 102 { 103 String userName = userNamesAreCaseSensitive ? caseSensitiveUserName : caseSensitiveUserName.toLowerCase(); 104 NodeRef userRef = getUserOrNull(userName); 105 if (userRef == null) 106 { 107 throw new UsernameNotFoundException("Could not find user by userName: " + caseSensitiveUserName); 108 } 109 110 Map <QName, Serializable > properties = nodeService.getProperties(userRef); 111 String password = DefaultTypeConverter.INSTANCE.convert(String .class, properties 112 .get(ContentModel.PROP_PASSWORD)); 113 114 GrantedAuthority[] gas = new GrantedAuthority[1]; 115 gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED"); 116 117 UserDetails ud = new User(userName, password, getEnabled(userRef), !getAccountHasExpired(userRef), 118 !getCredentialsHaveExpired(userRef), !getAccountlocked(userRef), gas); 119 return ud; 120 } 121 122 public NodeRef getUserOrNull(String caseSensitiveUserName) 123 { 124 String userName = userNamesAreCaseSensitive ? caseSensitiveUserName : caseSensitiveUserName.toLowerCase(); 125 SearchParameters sp = new SearchParameters(); 126 sp.setLanguage(SearchService.LANGUAGE_LUCENE); 127 sp.setQuery("@usr\\:username:" + userName); 128 sp.addStore(STOREREF_USERS); 129 sp.excludeDataInTheCurrentTransaction(false); 130 131 ResultSet rs = null; 132 133 try 134 { 135 rs = searchService.query(sp); 136 137 for (ResultSetRow row : rs) 138 { 139 140 NodeRef nodeRef = row.getNodeRef(); 141 if (nodeService.exists(nodeRef)) 142 { 143 String realUserName = DefaultTypeConverter.INSTANCE.convert(String .class, nodeService.getProperty( 144 nodeRef, ContentModel.PROP_USER_USERNAME)); 145 if (realUserName.equals(userName)) 146 { 147 return nodeRef; 148 } 149 } 150 } 151 } 152 finally 153 { 154 if (rs != null) 155 { 156 rs.close(); 157 } 158 } 159 160 return null; 161 } 162 163 public void createUser(String caseSensitiveUserName, char[] rawPassword) throws AuthenticationException 164 { 165 String userName = userNamesAreCaseSensitive ? caseSensitiveUserName : caseSensitiveUserName.toLowerCase(); 166 NodeRef userRef = getUserOrNull(userName); 167 if (userRef != null) 168 { 169 throw new AuthenticationException("User already exists: " + userName); 170 } 171 NodeRef typesNode = getUserFolderLocation(); 172 Map <QName, Serializable > properties = new HashMap <QName, Serializable >(); 173 properties.put(ContentModel.PROP_USER_USERNAME, userName); 174 String salt = null; properties.put(ContentModel.PROP_SALT, salt); 176 properties.put(ContentModel.PROP_PASSWORD, passwordEncoder.encodePassword(new String (rawPassword), salt)); 177 properties.put(ContentModel.PROP_ACCOUNT_EXPIRES, Boolean.valueOf(false)); 178 properties.put(ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(false)); 179 properties.put(ContentModel.PROP_ENABLED, Boolean.valueOf(true)); 180 properties.put(ContentModel.PROP_ACCOUNT_LOCKED, Boolean.valueOf(false)); 181 nodeService.createNode( 182 typesNode, 183 ContentModel.ASSOC_CHILDREN, 184 ContentModel.TYPE_USER, 185 ContentModel.TYPE_USER, 186 properties); 187 188 } 189 190 private NodeRef getUserFolderLocation() 191 { 192 QName qnameAssocSystem = QName.createQName("sys", "system", namespacePrefixResolver); 193 QName qnameAssocUsers = QName.createQName("sys", "people", namespacePrefixResolver); NodeRef rootNode = nodeService.getRootNode(STOREREF_USERS); 195 List <ChildAssociationRef> results = nodeService.getChildAssocs( 196 rootNode, 197 RegexQNamePattern.MATCH_ALL, 198 qnameAssocSystem); 199 NodeRef sysNodeRef = null; 200 if (results.size() == 0) 201 { 202 throw new AlfrescoRuntimeException("Required authority system folder path not found: " + qnameAssocSystem); 203 } 204 else 205 { 206 sysNodeRef = results.get(0).getChildRef(); 207 } 208 results = nodeService.getChildAssocs( 209 sysNodeRef, 210 RegexQNamePattern.MATCH_ALL, 211 qnameAssocUsers); 212 NodeRef userNodeRef = null; 213 if (results.size() == 0) 214 { 215 throw new AlfrescoRuntimeException("Required user folder path not found: " + qnameAssocUsers); 216 } 217 else 218 { 219 userNodeRef = results.get(0).getChildRef(); 220 } 221 return userNodeRef; 222 } 223 224 public void updateUser(String userName, char[] rawPassword) throws AuthenticationException 225 { 226 NodeRef userRef = getUserOrNull(userName); 227 if (userRef == null) 228 { 229 throw new AuthenticationException("User name does not exist: " + userName); 230 } 231 Map <QName, Serializable > properties = nodeService.getProperties(userRef); 232 String salt = null; properties.remove(ContentModel.PROP_SALT); 234 properties.put(ContentModel.PROP_SALT, salt); 235 properties.remove(ContentModel.PROP_PASSWORD); 236 properties.put(ContentModel.PROP_PASSWORD, passwordEncoder.encodePassword(new String (rawPassword), salt)); 237 nodeService.setProperties(userRef, properties); 238 } 239 240 public void deleteUser(String userName) throws AuthenticationException 241 { 242 NodeRef userRef = getUserOrNull(userName); 243 if (userRef == null) 244 { 245 throw new AuthenticationException("User name does not exist: " + userName); 246 } 247 nodeService.deleteNode(userRef); 248 } 249 250 public Object getSalt(UserDetails userDetails) 251 { 252 return null; 268 } 269 270 public boolean userExists(String userName) 271 { 272 return (getUserOrNull(userName) != null); 273 } 274 275 public boolean getAccountExpires(String userName) 276 { 277 NodeRef userNode = getUserOrNull(userName); 278 if (userNode == null) 279 { 280 return false; 281 } 282 Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRES); 283 if (ser == null) 284 { 285 return false; 286 } 287 else 288 { 289 return DefaultTypeConverter.INSTANCE.booleanValue(ser); 290 } 291 } 292 293 public Date getAccountExpiryDate(String userName) 294 { 295 NodeRef userNode = getUserOrNull(userName); 296 if (userNode == null) 297 { 298 return null; 299 } 300 if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, 301 ContentModel.PROP_ACCOUNT_EXPIRES))) 302 { 303 return DefaultTypeConverter.INSTANCE.convert(Date .class, nodeService.getProperty(userNode, 304 ContentModel.PROP_ACCOUNT_EXPIRY_DATE)); 305 } 306 else 307 { 308 return null; 309 } 310 } 311 312 public boolean getAccountHasExpired(String userName) 313 { 314 return getAccountHasExpired(getUserOrNull(userName)); 315 } 316 317 private boolean getAccountHasExpired(NodeRef userNode) 318 { 319 if (userNode == null) 320 { 321 return false; 322 } 323 if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, 324 ContentModel.PROP_ACCOUNT_EXPIRES))) 325 { 326 Date date = DefaultTypeConverter.INSTANCE.convert(Date .class, nodeService.getProperty(userNode, 327 ContentModel.PROP_ACCOUNT_EXPIRY_DATE)); 328 if (date == null) 329 { 330 return false; 331 } 332 else 333 { 334 return (date.compareTo(new Date ()) < 1); 335 } 336 } 337 else 338 { 339 return false; 340 } 341 } 342 343 public boolean getAccountlocked(String userName) 344 { 345 return getAccountlocked(getUserOrNull(userName)); 346 } 347 348 private boolean getAccountlocked(NodeRef userNode) 349 { 350 if (userNode == null) 351 { 352 return false; 353 } 354 Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_LOCKED); 355 if (ser == null) 356 { 357 return false; 358 } 359 else 360 { 361 return DefaultTypeConverter.INSTANCE.booleanValue(ser); 362 } 363 } 364 365 public boolean getCredentialsExpire(String userName) 366 { 367 return getCredentialsExpired(getUserOrNull(userName)); 368 } 369 370 private boolean getCredentialsExpired(NodeRef userNode) 371 { 372 if (userNode == null) 373 { 374 return false; 375 } 376 Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE); 377 if (ser == null) 378 { 379 return false; 380 } 381 else 382 { 383 return DefaultTypeConverter.INSTANCE.booleanValue(ser); 384 } 385 } 386 387 public Date getCredentialsExpiryDate(String userName) 388 { 389 NodeRef userNode = getUserOrNull(userName); 390 if (userNode == null) 391 { 392 return null; 393 } 394 if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, 395 ContentModel.PROP_CREDENTIALS_EXPIRE))) 396 { 397 return DefaultTypeConverter.INSTANCE.convert(Date .class, nodeService.getProperty(userNode, 398 ContentModel.PROP_CREDENTIALS_EXPIRY_DATE)); 399 } 400 else 401 { 402 return null; 403 } 404 } 405 406 public boolean getCredentialsHaveExpired(String userName) 407 { 408 return getCredentialsHaveExpired(getUserOrNull(userName)); 409 } 410 411 private boolean getCredentialsHaveExpired(NodeRef userNode) 412 { 413 if (userNode == null) 414 { 415 return false; 416 } 417 if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, 418 ContentModel.PROP_CREDENTIALS_EXPIRE))) 419 { 420 Date date = DefaultTypeConverter.INSTANCE.convert(Date .class, nodeService.getProperty(userNode, 421 ContentModel.PROP_CREDENTIALS_EXPIRY_DATE)); 422 if (date == null) 423 { 424 return false; 425 } 426 else 427 { 428 return (date.compareTo(new Date ()) < 1); 429 } 430 } 431 else 432 { 433 return false; 434 } 435 } 436 437 public boolean getEnabled(String userName) 438 { 439 return getEnabled(getUserOrNull(userName)); 440 } 441 442 private boolean getEnabled(NodeRef userNode) 443 { 444 if (userNode == null) 445 { 446 return false; 447 } 448 Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_ENABLED); 449 if (ser == null) 450 { 451 return true; 452 } 453 else 454 { 455 return DefaultTypeConverter.INSTANCE.booleanValue(ser); 456 } 457 } 458 459 public void setAccountExpires(String userName, boolean expires) 460 { 461 NodeRef userNode = getUserOrNull(userName); 462 if (userNode == null) 463 { 464 throw new AuthenticationException("User not found: " + userName); 465 } 466 nodeService.setProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRES, Boolean.valueOf(expires)); 467 } 468 469 public void setAccountExpiryDate(String userName, Date exipryDate) 470 { 471 NodeRef userNode = getUserOrNull(userName); 472 if (userNode == null) 473 { 474 throw new AuthenticationException("User not found: " + userName); 475 } 476 nodeService.setProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRY_DATE, exipryDate); 477 478 } 479 480 public void setCredentialsExpire(String userName, boolean expires) 481 { 482 NodeRef userNode = getUserOrNull(userName); 483 if (userNode == null) 484 { 485 throw new AuthenticationException("User not found: " + userName); 486 } 487 nodeService.setProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(expires)); 488 } 489 490 public void setCredentialsExpiryDate(String userName, Date exipryDate) 491 { 492 NodeRef userNode = getUserOrNull(userName); 493 if (userNode == null) 494 { 495 throw new AuthenticationException("User not found: " + userName); 496 } 497 nodeService.setProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE, exipryDate); 498 499 } 500 501 public void setEnabled(String userName, boolean enabled) 502 { 503 NodeRef userNode = getUserOrNull(userName); 504 if (userNode == null) 505 { 506 throw new AuthenticationException("User not found: " + userName); 507 } 508 nodeService.setProperty(userNode, ContentModel.PROP_ENABLED, Boolean.valueOf(enabled)); 509 } 510 511 public void setLocked(String userName, boolean locked) 512 { 513 NodeRef userNode = getUserOrNull(userName); 514 if (userNode == null) 515 { 516 throw new AuthenticationException("User not found: " + userName); 517 } 518 nodeService.setProperty(userNode, ContentModel.PROP_ACCOUNT_LOCKED, Boolean.valueOf(locked)); 519 } 520 521 public String getMD4HashedPassword(String userName) 522 { 523 NodeRef userNode = getUserOrNull(userName); 524 if (userNode == null) 525 { 526 return null; 527 } 528 else 529 { 530 String password = DefaultTypeConverter.INSTANCE.convert(String .class, nodeService.getProperty(userNode, 531 ContentModel.PROP_PASSWORD)); 532 return password; 533 } 534 } 535 536 } 537 | Popular Tags |