Files
tianai-captcha-enhanced/tianai-captcha/src/main/java/cloud/tianai/captcha/site/SiteManager.java
T
abcv7 dbe9b58b0c feat: 增强版验证码全套实现 — 16种类型生成器/加密/风控/站点管理/平台后端/前端SDK/UI
- 核心新增: ICON_CLICK(PNG图标方案,预渲染资源)/SCRATCH/JIGSAW/CURVE_SLIDER(V1-V3)/ANGLE/CURVE_DRAW/WORD_ORDER_CLICK/PROOF_OF_WORK 等生成器
- 图标点选: classpath PNG 加载替代运行时字体渲染(Linux容器无emoji字体),提示条图作为 templateImage 返回前端
- 新增模块: crypto(AES+RSA)/obfuscator(背景乱序/噪声/扭曲)/risk(风控/IP黑名单/限流)/site(站点管理)/ml(轨迹规则引擎)
- 平台后端: 站点管理/验证码API(generate/verify/secondary-verify)/统计/ML轨迹学习
- 前端SDK: TPCaptcha兼容,支持全部新型号渲染与交互
- 工具: tools/icon-render 图标预渲染工具
2026-08-26 09:58:15 +08:00

84 lines
2.9 KiB
Java

package cloud.tianai.captcha.site;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class SiteManager {
private final ConcurrentHashMap<String, SiteConfig> sitesBySiteKey = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, SiteConfig> sitesBySiteId = new ConcurrentHashMap<>();
private final SecureRandom random = new SecureRandom();
public SiteConfig registerSite(String name, Set<String> domains, Set<String> allowedTypes) {
SiteConfig config = new SiteConfig();
config.setSiteId(generateId());
config.setSiteKey(generateKey());
config.setSecretKey(generateKey());
config.setName(name);
config.setDomains(domains);
config.setAllowedTypes(allowedTypes);
sitesBySiteKey.put(config.getSiteKey(), config);
sitesBySiteId.put(config.getSiteId(), config);
return config;
}
public SiteConfig getSiteBySiteKey(String siteKey) {
return sitesBySiteKey.get(siteKey);
}
public SiteConfig getSiteBySiteId(String siteId) {
return sitesBySiteId.get(siteId);
}
public boolean validateSiteKey(String siteKey, String domain) {
SiteConfig config = sitesBySiteKey.get(siteKey);
if (config == null || !config.isEnabled()) {
return false;
}
if (domain != null && config.getDomains() != null && !config.getDomains().isEmpty()) {
return config.getDomains().contains(domain) || config.getDomains().contains("*");
}
return true;
}
public boolean validateSecretKey(String siteKey, String secretKey) {
SiteConfig config = sitesBySiteKey.get(siteKey);
return config != null && config.getSecretKey().equals(secretKey);
}
public boolean isTypeAllowed(String siteKey, String type) {
SiteConfig config = sitesBySiteKey.get(siteKey);
if (config == null) return false;
if (config.getAllowedTypes() == null || config.getAllowedTypes().isEmpty()) return true;
return config.getAllowedTypes().contains(type);
}
public void removeSite(String siteKey) {
SiteConfig config = sitesBySiteKey.remove(siteKey);
if (config != null) {
sitesBySiteId.remove(config.getSiteId());
}
}
public Collection<SiteConfig> getAllSites() {
return Collections.unmodifiableCollection(sitesBySiteKey.values());
}
private String generateId() {
byte[] bytes = new byte[16];
random.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
private String generateKey() {
byte[] bytes = new byte[32];
random.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
}