[+/M] Add new node /user/login and test, reformat code.
This commit is contained in:
@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
import javax.validation.constraints.Pattern;
|
import javax.validation.constraints.Pattern;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
@Validated
|
@Validated
|
||||||
@RestController
|
@RestController
|
||||||
@@ -65,16 +66,30 @@ public class UserController {
|
|||||||
return DigestUtils.md5DigestAsHex(beforeMd5.getBytes()).toLowerCase();
|
return DigestUtils.md5DigestAsHex(beforeMd5.getBytes()).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/delete")
|
// Check username & password.
|
||||||
public synchronized ResponseEntity<String> delete(@RequestHeader String username, @RequestHeader String password) {
|
// user not exists -> http 404, password not match -> http 401; all match -> do and return do's result String.
|
||||||
|
private ResponseEntity<String> checkPasswordAndDo(String username, String password,
|
||||||
|
Function<User, String> operation) {
|
||||||
User user = userRepository.queryByUsername(username);
|
User user = userRepository.queryByUsername(username);
|
||||||
if (user == null) return ResponseEntity.notFound().build();
|
if (user == null) return ResponseEntity.notFound().build();
|
||||||
|
|
||||||
if (user.getPasswordMd5().equals(userToSaltedMd5(username, password))) {
|
if (!user.getPasswordMd5().equals(userToSaltedMd5(username, password)))
|
||||||
userRepository.delete(user);
|
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||||
return ResponseEntity.ok("");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("");
|
String result = operation.apply(user);
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete")
|
||||||
|
public synchronized ResponseEntity<String> delete(@RequestHeader String username, @RequestHeader String password) {
|
||||||
|
return checkPasswordAndDo(username, password, user -> {
|
||||||
|
userRepository.delete(user);
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("login")
|
||||||
|
public synchronized ResponseEntity<String> login(@RequestHeader String username, @RequestHeader String password) {
|
||||||
|
return checkPasswordAndDo(username, password, user -> userRepository.queryByUsername(username).getUuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,6 @@ import org.springframework.stereotype.Repository;
|
|||||||
public interface UserRepository extends JpaRepository<User, String> {
|
public interface UserRepository extends JpaRepository<User, String> {
|
||||||
// https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
|
// https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
|
||||||
boolean existsByUsername(String username);
|
boolean existsByUsername(String username);
|
||||||
|
|
||||||
User queryByUsername(String username);
|
User queryByUsername(String username);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.hydev.clock_api
|
package org.hydev.clock_api
|
||||||
|
|
||||||
import org.hamcrest.Matchers
|
import org.hamcrest.Matchers
|
||||||
|
import org.hamcrest.Matchers.matchesPattern
|
||||||
import org.hydev.clock_api.entity.User
|
import org.hydev.clock_api.entity.User
|
||||||
import org.hydev.clock_api.error.ErrorCode.*
|
import org.hydev.clock_api.error.ErrorCode.*
|
||||||
import org.hydev.clock_api.repository.UserRepository
|
import org.hydev.clock_api.repository.UserRepository
|
||||||
@@ -44,6 +45,7 @@ class UserRegisterDeleteNodeTest {
|
|||||||
private const val TEST_NODE = "/user"
|
private const val TEST_NODE = "/user"
|
||||||
private const val REGISTER_NODE = "${TEST_NODE}/register"
|
private const val REGISTER_NODE = "${TEST_NODE}/register"
|
||||||
private const val DELETE_NODE = "${TEST_NODE}/delete"
|
private const val DELETE_NODE = "${TEST_NODE}/delete"
|
||||||
|
private const val LOGIN_NODE = "${TEST_NODE}/login"
|
||||||
|
|
||||||
private const val H_USERNAME = "username"
|
private const val H_USERNAME = "username"
|
||||||
private const val V_USERNAME = "vanilla"
|
private const val V_USERNAME = "vanilla"
|
||||||
@@ -194,4 +196,21 @@ class UserRegisterDeleteNodeTest {
|
|||||||
assertEquals(false, userRepository.existsByUsername(V_USERNAME))
|
assertEquals(false, userRepository.existsByUsername(V_USERNAME))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testUserLogin() {
|
||||||
|
mockMvc.perform(post(REGISTER_NODE).header(H_USERNAME, V_USERNAME).header(H_PASSWORD, V_PASSWORD))
|
||||||
|
// https://stackoverflow.com/questions/49722217/how-do-i-validate-a-json-field-is-formatted-correctly-using-mockmvcresultmatcher
|
||||||
|
.andExpect(status().isOk)
|
||||||
|
.andExpect(content().string(matchesPattern(R_UUID)))
|
||||||
|
.andDo {
|
||||||
|
// Missing field, username not exists, password not match cases already test in testDeleteUser().
|
||||||
|
// Test successful login cases, status 200 and current user's uuid.
|
||||||
|
mockMvc.perform(post(LOGIN_NODE).header(H_USERNAME, V_USERNAME).header(H_PASSWORD, V_PASSWORD))
|
||||||
|
.andExpect(status().isOk)
|
||||||
|
.andExpect(content().string(it.response.contentAsString))
|
||||||
|
|
||||||
|
userRepository.deleteById(it.response.contentAsString)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user