Преглед на файлове

refactor: 用户系统改为接入门户的形式

370774330@qq.com преди 5 години
родител
ревизия
d79884233f
променени са 31 файла, в които са добавени 301 реда и са изтрити 746 реда
  1. 8 0
      api/pom.xml
  2. 14 0
      common/pom.xml
  3. 1 0
      common/src/main/java/seecoder/devcloud/common/CommonAutoConfiguration.java
  4. 27 54
      common/src/main/java/seecoder/devcloud/common/util/JwtTokenUtil.java
  5. 0 41
      common/src/main/java/seecoder/devcloud/common/validate/FieldCompare.java
  6. 0 39
      common/src/main/java/seecoder/devcloud/common/validate/FieldEquals.java
  7. 0 38
      common/src/main/java/seecoder/devcloud/common/validate/validator/FieldCompareValidator.java
  8. 0 30
      common/src/main/java/seecoder/devcloud/common/validate/validator/FieldEqualsValidator.java
  9. 1 1
      core/src/main/java/seecoder/devcloud/core/pipeline/PipelineException.java
  10. 0 1
      core/src/main/java/seecoder/devcloud/core/pipeline/config/HandlerConfigTable.java
  11. 0 9
      core/src/main/java/seecoder/devcloud/core/pipeline/handler/MavenPackageHandler.java
  12. 0 9
      core/src/main/java/seecoder/devcloud/core/pipeline/handler/MavenTestHandler.java
  13. 5 31
      web/src/main/java/seecoder/devcloud/web/controller/user/UserController.java
  14. 2 2
      web/src/main/java/seecoder/devcloud/web/dao/GeneralInsertUpdateSqlProvider.java
  15. 27 0
      web/src/main/java/seecoder/devcloud/web/dao/impl/UserMapperImpl.java
  16. 10 25
      web/src/main/java/seecoder/devcloud/web/dao/user/UserMapper.java
  17. 25 20
      web/src/main/java/seecoder/devcloud/web/infrastructure/config/WebSecurityConfig.java
  18. 0 29
      web/src/main/java/seecoder/devcloud/web/infrastructure/security/AuthController.java
  19. 0 39
      web/src/main/java/seecoder/devcloud/web/infrastructure/security/JwtAuthService.java
  20. 32 12
      web/src/main/java/seecoder/devcloud/web/infrastructure/security/JwtAuthenticationTokenFilter.java
  21. 0 18
      web/src/main/java/seecoder/devcloud/web/infrastructure/security/Sha256HexPasswordEncoder.java
  22. 0 24
      web/src/main/java/seecoder/devcloud/web/infrastructure/security/WebSecurityBean.java
  23. 6 2
      web/src/main/java/seecoder/devcloud/web/infrastructure/security/WebSecurityConstants.java
  24. 10 15
      web/src/main/java/seecoder/devcloud/web/model/po/user/User.java
  25. 0 25
      web/src/main/java/seecoder/devcloud/web/model/vo/user/ChangePasswordVO.java
  26. 4 4
      web/src/main/java/seecoder/devcloud/web/service/impl/user/GroupServiceImpl.java
  27. 5 145
      web/src/main/java/seecoder/devcloud/web/service/impl/user/UserServiceImpl.java
  28. 0 20
      web/src/main/java/seecoder/devcloud/web/service/user/UserService.java
  29. 4 0
      web/src/main/resources/application-wph.yml
  30. 10 2
      web/src/main/resources/devcloud-k8s-init
  31. 110 111
      web/src/test/java/seecoder/devcloud/web/service/user/UserServiceTest.java

+ 8 - 0
api/pom.xml

@@ -151,6 +151,14 @@
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <version>2.3.7.RELEASE</version>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.springframework.boot</groupId>
+                            <artifactId>spring-boot-configuration-processor</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
                 <executions>
                     <execution>
                         <id>repackage</id>

+ 14 - 0
common/pom.xml

@@ -44,6 +44,12 @@
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
@@ -106,6 +112,14 @@
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <version>2.3.4.RELEASE</version>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.springframework.boot</groupId>
+                            <artifactId>spring-boot-configuration-processor</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
                 <executions>
                     <execution>
                         <id>repackage</id>

+ 1 - 0
common/src/main/java/seecoder/devcloud/common/CommonAutoConfiguration.java

@@ -1,5 +1,6 @@
 package seecoder.devcloud.common;
 
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import seecoder.devcloud.common.util.JwtTokenUtil;

+ 27 - 54
common/src/main/java/seecoder/devcloud/common/util/JwtTokenUtil.java

@@ -5,37 +5,41 @@ import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
 import lombok.Data;
 import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
 import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.stereotype.Component;
 
 import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
 
+/**
+ * @author PuHong Weng
+ * @date 2021/3/11
+ * @description:
+ * 与门户系统对接,其返回的token如下,详细见
+ * https://www.yuque.com/gcbqv7/zp5lcv/ikf11b
+ * {
+ *   "iss": "p.seecoder.cn",
+ *   "sub": "17301xxxx67",
+ *   "aud": "seec-mooc",
+ *   "auth_time": 1606xxxx481,
+ *   "iat": 16061xxx481,
+ *   "exp": 16061xx,
+ *   "user_info": {
+ *     "phone": "17301xxxxx",
+ *     "email": "adxxx
+ *     "id": 4x9,
+ *     "name": "admin",
+ *     "role": "ADMIN"
+ *   }
+ * }
+ */
 @Data
 @ConfigurationProperties(prefix = "seecoder.jwt")
