package com.ctrip.framework.apollo.openapi.service; import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.hash.Hashing; import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.openapi.entity.Consumer; import com.ctrip.framework.apollo.openapi.entity.ConsumerAudit; import com.ctrip.framework.apollo.openapi.entity.ConsumerRole; import com.ctrip.framework.apollo.openapi.entity.ConsumerToken; import com.ctrip.framework.apollo.openapi.repository.ConsumerAuditRepository; import com.ctrip.framework.apollo.openapi.repository.ConsumerRepository; import com.ctrip.framework.apollo.openapi.repository.ConsumerRoleRepository; import com.ctrip.framework.apollo.openapi.repository.ConsumerTokenRepository; import com.ctrip.framework.apollo.portal.component.config.PortalConfig; import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; import com.ctrip.framework.apollo.portal.entity.po.Role; import com.ctrip.framework.apollo.portal.service.RolePermissionService; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; import com.ctrip.framework.apollo.portal.spi.UserService; import com.ctrip.framework.apollo.portal.util.RoleUtils; import org.apache.commons.lang.time.FastDateFormat; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Arrays; import java.util.Date; import java.util.List; /** * @author Jason Song(song_s@ctrip.com) */ @Service public class ConsumerService { private static final FastDateFormat TIMESTAMP_FORMAT = FastDateFormat.getInstance("yyyyMMddHHmmss"); private static final Joiner KEY_JOINER = Joiner.on("|"); @Autowired private UserInfoHolder userInfoHolder; @Autowired private ConsumerTokenRepository consumerTokenRepository; @Autowired private ConsumerRepository consumerRepository; @Autowired private ConsumerAuditRepository consumerAuditRepository; @Autowired private ConsumerRoleRepository consumerRoleRepository; @Autowired private PortalConfig portalConfig; @Autowired private RolePermissionService rolePermissionService; @Autowired private UserService userService; public Consumer createConsumer(Consumer consumer) { String appId = consumer.getAppId(); Consumer managedConsumer = consumerRepository.findByAppId(appId); if (managedConsumer != null) { throw new BadRequestException("Consumer already exist"); } String ownerName = consumer.getOwnerName(); UserInfo owner = userService.findByUserId(ownerName); if (owner == null) { throw new BadRequestException(String.format("User does not exist. UserId = %s", ownerName)); } consumer.setOwnerEmail(owner.getEmail()); String operator = userInfoHolder.getUser().getUserId(); consumer.setDataChangeCreatedBy(operator); consumer.setDataChangeLastModifiedBy(operator); return consumerRepository.save(consumer); } public ConsumerToken generateAndSaveConsumerToken(Consumer consumer, Date expires) { Preconditions.checkArgument(consumer != null, "Consumer can not be null"); ConsumerToken consumerToken = generateConsumerToken(consumer, expires); consumerToken.setId(0); return consumerTokenRepository.save(consumerToken); } public ConsumerToken getConsumerTokenByAppId(String appId) { Consumer consumer = consumerRepository.findByAppId(appId); if (consumer == null) { return null; } return consumerTokenRepository.findByConsumerId(consumer.getId()); } public Long getConsumerIdByToken(String token) { if (Strings.isNullOrEmpty(token)) { return null; } ConsumerToken consumerToken = consumerTokenRepository.findTopByTokenAndExpiresAfter(token, new Date()); return consumerToken == null ? null : consumerToken.getConsumerId(); } public Consumer getConsumerByConsumerId(long consumerId) { return consumerRepository.findOne(consumerId); } @Transactional public List<ConsumerRole> assignNamespaceRoleToConsumer(String token, String appId, String namespaceName) { Long consumerId = getConsumerIdByToken(token); if (consumerId == null) { throw new BadRequestException("Token is Illegal"); } Role namespaceModifyRole = rolePermissionService.findRoleByRoleName(RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName)); Role namespaceReleaseRole = rolePermissionService.findRoleByRoleName(RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName)); if (namespaceModifyRole == null || namespaceReleaseRole == null) { throw new BadRequestException("Namespace's role does not exist. Please check whether namespace has created."); } long namespaceModifyRoleId = namespaceModifyRole.getId(); long namespaceReleaseRoleId = namespaceReleaseRole.getId(); ConsumerRole managedModifyRole = consumerRoleRepository.findByConsumerIdAndRoleId(consumerId, namespaceModifyRoleId); ConsumerRole managedReleaseRole = consumerRoleRepository.findByConsumerIdAndRoleId(consumerId, namespaceReleaseRoleId); if (managedModifyRole != null && managedReleaseRole != null) { return Arrays.asList(managedModifyRole, managedReleaseRole); } String operator = userInfoHolder.getUser().getUserId(); ConsumerRole namespaceModifyConsumerRole = createConsumerRole(consumerId, namespaceModifyRoleId, operator); ConsumerRole namespaceReleaseConsumerRole = createConsumerRole(consumerId, namespaceReleaseRoleId, operator); ConsumerRole createdModifyConsumerRole = consumerRoleRepository.save(namespaceModifyConsumerRole); ConsumerRole createdReleaseConsumerRole = consumerRoleRepository.save(namespaceReleaseConsumerRole); return Arrays.asList(createdModifyConsumerRole, createdReleaseConsumerRole); } @Transactional public ConsumerRole assignAppRoleToConsumer(String token, String appId) { Long consumerId = getConsumerIdByToken(token); if (consumerId == null) { throw new BadRequestException("Token is Illegal"); } Role masterRole = rolePermissionService.findRoleByRoleName(RoleUtils.buildAppMasterRoleName(appId)); if (masterRole == null) { throw new BadRequestException("App's role does not exist. Please check whether app has created."); } long roleId = masterRole.getId(); ConsumerRole managedModifyRole = consumerRoleRepository.findByConsumerIdAndRoleId(consumerId, roleId); if (managedModifyRole != null) { return managedModifyRole; } String operator = userInfoHolder.getUser().getUserId(); ConsumerRole consumerRole = createConsumerRole(consumerId, roleId, operator); return consumerRoleRepository.save(consumerRole); } @Transactional public void createConsumerAudits(Iterable<ConsumerAudit> consumerAudits) { consumerAuditRepository.save(consumerAudits); } @Transactional public ConsumerToken createConsumerToken(ConsumerToken entity) { entity.setId(0); //for protection return consumerTokenRepository.save(entity); } private ConsumerToken generateConsumerToken(Consumer consumer, Date expires) { long consumerId = consumer.getId(); String createdBy = userInfoHolder.getUser().getUserId(); Date createdTime = new Date(); ConsumerToken consumerToken = new ConsumerToken(); consumerToken.setConsumerId(consumerId); consumerToken.setExpires(expires); consumerToken.setDataChangeCreatedBy(createdBy); consumerToken.setDataChangeCreatedTime(createdTime); consumerToken.setDataChangeLastModifiedBy(createdBy); consumerToken.setDataChangeLastModifiedTime(createdTime); generateAndEnrichToken(consumer, consumerToken); return consumerToken; } void generateAndEnrichToken(Consumer consumer, ConsumerToken consumerToken) { Preconditions.checkArgument(consumer != null); if (consumerToken.getDataChangeCreatedTime() == null) { consumerToken.setDataChangeCreatedTime(new Date()); } consumerToken.setToken(generateToken(consumer.getAppId(), consumerToken .getDataChangeCreatedTime(), portalConfig.consumerTokenSalt())); } String generateToken(String consumerAppId, Date generationTime, String consumerTokenSalt) { return Hashing.sha1().hashString(KEY_JOINER.join(consumerAppId, TIMESTAMP_FORMAT.format (generationTime), consumerTokenSalt), Charsets.UTF_8).toString(); } ConsumerRole createConsumerRole(Long consumerId, Long roleId, String operator) { ConsumerRole consumerRole = new ConsumerRole(); consumerRole.setConsumerId(consumerId); consumerRole.setRoleId(roleId); consumerRole.setDataChangeCreatedBy(operator); consumerRole.setDataChangeLastModifiedBy(operator); return consumerRole; } }