|
@@ -0,0 +1,281 @@
|
|
|
+package cn.kdan.pdf.tech.core.service.impl;
|
|
|
+
|
|
|
+import cn.kdan.pdf.tech.core.constant.SSOConstant;
|
|
|
+import cn.kdan.pdf.tech.core.constant.VppTeamConstant;
|
|
|
+import cn.kdan.pdf.tech.core.enums.RoleEnum;
|
|
|
+import cn.kdan.pdf.tech.core.enums.ScpoeEnum;
|
|
|
+import cn.kdan.pdf.tech.core.enums.SyncStatusEnum;
|
|
|
+import cn.kdan.pdf.tech.core.enums.SyncUserEnum;
|
|
|
+import cn.kdan.pdf.tech.core.model.*;
|
|
|
+import cn.kdan.pdf.tech.core.pojo.MSGroup;
|
|
|
+import cn.kdan.pdf.tech.core.pojo.dto.AddSyncDTO;
|
|
|
+import cn.kdan.pdf.tech.core.pojo.dto.CreateTeamDTO;
|
|
|
+import cn.kdan.pdf.tech.core.pojo.vo.VppTeamMemberVO;
|
|
|
+import cn.kdan.pdf.tech.core.service.*;
|
|
|
+import com.azure.identity.ClientSecretCredential;
|
|
|
+import com.azure.identity.ClientSecretCredentialBuilder;
|
|
|
+import com.microsoft.graph.models.Group;
|
|
|
+import com.microsoft.graph.models.GroupCollectionResponse;
|
|
|
+import com.microsoft.graph.models.User;
|
|
|
+import com.microsoft.graph.models.UserCollectionResponse;
|
|
|
+import com.microsoft.graph.serviceclient.GraphServiceClient;
|
|
|
+
|
|
|
+import enums.ValidStatusEnum;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.util.ObjectUtils;
|
|
|
+import utils.CommonUtils;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+@Transactional
|
|
|
+public class SyncServiceImpl implements SyncService {
|
|
|
+ @Resource
|
|
|
+ private DirectoryService directoryService;
|
|
|
+ @Resource
|
|
|
+ private VppMemberService vppMemberService;
|
|
|
+ @Resource
|
|
|
+ private VppTeamService teamService;
|
|
|
+ @Resource
|
|
|
+ private VppRTeamMemberRoleService vppRTeamMemberRoleService;
|
|
|
+ @Resource
|
|
|
+ private DirectorySyncService directorySyncService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addSyncSettings(AddSyncDTO syncDTO) {
|
|
|
+ //根据id获取目录
|
|
|
+ Directory directory = directoryService.getById(syncDTO.getDirectoryId());
|
|
|
+ //修改数据库
|
|
|
+ directory.setApplicationId(syncDTO.getApplicationID());
|
|
|
+ directory.setClientSecrets(syncDTO.getClientSecrets());
|
|
|
+ directory.setScope(syncDTO.getScope());
|
|
|
+ directory.setTenantId(syncDTO.getTenantId());
|
|
|
+ directory.setUpdateTime(new Date());
|
|
|
+ if (CollectionUtils.isEmpty(syncDTO.getGroupIds())) {
|
|
|
+ directory.setMsGroupIds(listToString(syncDTO.getGroupIds()));
|
|
|
+ }
|
|
|
+ directoryService.updateSelective(directory);
|
|
|
+ //创建一个目录的默认团队,判断是否有默认团队了
|
|
|
+ String teamId = directory.getTeamId();
|
|
|
+ VppTeam team = teamService.getById(teamId);
|
|
|
+ if (ObjectUtils.isEmpty(team)) {
|
|
|
+ //没有团队则先创建默认团队
|
|
|
+ teamId = CommonUtils.generateId();
|
|
|
+ CreateTeamDTO dto = new CreateTeamDTO();
|
|
|
+ dto.setTeamName(directory.getName());
|
|
|
+ dto.setTeamDescription("sync");
|
|
|
+ dto.setProductList(syncDTO.getProductList());
|
|
|
+ dto.setTeamId(teamId);
|
|
|
+ //创建团队
|
|
|
+ teamService.createTeam(dto);
|
|
|
+ //绑定目录和团队
|
|
|
+ directory.setTeamId(teamId);
|
|
|
+ directoryService.updateSelective(directory);
|
|
|
+ }
|
|
|
+ String syncId = startLog(directory);
|
|
|
+ if (syncDTO.getScope().equals(ScpoeEnum.ALL.value())) {
|
|
|
+ //同步全部
|
|
|
+ syncMSUserAll(directory);
|
|
|
+ }
|
|
|
+ if (syncDTO.getScope().equals(ScpoeEnum.SPECIFY.value())) {
|
|
|
+ //同步特定
|
|
|
+ syncMSUserSpecifyGroup(directory);
|
|
|
+ }
|
|
|
+ endLog(syncId);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void startSync(String directoryId) {
|
|
|
+ //根据id获取目录
|
|
|
+ Directory directory = directoryService.getById(directoryId);
|
|
|
+ //修改数据库
|
|
|
+ directory.setApplicationId(directory.getApplicationId());
|
|
|
+ directory.setClientSecrets(directory.getClientSecrets());
|
|
|
+ directory.setScope(directory.getScope());
|
|
|
+ directory.setTenantId(directory.getTenantId());
|
|
|
+ directory.setUpdateTime(new Date());
|
|
|
+ directoryService.updateSelective(directory);
|
|
|
+ //创建一个目录的默认团队,判断是否有默认团队了
|
|
|
+ String teamId = directory.getTeamId();
|
|
|
+ VppTeam team = teamService.getById(teamId);
|
|
|
+ if (ObjectUtils.isEmpty(team)) {
|
|
|
+ log.error("TEAM_NOT_EXIST:{}", teamId);
|
|
|
+ throw new RuntimeException(VppTeamConstant.TEAM_NOT_EXIST);
|
|
|
+ }
|
|
|
+ String syncId = startLog(directory);
|
|
|
+ if (directory.getScope().equals(ScpoeEnum.ALL.value())) {
|
|
|
+ //同步全部
|
|
|
+ syncMSUserAll(directory);
|
|
|
+ }
|
|
|
+ if (directory.getScope().equals(ScpoeEnum.SPECIFY.value())) {
|
|
|
+ //同步特定
|
|
|
+ syncMSUserSpecifyGroup(directory);
|
|
|
+ }
|
|
|
+ endLog(syncId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步MS用户同步所有
|
|
|
+ *
|
|
|
+ * @param directory 目录对象
|
|
|
+ */
|
|
|
+ public void syncMSUserAll(Directory directory) {
|
|
|
+ String companyId = directory.getCompanyId();
|
|
|
+ String teamId = directory.getTeamId();
|
|
|
+ final String[] scopes = new String[]{SSOConstant.GRAPH_SCOPE};
|
|
|
+ final ClientSecretCredential credential = new ClientSecretCredentialBuilder()
|
|
|
+ .clientId(directory.getApplicationId())
|
|
|
+ .tenantId(directory.getTenantId())
|
|
|
+ .clientSecret(directory.getClientSecrets())
|
|
|
+ .build();
|
|
|
+ final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
|
|
|
+
|
|
|
+ UserCollectionResponse userResponse = graphClient.users().get();
|
|
|
+ List<User> users = userResponse.getValue();
|
|
|
+ List<String> microsoftEmails = users.stream().map(User::getUserPrincipalName).collect(Collectors.toList());
|
|
|
+
|
|
|
+ handleUsersData(users, microsoftEmails, companyId, teamId);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void endLog(String syncId) {
|
|
|
+ DirectorySync directorySync = new DirectorySync();
|
|
|
+ directorySync.setStatus(SyncStatusEnum.SYNC_FINISHED.value());
|
|
|
+ directorySync.setSyncTime(new Date());
|
|
|
+ directorySync.setDirectorySyncId(syncId);
|
|
|
+ directorySyncService.create(directorySync);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String startLog(Directory directory) {
|
|
|
+ DirectorySync directorySync = new DirectorySync();
|
|
|
+ String syncId = CommonUtils.generateId();
|
|
|
+ directorySync.setDirectoryId(directory.getDirectoryId());
|
|
|
+ directorySync.setStatus(SyncStatusEnum.SYNC_ING.value());
|
|
|
+ directorySync.setSyncTime(new Date());
|
|
|
+ directorySync.setDirectorySyncId(CommonUtils.generateId());
|
|
|
+ directorySyncService.create(directorySync);
|
|
|
+ return syncId;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步MS用户同步特定
|
|
|
+ *
|
|
|
+ * @param directory 目录对象
|
|
|
+ */
|
|
|
+ public void syncMSUserSpecifyGroup(Directory directory) {
|
|
|
+ String companyId = directory.getCompanyId();
|
|
|
+ String teamId = directory.getTeamId();
|
|
|
+ List<String> groupIds = stringToList(directory.getMsGroupIds());
|
|
|
+ final String[] scopes = new String[]{SSOConstant.GRAPH_SCOPE};
|
|
|
+ final ClientSecretCredential credential = new ClientSecretCredentialBuilder()
|
|
|
+ .clientId(directory.getApplicationId())
|
|
|
+ .tenantId(directory.getTenantId())
|
|
|
+ .clientSecret(directory.getClientSecrets())
|
|
|
+ .build();
|
|
|
+ final GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
|
|
|
+
|
|
|
+ List<User> users = new ArrayList<>();
|
|
|
+ groupIds.forEach(groupId -> {
|
|
|
+ Group group = graphClient.groups().byGroupId(groupId).get(requestConfiguration -> {
|
|
|
+ requestConfiguration.queryParameters.expand = new String[]{"members"};
|
|
|
+ });
|
|
|
+ group.getMembers().forEach(member -> {
|
|
|
+ if (member instanceof User) {
|
|
|
+ users.add((User) member);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ List<String> microsoftEmails = users.stream().map(User::getUserPrincipalName).collect(Collectors.toList());
|
|
|
+
|
|
|
+ handleUsersData(users, microsoftEmails, companyId, teamId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对比微软用户和我们指定组用户的差别,进行同步
|
|
|
+ *
|
|
|
+ * @param users users
|
|
|
+ * @param microsoftEmails microsoftEmails
|
|
|
+ * @param companyId companyId
|
|
|
+ * @param teamId teamId
|
|
|
+ */
|
|
|
+ private void handleUsersData(List<User> users, List<String> microsoftEmails, String companyId, String teamId) {
|
|
|
+ for (User user : users) {
|
|
|
+ String email = user.getUserPrincipalName();
|
|
|
+ String name = user.getDisplayName();
|
|
|
+ String id = user.getId();
|
|
|
+
|
|
|
+ VppMember member = vppMemberService.getByAccount(email);
|
|
|
+
|
|
|
+ if (ObjectUtils.isEmpty(member)) {
|
|
|
+ VppMember newMember = new VppMember().withId(id)
|
|
|
+ .withFullName(name)
|
|
|
+ .withEmail(email)
|
|
|
+ .withValidFlag(ValidStatusEnum.VALID.value())
|
|
|
+ .withCreatedAt(new Date())
|
|
|
+ .withUpdatedAt(new Date())
|
|
|
+ .withSubscriberType(0)
|
|
|
+ .withRole(RoleEnum.TEAM_MEMBER.code())
|
|
|
+ .withIsSso(SyncUserEnum.SSO.value())
|
|
|
+ .withCompanyId(companyId);
|
|
|
+ vppMemberService.insert(newMember);
|
|
|
+
|
|
|
+ VppRTeamMemberRole vppRTeamMemberRole = new VppRTeamMemberRole()
|
|
|
+ .withMemberId(id)
|
|
|
+ .withRoleId(RoleEnum.TEAM_MEMBER.code())
|
|
|
+ .withTeamId(teamId)
|
|
|
+ .withId(CommonUtils.generateId());
|
|
|
+ vppRTeamMemberRoleService.create(vppRTeamMemberRole);
|
|
|
+ } else {
|
|
|
+ member.setFullName(name);
|
|
|
+ vppMemberService.update(member);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ List<VppTeamMemberVO> localMembers = vppRTeamMemberRoleService.listForMember(teamId, RoleEnum.TEAM_MEMBER.code(), null, null, "1");
|
|
|
+ localMembers.stream()
|
|
|
+ .filter(member -> !microsoftEmails.contains(member.getEmail()))
|
|
|
+ .forEach(member -> vppRTeamMemberRoleService.deleteMember(member.getId()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MSGroup> getGroupList(String clientId, String tenantId, String clientSecret) {
|
|
|
+ String[] scopes = new String[]{SSOConstant.GRAPH_SCOPE};
|
|
|
+ ClientSecretCredential credential = new ClientSecretCredentialBuilder()
|
|
|
+ .clientId(clientId).tenantId(tenantId).clientSecret(clientSecret).build();
|
|
|
+ GraphServiceClient graphClient = new GraphServiceClient(credential, scopes);
|
|
|
+ try {
|
|
|
+ GroupCollectionResponse groupResponse = graphClient.groups().get();
|
|
|
+ List<Group> groups = groupResponse.getValue();
|
|
|
+ List<MSGroup> msGroups = new ArrayList<>();
|
|
|
+ groups.forEach(group -> {
|
|
|
+ String name = group.getDisplayName();
|
|
|
+ String id = group.getId();
|
|
|
+ MSGroup msGroup = new MSGroup();
|
|
|
+ msGroup.setId(id);
|
|
|
+ msGroup.setDisplayName(name);
|
|
|
+ msGroups.add(msGroup);
|
|
|
+ });
|
|
|
+ return msGroups;
|
|
|
+ } catch (Exception e) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public String listToString(List<String> stringList) {
|
|
|
+ return String.join(",", stringList);
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<String> stringToList(String str) {
|
|
|
+ return Arrays.asList(str.split(","));
|
|
|
+ }
|
|
|
+
|
|
|
+}
|