Created
August 27, 2017 13:18
-
-
Save dularion/c4b4fd9970bd6856766e3fd62561aa9f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package project | |
import grails.converters.JSON | |
import grails.plugin.springsecurity.SpringSecurityUtils | |
import grails.plugin.springsecurity.userdetails.GrailsUser | |
import grails.plugin.springsecurity.userdetails.GrailsUserDetailsService | |
import grails.plugin.springsecurity.userdetails.NoStackUsernameNotFoundException | |
import grails.transaction.Transactional | |
import org.apache.commons.logging.Log | |
import org.apache.commons.logging.LogFactory | |
import org.grails.web.json.JSONObject | |
import org.springframework.security.core.authority.SimpleGrantedAuthority | |
import org.springframework.security.core.userdetails.UserDetails | |
import org.springframework.security.core.userdetails.UsernameNotFoundException | |
class DaoLdapUserDetailsService implements GrailsUserDetailsService { | |
LdapConnectionService ldapConnectionService | |
protected final Log logger = LogFactory.getLog(getClass()); | |
private static ldapAccountEnabled = true | |
/** | |
* Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least | |
* one role, so we give a user with no granted roles this one which gets | |
* past that restriction but doesn't grant anything. | |
*/ | |
static final List NO_ROLES = [new SimpleGrantedAuthority(SpringSecurityUtils.NO_ROLE)] | |
UserDetails loadUserByUsername(String username, boolean loadRoles) | |
throws UsernameNotFoundException { | |
return loadUserByUsername(username) | |
} | |
@Transactional | |
def updateUserInfo(User user, ldapUser) { | |
user.nameShort = ldapUser['shortname'] | |
//etc | |
user.save(failOnError: true, flush: true) | |
logger.debug('updateUserInfo ' + user.nameShort) | |
UserInfo userInfo = UserInfo.findByUser(user) | |
if (!userInfo) { | |
return | |
} | |
user.nameLast = ldapUser['sn'] | |
user.importedId = ldapUser['uidNumber'] | |
user.nameShort = ldapUser['Nutzerkuerzel'] | |
if (user.nameLast != ldapUser['givenName']) { | |
user.nameFirst = ldapUser['givenName'] | |
} | |
user.enabled = !user.defaultTenant.deleted | |
user.deleted = user.defaultTenant.deleted | |
user.save(flush: true, failOnError: true) | |
userInfo.metaData = (ldapUser as JSON).toString() | |
userInfo.save(failOnError: true, flush: true) | |
} | |
@Transactional | |
/** | |
* fetchTenantsFromLdap | |
* @return results.tenants List<Tenant> | |
* @return results.default Tenant | |
* | |
*/ | |
Map fetchTenantsFromLdap(ldapUser) { | |
def result = [:] | |
result.tenants = [] | |
def ldapRights = ldapUser['Berechtigungen']?.split(',') | |
// logger.debug('berechtigung ' + ldapRights) | |
Tenant defaultTenant | |
ldapRights.each { | |
if (it.isNumber()) { | |
Tenant tenant = Tenant.findByExternalId(it) | |
if (tenant) { | |
result.tenants.push(tenant) | |
} else { | |
logger.error('TENANT not found by externalId for ldapRights it !!' + it) | |
} | |
} else { | |
def tenantId = it.toString().replace('!', '') | |
if (tenantId.isNumber()) { | |
result.default = Tenant.findByExternalId(tenantId) | |
result.tenants.push(result.default) | |
} | |
} | |
} | |
if (!result.default && result.tenants.size() > 0) { | |
result.default = result.tenants[0] | |
} | |
if (!result.default) { | |
logger.warn('no tenants found by Berechtigungen user: ' + ldapUser.uid + ' ldapRights: ' + ldapRights | |
+ ' fallback to LDAP DN') | |
} | |
if (!result.default) { | |
def msg = 'No tenant for user:' + ldapUser.uid + ' ldapRights: ' + ldapRights | |
logger.error(msg) | |
throw new Exception(msg) | |
} | |
result.tenants = result.tenants.unique() | |
return result | |
} | |
@Transactional | |
User createUserFromLdap(ldapUser) { | |
logger.debug('createUserFromLdap ' + ldapUser) | |
def tenantResult = fetchTenantsFromLdap(ldapUser) | |
User user = new User(ldapUser.uid, UUID.randomUUID().toString()) | |
user.nameLast = ldapUser['sn'] | |
user.importedId = ldapUser['uidNumber'] | |
user.nameShort = ldapUser['Nutzerkuerzel'] | |
if (user.nameLast != ldapUser['givenName']) { | |
user.nameFirst = ldapUser['givenName'] | |
} | |
// | |
user.defaultTenant = tenantResult.default | |
user.enabled = ldapAccountEnabled | |
user.save(failOnError: true, flush: true) | |
UserInfo userInfo = new UserInfo(metaData: (new JSONObject(ldapUser)).toString(), user: user) | |
userInfo.save(failOnError: true, flush: true) | |
//TODO: Berater or Onlineteam??? Berater soll es sein https://tackl.it/app/#/tackls?projectId=188&tenantId=6&filterId=120&tacklId=9990 | |
ShareRole defaultShareRole = ShareRole.findByNameOrId('Berater', 1) | |
tenantResult.tenants.each { Tenant tenant -> | |
Share share = new Share(user: user, shareRole: defaultShareRole) | |
share.setEntity(tenant) | |
share.save(failOnError: true, flush: true) | |
} | |
return user | |
} | |
/** | |
* | |
* @param username | |
* @return | |
* @throws UsernameNotFoundException | |
*/ | |
@Transactional(readOnly = false, noRollbackFor = [IllegalArgumentException, UsernameNotFoundException]) | |
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | |
def ldapUser = ldapConnectionService.loadUser(username) | |
User user | |
if (ldapUser) { | |
// user = User.findByImportedId(ldapUser.uidNumber) | |
user = User.findByUsername(ldapUser.uid) | |
} else { | |
user = User.findByUsername(username) | |
} | |
if (!user && ldapUser) { | |
user = createUserFromLdap(ldapUser) | |
return new GrailsUser(username, 'ldap_init', ldapAccountEnabled, | |
true, true, | |
true, NO_ROLES, user.id) | |
} | |
if (!user && !ldapUser){ | |
throw new NoStackUsernameNotFoundException() | |
} | |
if (user && ldapUser) { | |
updateUserInfo(user, ldapUser) | |
} | |
def roles = user.authorities | |
// or if you are using role groups: | |
// def roles = user.authorities.collect { it.authorities }.flatten().unique() | |
def authorities = roles.collect { | |
new SimpleGrantedAuthority(it.authority) | |
} | |
return new GrailsUser(user.username, user.password, user.enabled, | |
!user.accountExpired, !user.passwordExpired, | |
!user.accountLocked, authorities ?: NO_ROLES, user.id) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment