package qunar.tc.qconfig.server.security; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.*; import com.google.common.io.CharSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import qunar.tc.qconfig.client.Configuration; import qunar.tc.qconfig.client.TypedConfig; import javax.annotation.PostConstruct; import java.io.IOException; import java.util.List; import java.util.Set; /** * @author zhenyu.nie created on 2016 2016/11/30 14:40 */ @Service public class NoTokenPermissionServiceImpl implements NoTokenPermissionService { private static final Logger logger = LoggerFactory.getLogger(NoTokenPermissionServiceImpl.class); private volatile NoTokenInfo noTokenInfo; @PostConstruct public void init() { TypedConfig<String> config = TypedConfig.get("no-token-info", TypedConfig.STRING_PARSER); config.current(); config.addListener(new Configuration.ConfigListener<String>() { @Override public void onLoad(String conf) { noTokenInfo = initNoTokenInfo(conf); logger.info("change no token info: {}", noTokenInfo); } }); } private static final Splitter ANGLE_SPLITTER = Splitter.on('>').omitEmptyStrings().trimResults(); private NoTokenInfo initNoTokenInfo(String conf) { if (Strings.isNullOrEmpty(conf)) { return new NoTokenInfo(ImmutableSet.<String>of(), ImmutableTable.<String, String, Object>of()); } List<String> lines; try { lines = CharSource.wrap(conf).readLines(); } catch (IOException e) { // not happen throw new RuntimeException(e); } Set<String> groups = Sets.newHashSet(); Table<String, String, Object> files = HashBasedTable.create(); for (String line : lines) { List<String> strs = ANGLE_SPLITTER.splitToList(line); if (strs.isEmpty()) { continue; } if (strs.size() == 1) { groups.add(strs.get(0)); } else if (strs.size() == 2) { files.put(strs.get(0), strs.get(1), Boolean.TRUE); } else { throw new IllegalArgumentException("can not parse no token info [" + line + "]"); } } return new NoTokenInfo(groups, files); } @Override public boolean hasPermission(String group, String dataId) { return noTokenInfo.hasPermission(group, dataId); } private static class NoTokenInfo { private final Set<String> groups; private final Table<String, String, Object> files; public NoTokenInfo(Set<String> groups, Table<String, String, Object> files) { this.groups = groups; this.files = files; } public boolean hasPermission(String group, String dataId) { return groups.contains(group) || files.contains(group, dataId); } @Override public String toString() { return "NoTokenInfo{" + "groups=" + groups + ", files=" + files + '}'; } } }