package com.aperture_software.glados_wiki.services;
import com.aperture_software.glados_wiki.config.WikiConfig;
import com.aperture_software.glados_wiki.entities.Group;
import com.aperture_software.glados_wiki.entities.Page;
import com.aperture_software.glados_wiki.entities.UserAuthentication;
import com.aperture_software.glados_wiki.entities.page_acl.DefaultAclPolicy;
import com.aperture_software.glados_wiki.exceptions.PageAclException;
import com.aperture_software.glados_wiki.support.SecurityUtils2;
import com.google.common.base.Optional;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* Created by jhyun on 14. 2. 7.
*/
@Service
public class PageAclService {
private static Logger LOG = LoggerFactory.getLogger(PageAclService.class);
@Autowired
private GroupService groupService;
@Autowired
private UserService userService;
@Autowired
private WikiConfig wikiConfig;
private boolean checkAcl(Set<UserAuthentication> myAuthentications, Set<UserAuthentication> targetAcls, boolean targetEveryone, boolean siteEveryone) {
if (myAuthentications != null && myAuthentications.size() > 0) {
Optional<Group> admins = groupService.getByName(GroupService.ADMIN_ROLE);
if (admins.isPresent()) {
if (myAuthentications.contains(admins.get())) {
//LOG.warn("ADMINS!!!");
return true;
}
}
}
//
if (targetAcls != null && targetAcls.size() > 0) {
return Sets.intersection(myAuthentications, targetAcls).size() > 0;
} else {
if (targetEveryone) return true;
if (siteEveryone) return true;
}
//
return false;
}
private Set<UserAuthentication> mergeUserAuthentications(Collection<UserAuthentication> a, Collection<UserAuthentication> b) {
HashSet<UserAuthentication> a_ = new HashSet<UserAuthentication>(a);
HashSet<UserAuthentication> b_ = new HashSet<UserAuthentication>(b);
return Sets.union(a_, b_);
}
private boolean isAny(final String s, final String... args) {
for (String a : args) {
if (ObjectUtils.equals(s, a)) {
return true;
}
}
return false;
}
private boolean checkAcl2(Set<UserAuthentication> allows, boolean isPageDefaultAcl, boolean isSiteDefaultAcl) {
Set<UserAuthentication> myAuths = SecurityUtils2.getUserAuthentications(userService);
return checkAcl(myAuths, allows, isPageDefaultAcl, isSiteDefaultAcl);
}
public boolean isReadable(Page page) {
return checkAcl2((page != null) ? mergeUserAuthentications(page.getReadables(), page.getWritables()) : new HashSet<UserAuthentication>(),
(page != null) ? isAny(page.getAclForEveryone(), DefaultAclPolicy.READ_ONLY, DefaultAclPolicy.READ_WRITE) : false,
isAny(wikiConfig.getDefaultAclForEveryone(), DefaultAclPolicy.READ_ONLY, DefaultAclPolicy.READ_WRITE));
}
public void checkReadable(Page page) throws PageAclException {
if (isReadable(page) == false) throw new PageAclException();
}
public boolean isWritable(Page page) {
return checkAcl2((page != null) ? new HashSet<UserAuthentication>(page.getWritables()) : new HashSet<UserAuthentication>(),
(page != null) ? isAny(page.getAclForEveryone(), DefaultAclPolicy.READ_WRITE) : false,
isAny(wikiConfig.getDefaultAclForEveryone(), DefaultAclPolicy.READ_WRITE));
}
public void checkWritable(Page page) throws PageAclException {
if (isWritable(page) == false) throw new PageAclException();
}
}