-@Component
+@Configuration
 public class JwtTokenUtil {
-    private String secret;
-    private Long expiration;
 
-    public String generateToken(UserDetails userDetails) {
-        Map<String, Object> claims = new HashMap<>(2);
-        claims.put("sub", userDetails.getUsername());
-        claims.put("created", new Date());
-        return generateToken(claims);
-    }
+    private String secret;
 
-    public String getUsernameFromToken(String token) {
-        String username;
-        try {
-            Claims claims = getClaimsFromToken(token);
-            username = claims.getSubject();
-        } catch (Exception e) {
-            username = null;
-        }
-        return username;
-    }
+    private Long expiration;
 
     public Boolean isTokenExpired(String token) {
         try {
@@ -47,38 +51,7 @@ public class JwtTokenUtil {
         }
     }
 
-    /**
-     * 刷新令牌
-     *
-     * @param token 原令牌
-     * @return 新令牌
-     */
-    public String refreshToken(String token) {
-        String refreshedToken;
-        try {
-            Claims claims = getClaimsFromToken(token);
-            claims.put("created", new Date());
-            refreshedToken = generateToken(claims);
-        } catch (Exception e) {
-            refreshedToken = null;
-        }
-        return refreshedToken;
-    }
-
-    public Boolean validateToken(String token, UserDetails userDetails) {
-        String username = getUsernameFromToken(token);
-        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
-    }
-
-    private String generateToken(Map<String, Object> claims) {
-        Date expirationDate = new Date(System.currentTimeMillis() + expiration);
-        return Jwts.builder().setClaims(claims)
-                .setExpiration(expirationDate)
-                .signWith(SignatureAlgorithm.HS512, secret)
-                .compact();
-    }
-
-    private Claims getClaimsFromToken(String token) {
+    public Claims getClaimsFromToken(String token) {
         Claims claims;
         try {
             claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();

+ 0 - 41
common/src/main/java/seecoder/devcloud/common/validate/FieldCompare.java

@@ -1,41 +0,0 @@
-package seecoder.devcloud.common.validate;
-
-
-import seecoder.devcloud.common.validate.validator.FieldCompareValidator;
-
-import javax.validation.Constraint;
-import javax.validation.Payload;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Repeatable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Target({TYPE, ANNOTATION_TYPE})
-@Retention(RUNTIME)
-@Repeatable(FieldCompare.List.class)
-@Constraint(validatedBy = FieldCompareValidator.class)
-@Documented
-public @interface FieldCompare {
-	String message() default "{seecoder.devcloud.common.validate.FieldCompare}";
-
-	Class<?>[] groups() default {};
-
-	Class<? extends Payload>[] payload() default {};
-
-	String lessField();
-
-	String greaterField();
-
-	boolean allowEqual() default false;
-
-	@Target({TYPE, ANNOTATION_TYPE})
-	@Retention(RUNTIME)
-	@Documented
-	@interface List {
-		FieldCompare[] value();
-	}
-}

+ 0 - 39
common/src/main/java/seecoder/devcloud/common/validate/FieldEquals.java

@@ -1,39 +0,0 @@
-package seecoder.devcloud.common.validate;
-
-import seecoder.devcloud.common.validate.validator.FieldEqualsValidator;
-
-import javax.validation.Constraint;
-import javax.validation.Payload;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Repeatable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Target({TYPE, ANNOTATION_TYPE})
-@Retention(RUNTIME)
-@Repeatable(FieldEquals.List.class)
-@Constraint(validatedBy = FieldEqualsValidator.class)
-@Documented
-public @interface FieldEquals {
-	String message() default "{seecoder.devcloud.common.validate.FieldEquals}";
-
-	Class<?>[] groups() default {};
-
-	Class<? extends Payload>[] payload() default {};
-
-	String firstField();
-
-	String secondField();
-
-	@Target({TYPE, ANNOTATION_TYPE})
-	@Retention(RUNTIME)
-	@Documented
-	@interface List {
-		FieldEquals[] value();
-	}
-
-}

+ 0 - 38
common/src/main/java/seecoder/devcloud/common/validate/validator/FieldCompareValidator.java

@@ -1,38 +0,0 @@
-package seecoder.devcloud.common.validate.validator;
-
-import org.springframework.beans.BeanUtils;
-import seecoder.devcloud.common.validate.FieldCompare;
-
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-
-public class FieldCompareValidator implements ConstraintValidator<FieldCompare, Object> {
-	private String lessField;
-	private String greaterField;
-	private boolean allowEqual;
-
-
-	@Override
-	public void initialize(FieldCompare constraintAnnotation) {
-		this.lessField = constraintAnnotation.lessField();
-		this.greaterField = constraintAnnotation.greaterField();
-		this.allowEqual = constraintAnnotation.allowEqual();
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	public boolean isValid(Object value, ConstraintValidatorContext context) {
-		try {
-			Comparable lessObject = (Comparable) BeanUtils.getPropertyDescriptor(value.getClass(), lessField).getReadMethod().invoke(value);
-			Comparable greaterObject = (Comparable) BeanUtils.getPropertyDescriptor(value.getClass(), greaterField).getReadMethod().invoke(value);
-			int result = lessObject.compareTo(greaterObject);
-			if (allowEqual && result == 0) {
-				return true;
-			} else {
-				return result < 0;
-			}
-		} catch (Exception e) {
-			return false;
-		}
-	}
-}

+ 0 - 30
common/src/main/java/seecoder/devcloud/common/validate/validator/FieldEqualsValidator.java

@@ -1,30 +0,0 @@
-package seecoder.devcloud.common.validate.validator;
-
-import org.springframework.beans.BeanUtils;
-import seecoder.devcloud.common.validate.FieldEquals;
-
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-import java.util.Objects;
-
-public class FieldEqualsValidator implements ConstraintValidator<FieldEquals, Object> {
-	private String firstField;
-	private String secondField;
-
-	@Override
-	public void initialize(FieldEquals constraintAnnotation) {
-		this.firstField = constraintAnnotation.firstField();
-		this.secondField = constraintAnnotation.secondField();
-	}
-
-	@Override
-	public boolean isValid(Object value, ConstraintValidatorContext context) {
-		try {
-			Object firstObject = BeanUtils.getPropertyDescriptor(value.getClass(), firstField).getReadMethod().invoke(value);
-			Object secondObject = BeanUtils.getPropertyDescriptor(value.getClass(), secondField).getReadMethod().invoke(value);
-			return Objects.equals(firstObject, secondObject);
-		} catch (Exception e) {
-			return false;
-		}
-	}
-}

+ 1 - 1
core/src/main/java/seecoder/devcloud/core/PipelineException.java → core/src/main/java/seecoder/devcloud/core/pipeline/PipelineException.java

@@ -1,4 +1,4 @@
-package seecoder.devcloud.core;
+package seecoder.devcloud.core.pipeline;
 
 /**
  * @author PuHong Weng

+ 0 - 1
core/src/main/java/seecoder/devcloud/core/pipeline/config/HandlerConfigTable.java

@@ -30,7 +30,6 @@ public class HandlerConfigTable {
         Handler handler = null;
         try {
             handler = (Handler) handlerConfigMap.get(config).newInstance();
-
         } catch (InstantiationException | IllegalAccessException e) {
             log.error("流水线配置转换发生错误",e);
             //todo throw pipeline exception

+ 0 - 9
core/src/main/java/seecoder/devcloud/core/pipeline/handler/MavenPackageHandler.java

@@ -1,9 +0,0 @@
-package seecoder.devcloud.core.pipeline.handler;
-
-/**
- * @author PuHong Weng
- * @date 2021/1/19
- * @description:
- */
-public class MavenPackageHandler {
-}

+ 0 - 9
core/src/main/java/seecoder/devcloud/core/pipeline/handler/MavenTestHandler.java

@@ -1,9 +0,0 @@
-package seecoder.devcloud.core.pipeline.handler;
-
-/**
- * @author PuHong Weng
- * @date 2021/1/19
- * @description:
- */
-public class MavenTestHandler {
-}

+ 5 - 31
web/src/main/java/seecoder/devcloud/web/controller/user/UserController.java

@@ -3,12 +3,6 @@ package seecoder.devcloud.web.controller.user;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import seecoder.devcloud.web.service.user.UserService;
-import seecoder.devcloud.web.model.vo.Response;
-import seecoder.devcloud.web.model.vo.user.ChangePasswordVO;
-import seecoder.devcloud.web.model.vo.user.RegisterVO;
-import seecoder.devcloud.web.model.vo.user.UserVO;
-
-import javax.validation.constraints.Pattern;
 
 /**
  * @author PuHong Weng
@@ -26,30 +20,10 @@ public class UserController {
         this.userService = userService;
     }
 
-    @PostMapping("/register")
-    public Response<UserVO> register(@RequestBody RegisterVO registerVO){
-        return Response.ok(userService.register(registerVO)) ;
-    }
-
-    @PutMapping("/password")
-    public Response changePassword(@RequestBody ChangePasswordVO vo){
-        userService.changePassword(vo);
-        return Response.ok();
-    }
-
-    @PutMapping("/nickname")
-    public Response<UserVO> changeUserInfo(
-            @RequestParam("userId") Integer userid,
-            @RequestParam("nickname")
-            @Pattern(regexp = "^\\w+${4,23}", message = "昵称只能包含大小写字母、数字和下划线,且必须为4-23位!")
-                    String nickName) {
-        return Response.ok(userService.changeUserInfo(userid, nickName));
-    }
-
-    @GetMapping("/id")
-    public Response<UserVO> findUserById(
-            @RequestParam("userId") Integer userId){
-        return Response.ok(userService.getUserById(userId));
-    }
+//    @GetMapping("/id")
+//    public Response<UserVO> findUserById(
+//            @RequestParam("userId") Integer userId){
+//        return Response.ok(userService.getUserById(userId));
+//    }
 
 }

+ 2 - 2
web/src/main/java/seecoder/devcloud/web/dao/GeneralInsertUpdateSqlProvider.java

@@ -10,8 +10,8 @@ import java.util.stream.Collectors;
 /**
  * @author PuHong Weng
  * @date 2021/3/1
- * @description: 避免写繁琐的插入和更新的方法的,注意 pojo类的字段要和数据库表对应, 用法示例见 UserMapper.class
- * 插入单个参数(除了ignoredCols以外的参数)时,mapper写方法就行,实例见 UserMapper.insert
+ * @description: 避免写繁琐的插入和更新的方法的,注意 pojo类的字段要和数据库表对应, 用法示例见 UserMapperImpl.class
+ * 插入单个参数(除了ignoredCols以外的参数)时,mapper写方法就行,实例见 UserMapperImpl.insert
  * 插入多个参数(除了ignoredCols以外的参数)时,mapper方法参数要加@Param说明,实例见 GroupMemberMapper.insert
  */
 public class GeneralInsertUpdateSqlProvider {

+ 27 - 0
web/src/main/java/seecoder/devcloud/web/dao/impl/UserMapperImpl.java

@@ -0,0 +1,27 @@
+package seecoder.devcloud.web.dao.impl;
+
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import seecoder.devcloud.web.dao.user.UserMapper;
+import seecoder.devcloud.web.model.po.user.User;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/11
+ * @description:
+ */
+public class UserMapperImpl implements UserMapper {
+
+
+    @Override
+    public User findLoginUser() {
+        User loginUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        return loginUser;
+    }
+
+    @Override
+    public User findUserByUsername(String username) {
+        //todo 从门户获取
+        return null;
+    }
+}

+ 10 - 25
web/src/main/java/seecoder/devcloud/web/dao/user/UserMapper.java

@@ -1,35 +1,20 @@
 package seecoder.devcloud.web.dao.user;
 
-
-import org.apache.ibatis.annotations.*;
-import seecoder.devcloud.web.dao.GeneralInsertUpdateSqlProvider;
 import seecoder.devcloud.web.model.po.user.User;
 
-
-@Mapper
+/**
+ * 准确来说已经不是mybatis的mapper了
+ * 因为集成了门户系统,用户数据需要从那取
+ * 这里写成这种形式是为了不破坏三层结构
+ */
 public interface UserMapper {
 
 	/**
-	 * 这里的id是取自gitlab的用户id,所以不需要自增和回填
+	 * 返回当前自己的用户信息
+	 * 由于集成了门户系统而且使用了jwt作为安全认证机制,自己的用户信息存放在 SecurityContextHolder中
+	 * 见 JwtAuthenticationTokenFilter.class
 	 */
-	@InsertProvider(type = GeneralInsertUpdateSqlProvider.class, method = "insert")
-	int insert(User user,String... ignoredCols);
-
-	@UpdateProvider(type= GeneralInsertUpdateSqlProvider.class, method="updateById")
-	int updateById(User user);
-
-	@Delete("delete from user where id = #{id}")
-	int delete(User user);
-
-
-	@Select("select * from user where id = #{id}")
-	User findById(int id);
-
-	@Select("select * from user where username = #{username}")
-	User findByUsername(String username);
-
-	@Select("select * from user where email = #{email}")
-	User findByEmail(String email);
-
+	User findLoginUser();
 
+	User findUserByUsername(String username);
 }

+ 25 - 20
web/src/main/java/seecoder/devcloud/web/infrastructure/config/WebSecurityConfig.java

@@ -15,10 +15,13 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.builders.WebSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 import org.springframework.web.cors.CorsUtils;
+import seecoder.devcloud.web.infrastructure.security.JwtAuthenticationTokenFilter;
 import seecoder.devcloud.web.infrastructure.security.WebSecurityConstants;
 import seecoder.devcloud.web.service.impl.user.UserServiceImpl;
 
@@ -39,38 +42,40 @@ import java.util.Map;
 @DependsOn("userServiceImpl")
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
-    @Qualifier("userServiceImpl")
-    @Autowired
-    private UserDetailsService userDetailsService;
-
-    @Autowired
-    private PasswordEncoder passwordEncoder;
 
+    private final JwtAuthenticationTokenFilter filter;
 
+    @Autowired
+    public WebSecurityConfig(JwtAuthenticationTokenFilter filter) {
+        super();
+        this.filter = filter;
+    }
 
     @Override
     protected void configure(HttpSecurity http) throws Exception {
-        http
-
-                .authorizeRequests()
+        //访问控制
+        http.authorizeRequests()
                 //跨域的Options请求进行放行
                 .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
-                //todo 具体角色权限配置等开发完成之后再配, 这里先配为默认所有权限
-                .antMatchers("/**").hasAnyRole(WebSecurityConstants.STUDENT_ROLE,WebSecurityConstants.TEACHER_ROLE,WebSecurityConstants.ADMIN_ROLE)
+                //其他所有接口都要在登陆认证状态下请求
                 .anyRequest().authenticated()
-                .and()
-                .formLogin()
-                .and()
-                .logout()
-                .and()
-                .httpBasic();
-
+                //todo 具体角色权限配置等开发完成之后再配, 这里先配为默认所有权限
+                .antMatchers("/**").hasAnyRole(WebSecurityConstants.STUDENT_ROLE, WebSecurityConstants.ADMIN_ROLE);
 
-        //跨域
+        //开启跨域
         http.cors();
 
-        //改用jwt
+        //改用jwt无状态认证方式,将原来基于session的认证方式关闭
         http.csrf().disable();
+        http.sessionManagement()
+                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+                .and()
+                .addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
+    }
+
+    @Bean
+    public AuthenticationManager authenticationManager() throws Exception {
+        return super.authenticationManagerBean() ;
     }
 
 

+ 0 - 29
web/src/main/java/seecoder/devcloud/web/infrastructure/security/AuthController.java

@@ -1,29 +0,0 @@
-package seecoder.devcloud.web.infrastructure.security;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import seecoder.devcloud.web.model.vo.Response;
-
-import java.util.Map;
-
-@RestController
-@RequestMapping("/api/auth")
-public class AuthController {
-
-    private final JwtAuthService jwtAuthService;
-
-    @Autowired
-    public AuthController(JwtAuthService jwtAuthService) {
-        this.jwtAuthService = jwtAuthService;
-    }
-
-    @PostMapping("")
-    public Response login(@RequestBody Map<String, String> map) {
-        String username = map.get("username");
-        String password = map.get("password");
-        return Response.ok(jwtAuthService.login(username, password));
-    }
-}

+ 0 - 39
web/src/main/java/seecoder/devcloud/web/infrastructure/security/JwtAuthService.java

@@ -1,39 +0,0 @@
-package seecoder.devcloud.web.infrastructure.security;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.stereotype.Service;
-import seecoder.devcloud.common.util.JwtTokenUtil;
-
-@Service
-public class JwtAuthService {
-
-    private final AuthenticationManager authenticationManager;
-
-    private final UserDetailsService userDetailsService;
-
-    private final JwtTokenUtil jwtTokenUtil;
-
-    @Autowired
-    public JwtAuthService(AuthenticationManager authenticationManager, @Qualifier("userServiceImpl") UserDetailsService userDetailsService, JwtTokenUtil jwtTokenUtil) {
-        this.authenticationManager = authenticationManager;
-        this.userDetailsService = userDetailsService;
-        this.jwtTokenUtil = jwtTokenUtil;
-    }
-
-    public String login(String username, String password) {
-        UsernamePasswordAuthenticationToken upToken =
-                new UsernamePasswordAuthenticationToken(username, password);
-        Authentication authentication = authenticationManager.authenticate(upToken);
-        SecurityContextHolder.getContext().setAuthentication(authentication);
-        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
-        return jwtTokenUtil.generateToken(userDetails);
-    }
-
-}

+ 32 - 12
web/src/main/java/seecoder/devcloud/web/infrastructure/security/JwtAuthenticationTokenFilter.java

@@ -1,5 +1,6 @@
 package seecoder.devcloud.web.infrastructure.security;
 
+import io.jsonwebtoken.Claims;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -11,6 +12,8 @@ import org.springframework.security.web.authentication.WebAuthenticationDetailsS
 import org.springframework.stereotype.Component;
 import org.springframework.web.filter.OncePerRequestFilter;
 import seecoder.devcloud.common.util.JwtTokenUtil;
+import seecoder.devcloud.web.model.enums.UserIdentity;
+import seecoder.devcloud.web.model.po.user.User;
 
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
@@ -18,6 +21,13 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/11
+ * @description:
+ * 登陆是集成了门户系统的登陆,后端只用作token校验
+ */
 @Component
 public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
 
@@ -35,19 +45,29 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
     protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
         String authHeader = httpServletRequest.getHeader("Authorization");
         if (StringUtils.isNotEmpty(authHeader)) {
-            String username = jwtTokenUtil.getUsernameFromToken(authHeader);
-            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
-                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
-                if (jwtTokenUtil.validateToken(authHeader, userDetails)) {
-                    //加载用户、角色、权限信息,Spring Security根据这些信息判断接口的访问权限
-                    UsernamePasswordAuthenticationToken authentication
-                            = new UsernamePasswordAuthenticationToken(userDetails, null,
-                            userDetails.getAuthorities());
-                    authentication.setDetails(new WebAuthenticationDetailsSource()
-                            .buildDetails(httpServletRequest));
-                    SecurityContextHolder.getContext().setAuthentication(authentication);
-                }
+            // 有token,验证正确性,签名不正确,会抛异常
+            Claims claims = jwtTokenUtil.getClaimsFromToken(authHeader);
+
+            UserDetails userDetails = User.builder()
+                    .id(claims.get("id",Integer.class))
+                    .username(claims.get("name",String.class))
+                    .email(claims.get("email",String.class))
+                    .phone(claims.get("phone",String.class))
+                    //todo 验证是否和门户身份一致
+                    .role(UserIdentity.valueOf(claims.get("role",String.class)))
+                    .build();
+
+            // 验证token是否过期
+            if (jwtTokenUtil.isTokenExpired(authHeader)) {
+                //加载用户、角色、权限信息,Spring Security根据这些信息判断接口的访问权限
+                UsernamePasswordAuthenticationToken authentication
+                        = new UsernamePasswordAuthenticationToken(userDetails, null,
+                        userDetails.getAuthorities());
+                authentication.setDetails(new WebAuthenticationDetailsSource()
+                        .buildDetails(httpServletRequest));
+                SecurityContextHolder.getContext().setAuthentication(authentication);
             }
+
         }
         filterChain.doFilter(httpServletRequest, httpServletResponse);
     }

+ 0 - 18
web/src/main/java/seecoder/devcloud/web/infrastructure/security/Sha256HexPasswordEncoder.java

@@ -1,18 +0,0 @@
-package seecoder.devcloud.web.infrastructure.security;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Component;
-
-@Component
-public class Sha256HexPasswordEncoder implements PasswordEncoder {
-    @Override
-    public String encode(CharSequence rawPassword) {
-        return DigestUtils.sha256Hex(rawPassword != null ? rawPassword.toString() : StringUtils.EMPTY);
-    }
-
-    @Override
-    public boolean matches(CharSequence rawPassword, String encodedPassword) {
-        return StringUtils.equals(encode(rawPassword), encodedPassword);
-    }
-}

+ 0 - 24
web/src/main/java/seecoder/devcloud/web/infrastructure/security/WebSecurityBean.java

@@ -1,24 +0,0 @@
-package seecoder.devcloud.web.infrastructure.security;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-
-/**
- * @author PuHong Weng
- * @date 2021/3/6
- * @description:
- */
-@Configuration
-public class WebSecurityBean {
-
-    @Bean
-    public PasswordEncoder passwordEncoder(){
-        return new BCryptPasswordEncoder();
-    }
-
-
-}
-

+ 6 - 2
web/src/main/java/seecoder/devcloud/web/infrastructure/security/WebSecurityConstants.java

@@ -6,7 +6,11 @@ import seecoder.devcloud.web.model.enums.UserIdentity;
 
 import java.util.HashMap;
 import java.util.Map;
-
+/**
+ * @author PuHong Weng
+ * @date 2021/3/8
+ * @description:
+ */
 public abstract class WebSecurityConstants {
 	private static final String ROLE_PREFIX = "ROLE_";
 
@@ -20,7 +24,7 @@ public abstract class WebSecurityConstants {
 
 
 
-	private static Map<UserIdentity,GrantedAuthority> authorityTable= new HashMap<>();
+	private static final Map<UserIdentity,GrantedAuthority> authorityTable= new HashMap<>();
 	
 	static {
 		authorityTable.put(UserIdentity.STUDENT, STUDENT_AUTHORITY);

+ 10 - 15
web/src/main/java/seecoder/devcloud/web/model/po/user/User.java

@@ -1,6 +1,7 @@
 package seecoder.devcloud.web.model.po.user;
 
 
+import lombok.Builder;
 import lombok.Data;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -11,7 +12,9 @@ import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Collections;
 
+
 @Data
+@Builder
 public class User implements UserDetails {
 
 	/**
@@ -21,31 +24,23 @@ public class User implements UserDetails {
 
 	private String username;
 
-	private String nickname="";
-
-	private String password;
-
 	private String phone;
 
 	private String email;
 
 	private UserIdentity role;
 
-	private Timestamp createdAt;
-
-	/**
-	 * 这个属性来自于gitlab
-	 */
-	private Integer namespace;
+	@Override
+	public Collection<? extends GrantedAuthority> getAuthorities() {
+		return Collections.singleton(WebSecurityConstants.getAuthority(role));
+	}
 
 	/**
-	 * 这个属性来自于gitlab
+	 * 此后端整合portal门户系统,不需要登陆功能,不用重写此方法
 	 */
-	private String token;
-
 	@Override
-	public Collection<? extends GrantedAuthority> getAuthorities() {
-		return Collections.singleton(WebSecurityConstants.getAuthority(role));
+	public String getPassword() {
+		return "";
 	}
 
 	// spring security以下四个方法目前没有需求,默认全部返回true

+ 0 - 25
web/src/main/java/seecoder/devcloud/web/model/vo/user/ChangePasswordVO.java

@@ -1,25 +0,0 @@
-package seecoder.devcloud.web.model.vo.user;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import seecoder.devcloud.common.validate.FieldEquals;
-
-import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Pattern;
-
-@Data
-@FieldEquals(firstField = "password", secondField = "confirm", message = "两次输入的新密码不一致!")
-@AllArgsConstructor
-public class ChangePasswordVO {
-
-	private Integer userId;
-	@NotNull(message = "请填写原密码!")
-	private String origin;
-	@Pattern(regexp = "[0-9a-zA-Z_]{8,16}", message = "密码只能包含大小写字母、数字和下划线,且必须为8-16位!")
-	@NotNull(message = "请填写新密码!")
-	private String password;
-	/**
-	 * 新密码要输入两遍,做确认
-	 */
-	private String confirm;
-}

+ 4 - 4
web/src/main/java/seecoder/devcloud/web/service/impl/user/GroupServiceImpl.java

@@ -28,16 +28,16 @@ import java.util.UUID;
 @Slf4j
 public class GroupServiceImpl implements GroupService {
     private final GroupMapper groupMapper;
-    private final UserMapper userMapper;
     private final GroupMemberMapper groupMemberMapper;
     private final GitlabApi gitlabApi;
+    private final UserMapper userMapper;
 
     @Autowired
-    public GroupServiceImpl(GroupMapper groupMapper, UserMapper userMapper, GroupMemberMapper groupMemberMapper, GitlabApi gitlabApi) {
+    public GroupServiceImpl(GroupMapper groupMapper, GroupMemberMapper groupMemberMapper, GitlabApi gitlabApi, UserMapper userMapper) {
         this.groupMapper = groupMapper;
-        this.userMapper = userMapper;
         this.groupMemberMapper = groupMemberMapper;
         this.gitlabApi = gitlabApi;
+        this.userMapper = userMapper;
     }
 
     @Override
@@ -46,7 +46,7 @@ public class GroupServiceImpl implements GroupService {
         if (groupMapper.findGroupByName(name) != null){
             throw new ServiceException("您创建的小组名字已被使用!");
         }
-        User user = userMapper.findById(userId);
+        User user = userMapper.findLoginUser();
         List<User> members = new ArrayList<>();
         members.add(user);
         GitlabGroup gitGroup;

+ 5 - 145
web/src/main/java/seecoder/devcloud/web/service/impl/user/UserServiceImpl.java

@@ -2,168 +2,28 @@ package seecoder.devcloud.web.service.impl.user;
 
 
 import lombok.extern.slf4j.Slf4j;
-import org.gitlab4j.api.GitLabApiException;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Sort;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.Assert;
-import seecoder.devcloud.api.gitlab.GitlabApi;
-import seecoder.devcloud.api.gitlab.model.GitlabUser;
-import seecoder.devcloud.api.jenkins.JenkinsApi;
-import seecoder.devcloud.common.exceptions.InvalidRequestException;
-import seecoder.devcloud.common.exceptions.ServiceException;
-import seecoder.devcloud.common.util.ToolKit;
-import seecoder.devcloud.web.dao.user.UserMapper;
-import seecoder.devcloud.web.model.vo.user.ChangePasswordVO;
-import seecoder.devcloud.web.model.vo.user.RegisterVO;
 
-import seecoder.devcloud.web.model.enums.UserIdentity;
 import seecoder.devcloud.web.model.po.user.User;
-import seecoder.devcloud.web.model.vo.user.UserVO;
-import seecoder.devcloud.web.service.user.MailService;
 import seecoder.devcloud.web.service.user.UserService;
 
 @Service
 @Slf4j
 public class UserServiceImpl implements UserService, UserDetailsService {
-	private static final Sort PAGE_SORT = Sort.by(Sort.Direction.ASC, "id");
 
-	private final UserMapper userMapper;
-	private final MailService mailService;
-	private final GitlabApi gitlabApi;
-	private final JenkinsApi jenkinsApi;
-	/**
-	 * spring security提供的加密
-	 */
-	private final PasswordEncoder passwordEncoder;
-
-	@Autowired
-	public UserServiceImpl(UserMapper userMapper, MailService mailService, GitlabApi gitlabApi, JenkinsApi jenkinsApi, PasswordEncoder passwordEncoder) {
-		this.userMapper = userMapper;
-		this.mailService = mailService;
-		this.gitlabApi = gitlabApi;
-		this.jenkinsApi = jenkinsApi;
-		this.passwordEncoder = passwordEncoder;
-	}
-
-	@Override
-	@Transactional
-	public UserVO register(RegisterVO form) throws ServiceException {
-		return register(form.getUsername(), form.getEmail(), form.getPassword(),form.getNickname(), UserIdentity.STUDENT);
-	}
-
-	@Override
-	@Transactional
-	public UserVO registerTeacher(RegisterVO form) throws ServiceException {
-		return register(form.getUsername(), form.getEmail(), form.getPassword(),form.getNickname(), UserIdentity.TEACHER);
-	}
-
-	private UserVO register(String username, String email, String password, String nickname,UserIdentity role) throws ServiceException {
-		User user = userMapper.findByUsername(username);
-		Asserts.isNull(user, "用户名已被使用!");
-		user = userMapper.findByEmail(email);
-		Asserts.isNull(user, "邮箱已被使用!");
-		String realPassword = password == null ? ToolKit.randomPassword() : password;
-		GitlabUser gitlabUser;
-		try {
-			gitlabUser = gitlabApi.createUser(username, email, realPassword);
-		} catch (GitLabApiException e) {
-			log.error(e.getMessage(), e);
-			throw new ServiceException("创建GitLab用户时发生异常[" + e.getMessage() + "]");
-		}
-		user = new User();
-		BeanUtils.copyProperties(gitlabUser, user);
-		if(nickname!=null){
-			user.setNickname(nickname);
-		}
-
-		user.setUsername(username);
-		user.setEmail(email);
-		//在gitlab注册后,直接加密
-		user.setPassword(passwordEncoder.encode(realPassword));
-		user.setRole(role);
-		userMapper.insert(user, "created_at");
-		final UserVO userVO = new UserVO(user);
-		if (password == null) {
-			mailService.send("尊敬的" + username + "您好, 您的初始密码为" + realPassword + ", 请及时修改", "注册成功 | SEECODER", email);
-		}
-		return userVO;
-	}
-
-	@Override
-	@Transactional
-	public void delete(int userId) throws ServiceException {
-		User user = userMapper.findById(userId);
-		Assert.notNull(user, "找不到要删除的用户");
-		Assert.isTrue(user.getRole() == UserIdentity.STUDENT, "目标用户只能是学生");
-		try {
-			gitlabApi.deleteUser(userId);
-		} catch (Exception e) {
-			log.error(e.getMessage(), e);
-			throw new ServiceException("删除GitLab用户时发生异常[" + e.getMessage() + "]");
-		}
-		//todo 删除用户需要连带删除什么
-		userMapper.delete(user);
-	}
-
-	@Override
-	public UserVO getUserById(Integer userid) {
-		return new UserVO(userMapper.findById(userid));
-	}
-
-	@Override
-	public UserVO changeUserInfo(Integer userid, String nickName) throws ServiceException {
-		User one = userMapper.findById(userid);
-		if (one == null) {
-			throw new ServiceException("用户不存在");
-		}
-		one.setNickname(nickName);
-		userMapper.updateById(one);
-		return new UserVO(one);
-	}
 
-	@Override
-	public void changePassword(ChangePasswordVO form) throws ServiceException {
-		User user = userMapper.findById(form.getUserId());
 
-		if (!passwordEncoder.matches(form.getOrigin(),user.getPassword())) {
-			throw new InvalidRequestException("原密码验证失败,如忘记密码请联系管理员重置");
-		}
-		changePassword(user, form.getPassword());
-	}
-
-	private void changePassword(User user, String password) throws ServiceException {
-		try {
-			/**
-			 * todo 修改密码容易导致gitlab与devcloud不一致
-			 * 管理员每次修改密码,会导致下次普通用户登陆gitlab的时候强制重新改密码
-			 * 如果这时候学生在gitlab那边改的密码与这里改的不一样,就产生了密码不一致的结果
-			 * 而且目前官方gitlab client api不支持普通用户通过api改密码
-			 * 见 https://docs.gitlab.com/ce/api/users.html
-			 * 所以这个bug暂时无解,最好是让学生建立用户完毕之后不要乱改密码
-			 */
-			gitlabApi.changePassword(user.getId(), password);
-		} catch (GitLabApiException e) {
-			log.error(e.getMessage(), e);
-			throw new ServiceException("修改GitLab用户密码时发生异常[" + e.getMessage() + "]");
-		}
-		user.setPassword(passwordEncoder.encode(password));
-		userMapper.updateById(user);
-	}
 
+	/**
+	 * 此后端整合portal门户系统,不需要登陆功能,不用重写此方法
+	 */
 	@Override
 	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-		UserDetails u = userMapper.findByUsername(username);
-		if (u == null){
-			throw new UsernameNotFoundException("此账号不存在");
-		}
-		return u;
+		//todo 门户功能获取用户
+		return null;
 	}
 
 

+ 0 - 20
web/src/main/java/seecoder/devcloud/web/service/user/UserService.java

@@ -1,28 +1,8 @@
 package seecoder.devcloud.web.service.user;
 
 
-import seecoder.devcloud.common.exceptions.ServiceException;
-
-import seecoder.devcloud.web.model.vo.user.ChangePasswordVO;
-import seecoder.devcloud.web.model.vo.user.RegisterVO;
-import seecoder.devcloud.web.model.vo.user.UserVO;
-
 public interface UserService {
 
-	UserVO register(RegisterVO form) throws ServiceException;
-
-	/**
-	 * 暂时没这个需求,先保留
-	 */
-	@Deprecated
-	UserVO registerTeacher(RegisterVO form) throws ServiceException;
-
-	void delete(int userId) throws ServiceException;
-
-	UserVO getUserById(Integer userid);
-
-	UserVO changeUserInfo(Integer userid, String nickName) throws ServiceException;
 
-	void changePassword(ChangePasswordVO form) throws ServiceException;
 
 }

+ 4 - 0
web/src/main/resources/application-wph.yml

@@ -25,6 +25,10 @@ mybatis:
     map-underscore-to-camel-case: true
 
 seecoder:
+  jwt:
+    secret: SEEC-1919810-OIDC-114514
+    expiration: 3600000
+
   k8s:
     api-server: https://192.168.99.105:8443
     token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjBmSXc4RlRjNUpBYVpGYWc4QzRDY1MzUWJad1JMdFhKcDI1cngzWGtiRlkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXZjbG91ZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXNicXY4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5NmIxNzU1ZS0zZjE3LTQ1ZTctODFmYi01MTRhODA3NDRhMzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGV2Y2xvdWQ6ZGVmYXVsdCJ9.W0Y1lR6LBi1ZjylBx35YeqYuq2u2AqH-ayK4FD-LDfC26E89DanOwSv9XLrRMnnDBZFS_ZCRBumbnDeMiS5vw2x7-QnrDqj1M5u9FB2fIJsz2LyUkOhATZZmTzj_Uhewvvg09aDKh16ttj6ZX27m-KVk_6MP-VfiuvZnCVxDbqRkRjK-zsor4ty1CEATPyKK-tvugAwS0RFNHUL94DamfZAq_t1PSnH5ZtEHq0uEMZxY2c7j6u9d_aD9lphm_ZpCy_C8OCHfanM21CQPDHlcJTW_aiOO6bAp8qdc1egPO5uIamHl6Zm0N3RkcsRp4DGOHrltTV9y_cGZHXSWmRHfxw

+ 10 - 2
web/src/main/resources/devcloud-k8s-init

@@ -3,7 +3,15 @@ kind: Namespace
 metadata:
   name: devcloud
 ---
-# todo 学生镜像secret创建
+# todo 私有仓库secret创建
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: admin
+  namespace: devcloud
+imagePullSecrets:
+  - name: # todo 私有仓库secret名字
 ---
 # 用来帮助学生部署项目的权限角色
 apiVersion: rbac.authorization.k8s.io/v1
@@ -24,7 +32,7 @@ metadata:
   name: devcloud-crb
 subjects:
   - kind: ServiceAccount
-    name: default # Name is case sensitive
+    name: admin
     namespace: devcloud
     apiGroup: ""
 roleRef:

+ 110 - 111
web/src/test/java/seecoder/devcloud/web/service/user/UserServiceTest.java

@@ -1,111 +1,110 @@
-package seecoder.devcloud.web.service.user;
-
-import org.gitlab4j.api.GitLabApi;
-import org.gitlab4j.api.models.AbstractUser;
-import org.junit.Assert;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.runner.RunWith;
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-import seecoder.devcloud.api.ApplicationProperties;
-import seecoder.devcloud.common.exceptions.ServiceException;
-import seecoder.devcloud.web.model.vo.user.ChangePasswordVO;
-import seecoder.devcloud.web.model.vo.user.RegisterVO;
-import seecoder.devcloud.web.model.vo.user.UserVO;
-
-import java.util.stream.Collectors;
-
-/**
- * @author PuHong Weng
- * @date 2021/3/2
- * @description: 与gitlab交互,没有办法配事务,只能手动测试。mvn test的时候请排除这个类
- */
-@RunWith(SpringRunner.class)
-@SpringBootTest
-@MapperScan(basePackages = {"seecoder.devcloud.web.dao"})
-class UserServiceTest {
-
-    @Autowired
-    UserService userService;
-
-    @Autowired
-    ApplicationProperties properties;
-
-    /**
-     * 注意 GitlabApi 和 GitLabApi 区别
-     * GitlabApi 是我们对 GitLabApi 的一个小封装
-     * 这里作辅助测试用
-     */
-    GitLabApi gitLabApi;
-
-    @BeforeEach
-    void setUp() {
-        gitLabApi = new GitLabApi(properties.getGitlab().getHost(), properties.getGitlab().getToken());
-    }
-
-    @Test
-    void register() {
-        RegisterVO registerVO = RegisterVO.builder()
-                .username("gfygfytest")
-                .password("gfygfytest")
-                .email("308213885@qq.com")
-                .nickname("kennyday")
-                .build();
-        try {
-            System.out.println(userService.register(registerVO));
-        } catch (ServiceException e){
-            e.printStackTrace();
-            Assert.fail(e.getMessage());
-        }
-    }
-
-    @Test
-    void delete() {
-        try {
-            userService.delete(37);
-            //gitLabApi.getUserApi().deleteUser(35);
-            System.out.println(gitLabApi.getUserApi().getActiveUsers().stream().map(AbstractUser::getId).collect(Collectors.toList()));
-        } catch (Exception e) {
-            e.printStackTrace();
-            Assert.fail(e.getMessage());
-        }
-
-    }
-
-    @Test
-    void getUserById() {
-        try {
-            UserVO u = userService.getUserById(25);
-            Assert.assertNotNull(u);
-            System.out.println(u);
-        } catch (Exception e) {
-            e.printStackTrace();
-            Assert.fail(e.getMessage());
-        }
-    }
-
-    @Test
-    void changeUserInfo() {
-        try {
-            userService.changeUserInfo(31,"gogoing");
-        } catch (ServiceException e) {
-            e.printStackTrace();
-            Assert.fail(e.getMessage());
-        }
-    }
-
-
-    @Test
-    void changeUserPassword() {
-        try {
-
-            userService.changePassword(new ChangePasswordVO(25,"1234qwer","1234qwer1","1234qwer1"));
-        } catch (ServiceException e) {
-            e.printStackTrace();
-            Assert.fail(e.getMessage());
-        }
-    }
-}
+//package seecoder.devcloud.web.service.user;
+//
+//import org.gitlab4j.api.GitLabApi;
+//import org.gitlab4j.api.models.AbstractUser;
+//import org.junit.Assert;
+//import org.junit.jupiter.api.BeforeEach;
+//import org.junit.jupiter.api.Test;
+//import org.junit.runner.RunWith;
+//import org.mybatis.spring.annotation.MapperScan;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.boot.test.context.SpringBootTest;
+//import org.springframework.test.context.junit4.SpringRunner;
+//import seecoder.devcloud.api.ApplicationProperties;
+//import seecoder.devcloud.common.exceptions.ServiceException;
+//import seecoder.devcloud.web.model.vo.user.RegisterVO;
+//import seecoder.devcloud.web.model.vo.user.UserVO;
+//
+//import java.util.stream.Collectors;
+//
+///**
+// * @author PuHong Weng
+// * @date 2021/3/2
+// * @description: 与gitlab交互,没有办法配事务,只能手动测试。mvn test的时候请排除这个类
+// */
+//@RunWith(SpringRunner.class)
+//@SpringBootTest
+//@MapperScan(basePackages = {"seecoder.devcloud.web.dao"})
+//class UserServiceTest {
+//
+//    @Autowired
+//    UserService userService;
+//
+//    @Autowired
+//    ApplicationProperties properties;
+//
+//    /**
+//     * 注意 GitlabApi 和 GitLabApi 区别
+//     * GitlabApi 是我们对 GitLabApi 的一个小封装
+//     * 这里作辅助测试用
+//     */
+//    GitLabApi gitLabApi;
+//
+//    @BeforeEach
+//    void setUp() {
+//        gitLabApi = new GitLabApi(properties.getGitlab().getHost(), properties.getGitlab().getToken());
+//    }
+//
+//    @Test
+//    void register() {
+//        RegisterVO registerVO = RegisterVO.builder()
+//                .username("gfygfytest")
+//                .password("gfygfytest")
+//                .email("308213885@qq.com")
+//                .nickname("kennyday")
+//                .build();
+//        try {
+//            System.out.println(userService.register(registerVO));
+//        } catch (ServiceException e){
+//            e.printStackTrace();
+//            Assert.fail(e.getMessage());
+//        }
+//    }
+//
+//    @Test
+//    void delete() {
+//        try {
+//            userService.delete(37);
+//            //gitLabApi.getUserApi().deleteUser(35);
+//            System.out.println(gitLabApi.getUserApi().getActiveUsers().stream().map(AbstractUser::getId).collect(Collectors.toList()));
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            Assert.fail(e.getMessage());
+//        }
+//
+//    }
+//
+//    @Test
+//    void getUserById() {
+//        try {
+//            UserVO u = userService.getUserById(25);
+//            Assert.assertNotNull(u);
+//            System.out.println(u);
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            Assert.fail(e.getMessage());
+//        }
+//    }
+//
+//    @Test
+//    void changeUserInfo() {
+//        try {
+//            userService.changeUserInfo(31,"gogoing");
+//        } catch (ServiceException e) {
+//            e.printStackTrace();
+//            Assert.fail(e.getMessage());
+//        }
+//    }
+//
+//
+//    @Test
+//    void changeUserPassword() {
+//        try {
+//
+//            userService.changePassword(new ChangePasswordVO(25,"1234qwer","1234qwer1","1234qwer1"));
+//        } catch (ServiceException e) {
+//            e.printStackTrace();
+//            Assert.fail(e.getMessage());
+//        }
+//    }
+//}