Store license check user info
这个提交包含在:
父节点
d5b8f03996
当前提交
4f59fead0a
@ -2,6 +2,7 @@ package com.xuqm.license.controller;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAlias;
|
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.xuqm.common.model.ApiResponse;
|
import com.xuqm.common.model.ApiResponse;
|
||||||
import com.xuqm.license.service.DeviceService;
|
import com.xuqm.license.service.DeviceService;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@ -32,7 +33,8 @@ public class LicensePublicController {
|
|||||||
req.deviceName(),
|
req.deviceName(),
|
||||||
req.deviceModel(),
|
req.deviceModel(),
|
||||||
req.deviceVendor(),
|
req.deviceVendor(),
|
||||||
req.osVersion());
|
req.osVersion(),
|
||||||
|
req.userInfo());
|
||||||
Map<String, Object> data = new java.util.LinkedHashMap<>();
|
Map<String, Object> data = new java.util.LinkedHashMap<>();
|
||||||
data.put("success", result.success());
|
data.put("success", result.success());
|
||||||
data.put("token", result.token());
|
data.put("token", result.token());
|
||||||
@ -44,7 +46,7 @@ public class LicensePublicController {
|
|||||||
|
|
||||||
@PostMapping("/verify")
|
@PostMapping("/verify")
|
||||||
public ResponseEntity<ApiResponse<Map<String, Object>>> verify(@Valid @RequestBody VerifyRequest req) {
|
public ResponseEntity<ApiResponse<Map<String, Object>>> verify(@Valid @RequestBody VerifyRequest req) {
|
||||||
DeviceService.VerifyResult result = deviceService.verify(req.companyId(), req.deviceId(), req.token());
|
DeviceService.VerifyResult result = deviceService.verify(req.companyId(), req.deviceId(), req.token(), req.userInfo());
|
||||||
Map<String, Object> data = new java.util.LinkedHashMap<>();
|
Map<String, Object> data = new java.util.LinkedHashMap<>();
|
||||||
data.put("valid", result.valid());
|
data.put("valid", result.valid());
|
||||||
if (result.error() != null) {
|
if (result.error() != null) {
|
||||||
@ -59,12 +61,14 @@ public class LicensePublicController {
|
|||||||
@JsonProperty("deviceName") @JsonAlias("device_name") String deviceName,
|
@JsonProperty("deviceName") @JsonAlias("device_name") String deviceName,
|
||||||
@JsonProperty("deviceModel") @JsonAlias("device_model") String deviceModel,
|
@JsonProperty("deviceModel") @JsonAlias("device_model") String deviceModel,
|
||||||
@JsonProperty("deviceVendor") @JsonAlias("device_vendor") String deviceVendor,
|
@JsonProperty("deviceVendor") @JsonAlias("device_vendor") String deviceVendor,
|
||||||
@JsonProperty("osVersion") @JsonAlias("os_version") String osVersion
|
@JsonProperty("osVersion") @JsonAlias("os_version") String osVersion,
|
||||||
|
@JsonProperty("userInfo") @JsonAlias("user_info") JsonNode userInfo
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public record VerifyRequest(
|
public record VerifyRequest(
|
||||||
@NotBlank @JsonProperty("companyId") @JsonAlias("company_id") String companyId,
|
@NotBlank @JsonProperty("companyId") @JsonAlias("company_id") String companyId,
|
||||||
@NotBlank @JsonProperty("deviceId") @JsonAlias("device_id") String deviceId,
|
@NotBlank @JsonProperty("deviceId") @JsonAlias("device_id") String deviceId,
|
||||||
@NotBlank String token
|
@NotBlank String token,
|
||||||
|
@JsonProperty("userInfo") @JsonAlias("user_info") JsonNode userInfo
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,21 @@ public class DeviceEntity {
|
|||||||
@Column(name = "os_version", length = 255)
|
@Column(name = "os_version", length = 255)
|
||||||
private String osVersion;
|
private String osVersion;
|
||||||
|
|
||||||
|
@Column(name = "user_id", length = 255)
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Column(name = "user_name", length = 255)
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
@Column(name = "user_email", length = 255)
|
||||||
|
private String userEmail;
|
||||||
|
|
||||||
|
@Column(name = "user_phone", length = 64)
|
||||||
|
private String userPhone;
|
||||||
|
|
||||||
|
@Column(name = "user_info_json", columnDefinition = "TEXT")
|
||||||
|
private String userInfoJson;
|
||||||
|
|
||||||
@Column(nullable = false, name = "token_hash", length = 512)
|
@Column(nullable = false, name = "token_hash", length = 512)
|
||||||
private String tokenHash;
|
private String tokenHash;
|
||||||
|
|
||||||
@ -71,6 +86,21 @@ public class DeviceEntity {
|
|||||||
public String getOsVersion() { return osVersion; }
|
public String getOsVersion() { return osVersion; }
|
||||||
public void setOsVersion(String osVersion) { this.osVersion = osVersion; }
|
public void setOsVersion(String osVersion) { this.osVersion = osVersion; }
|
||||||
|
|
||||||
|
public String getUserId() { return userId; }
|
||||||
|
public void setUserId(String userId) { this.userId = userId; }
|
||||||
|
|
||||||
|
public String getUserName() { return userName; }
|
||||||
|
public void setUserName(String userName) { this.userName = userName; }
|
||||||
|
|
||||||
|
public String getUserEmail() { return userEmail; }
|
||||||
|
public void setUserEmail(String userEmail) { this.userEmail = userEmail; }
|
||||||
|
|
||||||
|
public String getUserPhone() { return userPhone; }
|
||||||
|
public void setUserPhone(String userPhone) { this.userPhone = userPhone; }
|
||||||
|
|
||||||
|
public String getUserInfoJson() { return userInfoJson; }
|
||||||
|
public void setUserInfoJson(String userInfoJson) { this.userInfoJson = userInfoJson; }
|
||||||
|
|
||||||
public String getTokenHash() { return tokenHash; }
|
public String getTokenHash() { return tokenHash; }
|
||||||
public void setTokenHash(String tokenHash) { this.tokenHash = tokenHash; }
|
public void setTokenHash(String tokenHash) { this.tokenHash = tokenHash; }
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package com.xuqm.license.service;
|
package com.xuqm.license.service;
|
||||||
|
|
||||||
import com.xuqm.common.exception.BusinessException;
|
import com.xuqm.common.exception.BusinessException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.xuqm.license.entity.CompanyEntity;
|
import com.xuqm.license.entity.CompanyEntity;
|
||||||
import com.xuqm.license.entity.DeviceEntity;
|
import com.xuqm.license.entity.DeviceEntity;
|
||||||
import com.xuqm.license.repository.DeviceRepository;
|
import com.xuqm.license.repository.DeviceRepository;
|
||||||
@ -22,11 +24,14 @@ public class DeviceService {
|
|||||||
private final DeviceRepository deviceRepository;
|
private final DeviceRepository deviceRepository;
|
||||||
private final CompanyService companyService;
|
private final CompanyService companyService;
|
||||||
private final LicenseAuthService licenseAuthService;
|
private final LicenseAuthService licenseAuthService;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
public DeviceService(DeviceRepository deviceRepository, CompanyService companyService, LicenseAuthService licenseAuthService) {
|
public DeviceService(DeviceRepository deviceRepository, CompanyService companyService,
|
||||||
|
LicenseAuthService licenseAuthService, ObjectMapper objectMapper) {
|
||||||
this.deviceRepository = deviceRepository;
|
this.deviceRepository = deviceRepository;
|
||||||
this.companyService = companyService;
|
this.companyService = companyService;
|
||||||
this.licenseAuthService = licenseAuthService;
|
this.licenseAuthService = licenseAuthService;
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<DeviceEntity> findByDeviceId(String deviceId) {
|
public Optional<DeviceEntity> findByDeviceId(String deviceId) {
|
||||||
@ -39,7 +44,8 @@ public class DeviceService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public RegisterResult register(String companyId, String deviceId, String deviceName,
|
public RegisterResult register(String companyId, String deviceId, String deviceName,
|
||||||
String deviceModel, String deviceVendor, String osVersion) {
|
String deviceModel, String deviceVendor, String osVersion,
|
||||||
|
JsonNode userInfo) {
|
||||||
// Check if device already registered
|
// Check if device already registered
|
||||||
Optional<DeviceEntity> existingOpt = findByDeviceId(deviceId);
|
Optional<DeviceEntity> existingOpt = findByDeviceId(deviceId);
|
||||||
if (existingOpt.isPresent()) {
|
if (existingOpt.isPresent()) {
|
||||||
@ -54,6 +60,7 @@ public class DeviceService {
|
|||||||
existing.setDeviceModel(firstNonBlank(deviceModel, existing.getDeviceModel()));
|
existing.setDeviceModel(firstNonBlank(deviceModel, existing.getDeviceModel()));
|
||||||
existing.setDeviceVendor(firstNonBlank(deviceVendor, existing.getDeviceVendor()));
|
existing.setDeviceVendor(firstNonBlank(deviceVendor, existing.getDeviceVendor()));
|
||||||
existing.setOsVersion(firstNonBlank(osVersion, existing.getOsVersion()));
|
existing.setOsVersion(firstNonBlank(osVersion, existing.getOsVersion()));
|
||||||
|
applyUserInfo(existing, userInfo);
|
||||||
existing.setTokenHash(tokenHash);
|
existing.setTokenHash(tokenHash);
|
||||||
existing.setLastVerifiedAt(LocalDateTime.now());
|
existing.setLastVerifiedAt(LocalDateTime.now());
|
||||||
existing.setUpdatedAt(LocalDateTime.now());
|
existing.setUpdatedAt(LocalDateTime.now());
|
||||||
@ -83,6 +90,7 @@ public class DeviceService {
|
|||||||
device.setDeviceModel(deviceModel);
|
device.setDeviceModel(deviceModel);
|
||||||
device.setDeviceVendor(deviceVendor);
|
device.setDeviceVendor(deviceVendor);
|
||||||
device.setOsVersion(osVersion);
|
device.setOsVersion(osVersion);
|
||||||
|
applyUserInfo(device, userInfo);
|
||||||
device.setTokenHash(tokenHash);
|
device.setTokenHash(tokenHash);
|
||||||
device.setRegisteredAt(LocalDateTime.now());
|
device.setRegisteredAt(LocalDateTime.now());
|
||||||
device.setIsActive(true);
|
device.setIsActive(true);
|
||||||
@ -96,7 +104,7 @@ public class DeviceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public VerifyResult verify(String companyId, String deviceId, String token) {
|
public VerifyResult verify(String companyId, String deviceId, String token, JsonNode userInfo) {
|
||||||
if (!licenseAuthService.verifyTokenPayload(token, companyId, deviceId)) {
|
if (!licenseAuthService.verifyTokenPayload(token, companyId, deviceId)) {
|
||||||
return new VerifyResult(false, "Token mismatch");
|
return new VerifyResult(false, "Token mismatch");
|
||||||
}
|
}
|
||||||
@ -116,6 +124,7 @@ public class DeviceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
device.setLastVerifiedAt(LocalDateTime.now());
|
device.setLastVerifiedAt(LocalDateTime.now());
|
||||||
|
applyUserInfo(device, userInfo);
|
||||||
device.setUpdatedAt(LocalDateTime.now());
|
device.setUpdatedAt(LocalDateTime.now());
|
||||||
deviceRepository.save(device);
|
deviceRepository.save(device);
|
||||||
|
|
||||||
@ -156,6 +165,26 @@ public class DeviceService {
|
|||||||
return value == null || value.isBlank() ? fallback : value;
|
return value == null || value.isBlank() ? fallback : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyUserInfo(DeviceEntity device, JsonNode userInfo) {
|
||||||
|
if (userInfo == null || userInfo.isNull() || !userInfo.isObject()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
device.setUserId(firstNonBlank(text(userInfo, "userId"), device.getUserId()));
|
||||||
|
device.setUserName(firstNonBlank(text(userInfo, "name"), device.getUserName()));
|
||||||
|
device.setUserEmail(firstNonBlank(text(userInfo, "email"), device.getUserEmail()));
|
||||||
|
device.setUserPhone(firstNonBlank(text(userInfo, "phone"), device.getUserPhone()));
|
||||||
|
try {
|
||||||
|
device.setUserInfoJson(objectMapper.writeValueAsString(userInfo));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
// Ignore malformed optional metadata and keep core license check available.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String text(JsonNode node, String field) {
|
||||||
|
JsonNode value = node.get(field);
|
||||||
|
return value == null || value.isNull() ? null : value.asText(null);
|
||||||
|
}
|
||||||
|
|
||||||
public record RegisterResult(boolean success, String token, String message) {}
|
public record RegisterResult(boolean success, String token, String message) {}
|
||||||
public record VerifyResult(boolean valid, String error) {}
|
public record VerifyResult(boolean valid, String error) {}
|
||||||
}
|
}
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户