Skip to content

Commit

Permalink
Merge pull request apolloconfig#552 from lepdou/token
Browse files Browse the repository at this point in the history
apply consumer token and assign consumer role
  • Loading branch information
nobodyiam authored Feb 24, 2017
2 parents 07cb655 + b9d0d0a commit 8635fde
Show file tree
Hide file tree
Showing 13 changed files with 675 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@
* @author Jason Song([email protected])
*/
public interface ConsumerRepository extends PagingAndSortingRepository<Consumer, Long> {

Consumer findByAppId(String appId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ public interface ConsumerRoleRepository extends PagingAndSortingRepository<Consu
* find consumer roles by roleId
*/
List<ConsumerRole> findByRoleId(long roleId);

ConsumerRole findByConsumerIdAndRoleId(long consumerId, long roleId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ public interface ConsumerTokenRepository extends PagingAndSortingRepository<Cons
* @param validDate the date when the token is valid
*/
ConsumerToken findTopByTokenAndExpiresAfter(String token, Date validDate);

ConsumerToken findByConsumerId(Long consumerId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,63 +6,150 @@
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([email protected])
*/
@Service
public class ConsumerService {
static final String TOKEN_SALT_KEY = "consumer.token.salt";
private static final FastDateFormat TIMESTAMP_FORMAT = FastDateFormat.getInstance
("yyyyMMddHHmmss");

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());
new Date());
return consumerToken == null ? null : consumerToken.getConsumerId();
}

public Consumer getConsumerByConsumerId(long consumerId) {
return consumerRepository.findOne(consumerId);
}

public void generateAndEnrichConsumerToken(ConsumerToken consumerToken) {
Consumer consumer = getConsumerByConsumerId(consumerToken.getConsumerId());
@Transactional
public List<ConsumerRole> assignNamespaceRoleToConsumer(String token, String appId, String namespaceName) {
Long consumerId = getConsumerIdByToken(token);
if (consumerId == null) {
throw new BadRequestException("Token is Illegal");
}

Preconditions.checkState(consumer != null, String.format("Consumer with id: %d not found!",
consumerToken.getConsumerId()));
Role namespaceModifyRole =
rolePermissionService.findRoleByRoleName(RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName));
Role namespaceReleaseRole =
rolePermissionService.findRoleByRoleName(RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName));

if (consumerToken.getDataChangeCreatedTime() == null) {
consumerToken.setDataChangeCreatedTime(new Date());
if (namespaceModifyRole == null || namespaceReleaseRole == null) {
throw new BadRequestException("Namespace's role does not exist. Please check whether namespace has created.");
}
consumerToken.setToken(generateConsumerToken(consumer.getAppId(), consumerToken
.getDataChangeCreatedTime(), portalConfig.consumerTokenSalt()));

long namespaceModifyRoleId = namespaceModifyRole.getId();
long namespaceReleaseRoleId = namespaceReleaseRole.getId();

ConsumerRole managedModifyRole = consumerRoleRepository.findByConsumerIdAndRoleId(consumerId, namespaceModifyRoleId);
if (managedModifyRole != null) {
throw new BadRequestException("Namespace's role has assigned to consumer.");
}

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 void createConsumerAudits(Iterable<ConsumerAudit> consumerAudits) {
consumerAuditRepository.save(consumerAudits);
}

@Transactional
Expand All @@ -72,15 +159,50 @@ public ConsumerToken createConsumerToken(ConsumerToken entity) {
return consumerTokenRepository.save(entity);
}

@Transactional
public void createConsumerAudits(Iterable<ConsumerAudit> consumerAudits) {
consumerAuditRepository.save(consumerAudits);
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 generateConsumerToken(String consumerAppId, Date generationTime, String
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;
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package com.ctrip.framework.apollo.portal.controller;

import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.openapi.entity.Consumer;
import com.ctrip.framework.apollo.openapi.entity.ConsumerRole;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import com.ctrip.framework.apollo.openapi.service.ConsumerService;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
Expand All @@ -16,50 +22,60 @@
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
* @author Jason Song([email protected])
*/
@RestController
@RequestMapping("/consumers")
public class ConsumerController {
private static final Date DEFAULT_EXPIRES = new GregorianCalendar(2099, Calendar.JANUARY, 1)
.getTime();

private static final Date DEFAULT_EXPIRES = new GregorianCalendar(2099, Calendar.JANUARY, 1).getTime();

@Autowired
private ConsumerService consumerService;
@Autowired
private UserInfoHolder userInfoHolder;


@Transactional
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@RequestMapping(value = "/{consumerId}/tokens", method = RequestMethod.POST)
public ConsumerToken createConsumerToken(@PathVariable long consumerId,
@RequestParam(value = "expires", required = false)
@DateTimeFormat(pattern = "yyyyMMddHHmmss") Date
expires) {
@RequestMapping(value = "/consumers", method = RequestMethod.POST)
public ConsumerToken createConsumer(@RequestBody Consumer consumer,
@RequestParam(value = "expires", required = false)
@DateTimeFormat(pattern = "yyyyMMddHHmmss") Date
expires) {

if (StringUtils.isContainEmpty(consumer.getAppId(), consumer.getName(),
consumer.getOwnerName(), consumer.getOrgId())) {
throw new BadRequestException("Params(appId、name、ownerName、orgId) can not be empty.");
}

Consumer createdConsumer = consumerService.createConsumer(consumer);

if (expires == null) {
expires = DEFAULT_EXPIRES;
}

ConsumerToken consumerToken = generateConsumerToken(consumerId, expires);
return consumerService.generateAndSaveConsumerToken(createdConsumer, expires);
}

return consumerService.createConsumerToken(consumerToken);
@RequestMapping(value = "/consumers/by-appId", method = RequestMethod.GET)
public ConsumerToken getConsumerTokenByAppId(@RequestParam String appId) {
return consumerService.getConsumerTokenByAppId(appId);
}

private ConsumerToken generateConsumerToken(long consumerId, Date expires) {
String createdBy = userInfoHolder.getUser().getUserId();
Date createdTime = new Date();
@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@RequestMapping(value = "/consumers/{token}/assign-role", method = RequestMethod.POST)
public List<ConsumerRole> assignRoleToConsumer(@PathVariable String token, @RequestBody NamespaceDTO namespace) {

ConsumerToken consumerToken = new ConsumerToken();
consumerToken.setConsumerId(consumerId);
consumerToken.setExpires(expires);
consumerToken.setDataChangeCreatedBy(createdBy);
consumerToken.setDataChangeCreatedTime(createdTime);
consumerToken.setDataChangeLastModifiedBy(createdBy);
consumerToken.setDataChangeLastModifiedTime(createdTime);
String appId = namespace.getAppId();
String namespaceName = namespace.getNamespaceName();

consumerService.generateAndEnrichConsumerToken(consumerToken);
if (StringUtils.isContainEmpty(appId, namespaceName)) {
throw new BadRequestException("Params(AppId、NamespaceName) can not be empty.");
}

return consumerToken;
return consumerService.assignNamespaceRoleToConsumer(token, appId, namespaceName);
}


}
Loading

0 comments on commit 8635fde

Please sign in to comment.