package com.aperture_software.glados_wiki.shiro;
import com.aperture_software.glados_wiki.entities.Group;
import com.aperture_software.glados_wiki.entities.User;
import com.aperture_software.glados_wiki.services.GroupService;
import com.aperture_software.glados_wiki.services.UserService;
import com.aperture_software.glados_wiki.support.Sha256;
import com.google.common.base.Optional;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Created by jhyun on 13. 12. 24.
*/
@Component
public class MyRealm extends AuthorizingRealm implements InitializingBean {
private static Logger LOG = LoggerFactory.getLogger(MyRealm.class);
@Autowired
private UserService userService;
@Autowired
private GroupService groupService;
@Autowired
private AdminsAutoCreate adminsAutoCreate;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
final String u = ObjectUtils.toString(principals.getPrimaryPrincipal());
SimpleAuthorizationInfo a = new SimpleAuthorizationInfo();
//
Optional<User> u2 = userService.getByUsername(u);
if (u2.isPresent() == false) return null;
//
for (Group g : u2.get().getGroups()) {
if (g.isEnabled()) {
LOG.trace(String.format("principal [%s] ++ role [%s].", u, g.getName()));
if (groupService.existsByName(g.getName())) {
a.addRole(g.getName());
} else {
LOG.warn(String.format("group [%s] not found, skip.", g.getName()));
}
} else {
LOG.warn(String.format("SKIP role [%s] for user [%s]", g.getName(), u));
}
}
//
if (false == a.getRoles().contains(GroupService.EVERYONE_ROLE)) {
Optional<Group> gEveryone = groupService.getByName(GroupService.EVERYONE_ROLE);
if (gEveryone.isPresent()) {
a.addRole(gEveryone.get().getName());
} else {
LOG.warn(String.format("'EVERYONE' ROLE [%s] NOT FOUND! (IGNORED.)", GroupService.EVERYONE_ROLE));
}
}
//
return a;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
if (token instanceof UsernamePasswordToken) {
UsernamePasswordToken upt = (UsernamePasswordToken) token;
Optional<User> u = userService.getByUsername(upt.getUsername());
//
if (u.isPresent() == false) {
return null;
}
//
if (false == u.get().isEnabled()) {
// locked user, block.
return null;
}
//
User u2 = u.get();
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(u2.getUsername(),
u2.getPassword(), ByteSource.Util.bytes(u2.getPasswordSalt()), this.getName());
return authenticationInfo;
} else {
return null;
}
}
@Override
public void afterPropertiesSet() throws Exception {
HashedCredentialsMatcher cm = new HashedCredentialsMatcher(Sha256Hash.ALGORITHM_NAME);
cm.setStoredCredentialsHexEncoded(false);
cm.setHashIterations(Sha256.HASH_ITERATION);
//cm.setHashSalted(true);
this.setCredentialsMatcher(cm);
// auto-create group "admins" and user "admin".
adminsAutoCreate.run();
}
}