All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.arextest.schedule.aspect.AppAuthAspectExecutor Maven / Gradle / Ivy

There is a newer version: 2.0.4
Show newest version
package com.arextest.schedule.aspect;

import com.arextest.common.annotation.AppAuth;
import com.arextest.common.context.ArexContext;
import com.arextest.common.exceptions.ArexException;
import com.arextest.common.jwt.JWTService;
import com.arextest.common.model.response.ResponseCode;
import com.arextest.common.utils.ResponseUtils;
import com.arextest.config.model.dao.config.AppCollection;
import com.arextest.config.model.dao.config.SystemConfigurationCollection;
import com.arextest.config.model.dao.config.SystemConfigurationCollection.KeySummary;
import com.arextest.schedule.dao.mongodb.ApplicationRepository;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Optional;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Slf4j
@RequiredArgsConstructor
public class AppAuthAspectExecutor {

  public static final String POINT_CONTENT = "@annotation(com.arextest.common.annotation.AppAuth)";

  public static final String AROUND_CONTENT = "appAuth() && @annotation(auth)";

  private static final String NO_PERMISSION = "No permission";
  private static final String NO_APPID = "No appId";
  private static final String ERROR_APPID = "Error appId";
  private static Boolean authSwitch = null;

  private final ApplicationRepository applicationRepository;

  private final MongoTemplate mongoTemplate;

  private final JWTService jwtService;


  public Object doAround(ProceedingJoinPoint point, AppAuth auth) throws Throwable {

    try {
      if (!judgeByAuth()) {
        return point.proceed();
      }

      ArexContext context = ArexContext.getContext();
      setContext();

      if (context.getAppId() == null) {
        LOGGER.error("header has no appId");
        return reject(point, auth, NO_APPID);
      }

      OwnerExistResult ownerExistResult = getOwnerExistResult();
      if (ownerExistResult.getExist()) {
        context.setPassAuth(true);
        return point.proceed();
      } else {
        context.setPassAuth(false);
        return reject(point, auth, ownerExistResult.getRemark());
      }

    } finally {
      ArexContext.removeContext();
    }

  }

  protected boolean judgeByAuth() {
    if (authSwitch == null) {
      init();
    }
    return authSwitch;
  }

  protected void setContext() {
    ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    if (requestAttributes == null) {
      return;
    }
    HttpServletRequest request = requestAttributes.getRequest();
    String appId = request.getHeader("appId");
    String accessToken = request.getHeader("access-token");
    String userName = jwtService.getUserName(accessToken);
    ArexContext context = ArexContext.getContext();
    context.setAppId(appId);
    context.setOperator(userName);
  }

  protected OwnerExistResult getOwnerExistResult() {
    ArexContext context = ArexContext.getContext();
    String userName = context.getOperator();

    AppCollection application = applicationRepository.query(context.getAppId());
    if (application == null) {
      LOGGER.error("error appId, appId: {}", context.getAppId());
      return new OwnerExistResult(false, ERROR_APPID);
    }
    Set owners = application.getOwners();
    if (CollectionUtils.isEmpty(owners) || owners.contains(userName)) {
      return new OwnerExistResult(true, null);
    } else {
      return new OwnerExistResult(false, NO_PERMISSION);
    }
  }


  private Object reject(ProceedingJoinPoint point, AppAuth auth, String remark) throws Throwable {
    switch (auth.rejectStrategy()) {
      case FAIL_RESPONSE:
        return ResponseUtils.errorResponse(remark, ResponseCode.AUTHENTICATION_FAILED);
      case DOWNGRADE:
        ArexContext.getContext().setPassAuth(false);
        return point.proceed();
      default:
        return point.proceed();
    }
  }

  private void init() {
    Query query = new Query(
        Criteria.where(SystemConfigurationCollection.Fields.key).is(KeySummary.AUTH_SWITCH));
    SystemConfigurationCollection collection = mongoTemplate.findOne(query,
        SystemConfigurationCollection.class, SystemConfigurationCollection.DOCUMENT_NAME);
    authSwitch = Optional.ofNullable(collection)
        .map(SystemConfigurationCollection::getAuthSwitch)
        .orElse(null);
    if (authSwitch == null) {
      throw new ArexException(ResponseCode.AUTHENTICATION_FAILED.getCodeValue(),
          "get authSwitch failed, please update storage version");
    }
  }

  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  public static class OwnerExistResult {

    private Boolean exist;
    private String remark;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy