Steffen Nitschke
4 years ago
32 changed files with 1444 additions and 4 deletions
-
16Multi-Chess.xml
-
12build.gradle
-
9fh.fd.ci.server/build.gradle
-
45fh.fd.ci.server/src/main/java/de/fd/fh/ServerApp.java
-
46fh.fd.ci.server/src/main/java/de/fd/fh/server/access/Access.java
-
28fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessContextEventListener.java
-
58fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessRepository.java
-
152fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessService.java
-
62fh.fd.ci.server/src/main/java/de/fd/fh/server/access/AccessToken.java
-
6fh.fd.ci.server/src/main/java/de/fd/fh/server/access/Role.java
-
13fh.fd.ci.server/src/main/java/de/fd/fh/server/access/events/AccountCreatedEvent.java
-
12fh.fd.ci.server/src/main/java/de/fd/fh/server/access/events/AccountDeletedEvent.java
-
104fh.fd.ci.server/src/main/java/de/fd/fh/server/access/web/AccessController.java
-
26fh.fd.ci.server/src/main/java/de/fd/fh/server/user/User.java
-
43fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserContextEventListener.java
-
25fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserId.java
-
52fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserRepository.java
-
48fh.fd.ci.server/src/main/java/de/fd/fh/server/user/UserService.java
-
18fh.fd.ci.server/src/main/java/de/fd/fh/server/user/events/ChangePasswordEvent.java
-
13fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/ChangeUserRequest.java
-
89fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserController.java
-
13fh.fd.ci.server/src/main/java/de/fd/fh/server/user/web/UserRequest.java
-
36fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessContextEventListenerTest.java
-
42fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessRepositoryTest.java
-
245fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessServiceTest.java
-
31fh.fd.ci.server/src/test/java/de/fd/fh/server/access/AccessTokenTest.java
-
51fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserContextEventListenerTest.java
-
40fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserRepositoryTest.java
-
84fh.fd.ci.server/src/test/java/de/fd/fh/server/user/UserServiceTest.java
-
6fh.fd.ci.shared/src/main/java/de/fd/fh/shared/Utils.java
-
11fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/LoginRequest.java
-
12fh.fd.ci.shared/src/main/java/de/fd/fh/shared/network/messages/RegistrateRequest.java
@ -0,0 +1,16 @@ |
|||
<code_scheme name="Multi-Chess" version="173"> |
|||
<option name="FORMATTER_TAGS_ENABLED" value="true" /> |
|||
<codeStyleSettings language="JAVA"> |
|||
<option name="BRACE_STYLE" value="2" /> |
|||
<option name="CLASS_BRACE_STYLE" value="2" /> |
|||
<option name="METHOD_BRACE_STYLE" value="2" /> |
|||
<option name="LAMBDA_BRACE_STYLE" value="2" /> |
|||
<option name="ELSE_ON_NEW_LINE" value="true" /> |
|||
<option name="CATCH_ON_NEW_LINE" value="true" /> |
|||
<option name="FINALLY_ON_NEW_LINE" value="true" /> |
|||
<option name="IF_BRACE_FORCE" value="3" /> |
|||
<option name="DOWHILE_BRACE_FORCE" value="3" /> |
|||
<option name="WHILE_BRACE_FORCE" value="3" /> |
|||
<option name="FOR_BRACE_FORCE" value="3" /> |
|||
</codeStyleSettings> |
|||
</code_scheme> |
@ -1,12 +1,57 @@ |
|||
package de.fd.fh; |
|||
|
|||
import de.fd.fh.server.access.AccessContextEventListener; |
|||
import de.fd.fh.server.access.AccessRepository; |
|||
import de.fd.fh.server.access.AccessService; |
|||
import de.fd.fh.server.access.web.AccessController; |
|||
import de.fd.fh.server.user.UserContextEventListener; |
|||
import de.fd.fh.server.user.web.UserController; |
|||
import de.fd.fh.server.user.UserRepository; |
|||
import de.fd.fh.server.user.UserService; |
|||
|
|||
|
|||
import java.util.HashSet; |
|||
import java.util.Observable; |
|||
import java.util.Observer; |
|||
import java.util.Set; |
|||
|
|||
import static spark.Spark.*; |
|||
|
|||
public class ServerApp |
|||
{ |
|||
private static AccessRepository accessRepository; |
|||
private static UserRepository userRepository; |
|||
|
|||
private static final Set<Observer> listeners = new HashSet<>(); |
|||
|
|||
public static void main(String[] args) |
|||
{ |
|||
initRepositories(); |
|||
|
|||
initListeners(); |
|||
|
|||
new AccessController((AccessService) addListeners(new AccessService(accessRepository))); |
|||
new UserController((UserService) addListeners(new UserService(userRepository))); |
|||
|
|||
get("/hello", (req, res) -> "Hello World"); |
|||
|
|||
} |
|||
|
|||
private static Object addListeners(Observable service) |
|||
{ |
|||
listeners.forEach(service::addObserver); |
|||
|
|||
return service; |
|||
} |
|||
|
|||
private static void initListeners() |
|||
{ |
|||
listeners.add(new AccessContextEventListener(accessRepository)); |
|||
listeners.add(new UserContextEventListener(userRepository)); |
|||
} |
|||
|
|||
private static void initRepositories() { |
|||
accessRepository = new AccessRepository(); |
|||
userRepository = new UserRepository(); |
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import de.fd.fh.server.user.UserId; |
|||
import dev.morphia.annotations.Embedded; |
|||
import dev.morphia.annotations.Entity; |
|||
import dev.morphia.annotations.Id; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
@Entity("login") |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Getter |
|||
public class Access |
|||
{ |
|||
@Id |
|||
private String _id; |
|||
|
|||
private String name; |
|||
|
|||
private String password; |
|||
|
|||
@Embedded |
|||
private UserId userId; |
|||
|
|||
@Embedded |
|||
private AccessToken token; |
|||
|
|||
private Role role; |
|||
|
|||
void removeToken() |
|||
{ |
|||
this.token = null; |
|||
} |
|||
|
|||
void setToken(final AccessToken token) |
|||
{ |
|||
this.token = token; |
|||
} |
|||
|
|||
void updatePassword(final String newPassword) |
|||
{ |
|||
this.password = newPassword; |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import de.fd.fh.server.user.events.ChangePasswordEvent; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
import java.util.Observable; |
|||
import java.util.Observer; |
|||
|
|||
@RequiredArgsConstructor |
|||
public class AccessContextEventListener implements Observer |
|||
{ |
|||
private final AccessRepository accessRepository; |
|||
|
|||
@Override |
|||
public void update(Observable observable, Object o) |
|||
{ |
|||
if(o instanceof ChangePasswordEvent) |
|||
{ |
|||
final ChangePasswordEvent event = (ChangePasswordEvent) o; |
|||
|
|||
final Access access = accessRepository.findByUserId(event.getUserId()); |
|||
|
|||
access.updatePassword(event.getNewPassword()); |
|||
|
|||
accessRepository.save(access); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,58 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import com.mongodb.MongoClient; |
|||
import com.mongodb.WriteResult; |
|||
import de.fd.fh.server.user.UserId; |
|||
import dev.morphia.Datastore; |
|||
import dev.morphia.Key; |
|||
import dev.morphia.Morphia; |
|||
|
|||
public class AccessRepository |
|||
{ |
|||
private final Datastore datastore; |
|||
|
|||
public AccessRepository() |
|||
{ |
|||
System.out.println("AccessRepo"); |
|||
final Morphia morphia = new Morphia(); |
|||
|
|||
morphia.mapPackage("de.fd.fh.server.access"); |
|||
|
|||
this.datastore = morphia.createDatastore(new MongoClient(), "smartwarfare"); |
|||
datastore.ensureIndexes(); |
|||
} |
|||
|
|||
AccessRepository(Datastore datastore) |
|||
{ |
|||
this.datastore = datastore; |
|||
} |
|||
|
|||
public Key<Access> save(final Access access) |
|||
{ |
|||
return datastore.save(access); |
|||
} |
|||
|
|||
Access findByUserName(final String name) |
|||
{ |
|||
return datastore.createQuery(Access.class) |
|||
.field("name").equal(name).first(); |
|||
} |
|||
|
|||
Access findByToken(final String token) |
|||
{ |
|||
return datastore.createQuery(Access.class) |
|||
.field("token.token").equal(token).first(); |
|||
} |
|||
|
|||
Access findByUserId(final UserId userId) |
|||
{ |
|||
return datastore.createQuery(Access.class) |
|||
.field("userId.identifier").equal(userId.getIdentifier()).first(); |
|||
} |
|||
|
|||
WriteResult deleteLoginByUserId(final UserId userId) |
|||
{ |
|||
return datastore.delete(datastore.createQuery(Access.class) |
|||
.field("userId.identifier").equal(userId.getIdentifier()).first()); |
|||
} |
|||
} |
@ -0,0 +1,152 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import de.fd.fh.server.access.events.AccountCreatedEvent; |
|||
import de.fd.fh.server.access.events.AccountDeletedEvent; |
|||
import de.fd.fh.server.user.UserId; |
|||
import de.fd.fh.shared.network.messages.LoginRequest; |
|||
import de.fd.fh.shared.network.messages.RegistrateRequest; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.bson.types.ObjectId; |
|||
|
|||
import java.util.Base64; |
|||
import java.util.Observable; |
|||
|
|||
import static spark.Spark.halt; |
|||
|
|||
@RequiredArgsConstructor |
|||
public class AccessService extends Observable |
|||
{ |
|||
private final AccessRepository accessRepository; |
|||
|
|||
public AccessToken before(final String path, final String token) { |
|||
System.out.println("Pfad: " + path); |
|||
if (!(path.equals("/accounts/login") |
|||
|| path.equals("/accounts/registrate") |
|||
)) |
|||
{ |
|||
final AccessToken accessToken = authenticate(token); |
|||
|
|||
if (accessToken == null) |
|||
{ |
|||
halt(401); |
|||
} |
|||
return accessToken; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private AccessToken authenticate(final String bearerToken) |
|||
{ |
|||
return accessRepository.findByToken(bearerToken.substring("Bearer ".length())).getToken(); |
|||
} |
|||
|
|||
public boolean createPlayer(RegistrateRequest message) |
|||
{ |
|||
System.out.println("createPlayer: " + message); |
|||
|
|||
if (userNameDoesNotExist(message.getUserName())) |
|||
{ |
|||
System.out.println("Name does exist."); |
|||
return false; |
|||
} |
|||
|
|||
final Access access = new Access( |
|||
new ObjectId().toHexString(), |
|||
message.getUserName(), |
|||
message.getPassword(), |
|||
UserId.random(), |
|||
null, |
|||
Role.USER |
|||
); |
|||
|
|||
accessRepository.save(access); |
|||
|
|||
setChanged(); |
|||
notifyObservers(new AccountCreatedEvent(access.getName(), |
|||
access.getUserId())); |
|||
|
|||
System.out.println("DBLogin: " + access); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
private boolean userNameDoesNotExist(final String name) |
|||
{ |
|||
final Access user = accessRepository.findByUserName(name); |
|||
return user != null; |
|||
} |
|||
|
|||
public boolean logout(final String header) |
|||
{ |
|||
try |
|||
{ |
|||
System.out.println("logout " + header); |
|||
|
|||
final Access access = accessRepository.findByToken(header.substring("Bearer ".length())); |
|||
|
|||
access.removeToken(); |
|||
|
|||
accessRepository.save(access); |
|||
|
|||
return true; |
|||
} catch (Exception e) |
|||
{ |
|||
e.printStackTrace(); |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public LoginRequest authorization(final String header) |
|||
{ |
|||
System.out.println("authorization"); |
|||
final String auth = header.substring("Basic ".length()); |
|||
|
|||
try |
|||
{ |
|||
byte[] message = Base64.getDecoder().decode(auth); |
|||
|
|||
String messageStr = new String(message); |
|||
String[] user_password = messageStr.split(":"); |
|||
|
|||
final Access access = accessRepository.findByUserName(user_password[0]); |
|||
|
|||
System.out.println(access.getName()); |
|||
if (user_password[1].equals(access.getPassword())) |
|||
{ |
|||
access.setToken(AccessToken.of(access)); |
|||
accessRepository.save(access); |
|||
|
|||
final LoginRequest loginRequest = new LoginRequest(); |
|||
loginRequest.setUserId(access.getUserId().getIdentifier()); |
|||
loginRequest.setToken(access.getToken().getToken()); |
|||
loginRequest.setName(access.getName()); |
|||
|
|||
return loginRequest; |
|||
} |
|||
|
|||
return null; |
|||
} catch (Exception e) |
|||
{ |
|||
e.printStackTrace(); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
public boolean deleteAccount(final UserId userId, final AccessToken token) |
|||
{ |
|||
if (!token.getUserId().getIdentifier() |
|||
.equals(userId.getIdentifier())) |
|||
{ |
|||
return false; |
|||
} |
|||
if (accessRepository.deleteLoginByUserId(userId).wasAcknowledged()) |
|||
{ |
|||
setChanged(); |
|||
notifyObservers(new AccountDeletedEvent(userId)); |
|||
|
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
} |
@ -0,0 +1,62 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import de.fd.fh.server.user.UserId; |
|||
import dev.morphia.annotations.Embedded; |
|||
import dev.morphia.annotations.PrePersist; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Getter; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.time.LocalDateTime; |
|||
import java.util.Random; |
|||
|
|||
@Embedded |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Getter |
|||
public class AccessToken |
|||
{ |
|||
private String token; |
|||
|
|||
private LocalDateTime createdDate; |
|||
|
|||
private Role role; |
|||
|
|||
@Embedded |
|||
private UserId userId; |
|||
|
|||
static AccessToken of(final Access access) |
|||
{ |
|||
return new AccessToken( |
|||
generateToken(), |
|||
LocalDateTime.now(), |
|||
access.getRole(), |
|||
access.getUserId() |
|||
); |
|||
} |
|||
|
|||
@PrePersist |
|||
void prePersist() |
|||
{ |
|||
this.createdDate = LocalDateTime.now(); |
|||
} |
|||
|
|||
private static String generateToken() |
|||
{ |
|||
final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
|||
final String lower = upper.toLowerCase(); |
|||
final String numbers = "0123456789"; |
|||
final String alphabet = upper + lower + numbers; |
|||
|
|||
System.out.println("generate Security Token."); |
|||
|
|||
Random random = new Random(); |
|||
StringBuilder generatedString = new StringBuilder(); |
|||
for (int i = 0; i < 64; i++) { |
|||
generatedString.append(alphabet.charAt(random.nextInt(alphabet.length()))); |
|||
} |
|||
|
|||
System.out.println("Token: " + generatedString); |
|||
return generatedString.toString(); |
|||
} |
|||
} |
@ -0,0 +1,6 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
public enum Role |
|||
{ |
|||
ADMIN, USER |
|||
} |
@ -0,0 +1,13 @@ |
|||
package de.fd.fh.server.access.events; |
|||
|
|||
import de.fd.fh.server.user.UserId; |
|||
import lombok.Getter; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
@RequiredArgsConstructor |
|||
@Getter |
|||
public class AccountCreatedEvent |
|||
{ |
|||
private final String name; |
|||
private final UserId userId; |
|||
} |
@ -0,0 +1,12 @@ |
|||
package de.fd.fh.server.access.events; |
|||
|
|||
import de.fd.fh.server.user.UserId; |
|||
import lombok.Getter; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
@RequiredArgsConstructor |
|||
@Getter |
|||
public class AccountDeletedEvent |
|||
{ |
|||
private final UserId userId; |
|||
} |
@ -0,0 +1,104 @@ |
|||
package de.fd.fh.server.access.web; |
|||
|
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import de.fd.fh.server.access.AccessService; |
|||
import de.fd.fh.server.access.AccessToken; |
|||
import de.fd.fh.server.user.UserId; |
|||
import de.fd.fh.shared.Utils; |
|||
import de.fd.fh.shared.network.messages.LoginRequest; |
|||
import de.fd.fh.shared.network.messages.RegistrateRequest; |
|||
|
|||
import static spark.Spark.*; |
|||
|
|||
public class AccessController |
|||
{ |
|||
private final ObjectMapper objectMapper = new ObjectMapper(); |
|||
|
|||
public AccessController(final AccessService service) |
|||
{ |
|||
before("/*", |
|||
(req, res) -> |
|||
{ |
|||
final String path = req.pathInfo(); |
|||
final String token = req.headers(Utils.AUTHENTICATION_HEADER); |
|||
|
|||
final AccessToken accessToken = service.before(path, token); |
|||
|
|||
req.session().attribute("userId", |
|||
accessToken); |
|||
}); |
|||
|
|||
post("/accounts/registrate", |
|||
(request, response) -> |
|||
{ |
|||
final RegistrateRequest message = |
|||
objectMapper.readValue(request.body(), RegistrateRequest.class); |
|||
|
|||
if (service.createPlayer(message)) |
|||
{ |
|||
response.status(201); |
|||
} |
|||
else |
|||
{ |
|||
response.status(400); |
|||
} |
|||
return response; |
|||
} |
|||
); |
|||
|
|||
post("/accounts/login", |
|||
(request, response) -> |
|||
{ |
|||
final String header = request.headers(Utils.AUTHENTICATION_HEADER); |
|||
|
|||
final LoginRequest login = service.authorization(header); |
|||
|
|||
if (login == null) |
|||
{ |
|||
response.status(401); |
|||
} |
|||
else |
|||
{ |
|||
response.status(200); |
|||
response.type("application/json"); |
|||
response.body(objectMapper.writeValueAsString(login)); |
|||
} |
|||
return response; |
|||
}); |
|||
|
|||
post("/accounts/logout", |
|||
(request, response) -> |
|||
{ |
|||
final String token = request.headers(Utils.AUTHENTICATION_HEADER); |
|||
|
|||
if (service.logout(token)) |
|||
{ |
|||
response.status(200); |
|||
} |
|||
else |
|||
{ |
|||
response.status(400); |
|||
} |
|||
|
|||
return response; |
|||
}); |
|||
|
|||
delete("/accounts/:player_id", |
|||
(request, response) -> |
|||
{ |
|||
final UserId userId = UserId.of(request.params(":player_id")); |
|||
final AccessToken token = request.session().attribute("userId"); |
|||
|
|||
if (service.deleteAccount(userId, token)) |
|||
{ |
|||
response.status(200); |
|||
} |
|||
else |
|||
{ |
|||
response.status(400); |
|||
} |
|||
|
|||
return response; |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
package de.fd.fh.server.user; |
|||
|
|||
import lombok.*; |
|||
|
|||
@AllArgsConstructor |
|||
@Getter |
|||
public class User { |
|||
|
|||
private final UserId id; |
|||
|
|||
private String name; |
|||
|
|||
public static User of(String name) |
|||
{ |
|||
return new User(null, name); |
|||
} |
|||
|
|||
public void rename(String name) |
|||
{ |
|||
if (name == null) |
|||
{ |
|||
return; |
|||
} |
|||
this.name = name; |
|||
} |
|||
} |
@ -0,0 +1,43 @@ |
|||
package de.fd.fh.server.user; |
|||
|
|||
import de.fd.fh.server.access.events.AccountCreatedEvent; |
|||
import de.fd.fh.server.access.events.AccountDeletedEvent; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
import java.util.Observable; |
|||
import java.util.Observer; |
|||
|
|||
@RequiredArgsConstructor |
|||
public class UserContextEventListener implements Observer |
|||
{ |
|||
private final UserRepository userRepository; |
|||
|
|||
@Override |
|||
public void update( |
|||
final Observable observable, |
|||
final Object event) |
|||
{ |
|||
System.out.println("UserContextEventListener " + event); |
|||
if (event instanceof AccountCreatedEvent) { |
|||
handleAccountCreatedEvent((AccountCreatedEvent) event); |
|||
} |
|||
if (event instanceof AccountDeletedEvent) { |
|||
handleAccountDeletedEvent((AccountDeletedEvent) event); |
|||
} |
|||
} |
|||
|
|||
private void handleAccountDeletedEvent(final AccountDeletedEvent event) |
|||
{ |
|||
userRepository.deleteUserById(event.getUserId()); |
|||
} |
|||
|
|||
private void handleAccountCreatedEvent(final AccountCreatedEvent event) |
|||
{ |
|||
System.out.println("handleAccountCreatedEvent " + event); |
|||
final User user = new User(event.getUserId(), event.getName()); |
|||
System.out.println("User: " + user); |
|||
|
|||
userRepository.save(user); |
|||
System.out.println("UserId: " + user.getId()); |
|||
} |
|||
} |
@ -0,0 +1,25 @@ |
|||
package de.fd.fh.server.user; |
|||
|
|||
import dev.morphia.annotations.Embedded; |
|||
import lombok.*; |
|||
import org.bson.types.ObjectId; |
|||
|
|||
@Getter |
|||
@Embedded |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor(access = AccessLevel.PRIVATE) |
|||
@EqualsAndHashCode(of = {"identifier"}) |
|||
public class UserId |
|||
{ |
|||
private String identifier; |
|||
|
|||
public static UserId of(final String identifier) |
|||
{ |
|||
return new UserId(identifier); |
|||
} |
|||
|
|||
public static UserId random() |
|||
{ |
|||
return new UserId(new ObjectId().toHexString()); |
|||
} |
|||
} |
@ -0,0 +1,52 @@ |
|||
package de.fd.fh.server.user; |
|||
|
|||
import com.mongodb.MongoClient; |
|||
import com.mongodb.WriteResult; |
|||
import dev.morphia.Datastore; |
|||
import dev.morphia.Key; |
|||
import dev.morphia.Morphia; |
|||
|
|||
public class UserRepository { |
|||
|
|||
private final Datastore datastore; |
|||
|
|||
public UserRepository() |
|||
{ |
|||
System.out.println("UserRepo"); |
|||
final Morphia morphia = new Morphia(); |
|||
|
|||
morphia.mapPackage("de.fd.fh.server.user"); |
|||
|
|||
this.datastore = morphia.createDatastore(new MongoClient(), "smartwarfare"); |
|||
datastore.ensureIndexes(); |
|||
} |
|||
|
|||
UserRepository(Datastore datastore) |
|||
{ |
|||
this.datastore = datastore; |
|||
} |
|||
|
|||
public Key<User> save(final User user) |
|||
{ |
|||
return datastore.save(user); |
|||
} |
|||
|
|||
public User findUserById(final UserId userId) |
|||
{ |
|||
return datastore.createQuery(User.class) |
|||
.field("_id.identifier").equal(userId.getIdentifier()) |
|||
.first(); |
|||
} |
|||
|
|||
public User findUserByName(final String name) |
|||
{ |
|||
return datastore.createQuery(User.class) |
|||
.field("name").equal(name) |
|||
.first(); |
|||
} |
|||
|
|||
WriteResult deleteUserById(final UserId userId) |
|||
{ |
|||
return datastore.delete(findUserById(userId)); |
|||
} |
|||
} |
@ -0,0 +1,48 @@ |
|||
package de.fd.fh.server.user; |
|||
|
|||
import de.fd.fh.server.user.events.ChangePasswordEvent; |
|||
import de.fd.fh.server.user.web.ChangeUserRequest; |
|||
import de.fd.fh.server.user.web.UserRequest; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
import java.util.Observable; |
|||
|
|||
@RequiredArgsConstructor |
|||
public class UserService extends Observable |
|||
{ |
|||
private final UserRepository userRepository; |
|||
|
|||
public User changePlayer(final UserId userId, final ChangeUserRequest message) |
|||
{ |
|||
System.out.println("changePlayer: " + message); |
|||
|
|||
User user = userRepository.findUserById(userId); |
|||
|
|||
if (message.getPassword() != null) |
|||
{ |
|||
setChanged(); |
|||
notifyObservers(new ChangePasswordEvent(userId, message.getPassword())); |
|||
} |
|||
|
|||
userRepository.save(user); |
|||
|
|||
return userRepository.findUserById(userId); |
|||
} |
|||
|
|||
public User getPlayer(final UserId id) |
|||
{ |
|||
return userRepository.findUserById(id); |
|||
} |
|||
|
|||
public UserRequest getSmallPlayer(final UserId userId) |
|||
{ |
|||
final User user = userRepository.findUserById(userId); |
|||
|
|||
if(user == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new UserRequest(user.getId().getIdentifier(), user.getName()); |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
package de.fd.fh.server.user.events; |
|||
|
|||
import de.fd.fh.server.user.UserId; |
|||
import lombok.Getter; |
|||
|
|||
@Getter |
|||
public class ChangePasswordEvent |
|||
{ |
|||
private final String newPassword; |
|||
|
|||
private final UserId userId; |
|||
|
|||
public ChangePasswordEvent(final UserId userId, final String password) |
|||
{ |
|||
this.newPassword = password; |
|||
this.userId = userId; |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
package de.fd.fh.server.user.web; |
|||
|
|||
import lombok.Getter; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
@RequiredArgsConstructor |
|||
@Getter |
|||
public class ChangeUserRequest |
|||
{ |
|||
private final String name; |
|||
|
|||
private final String password; |
|||
} |
@ -0,0 +1,89 @@ |
|||
package de.fd.fh.server.user.web; |
|||
|
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import de.fd.fh.server.access.AccessToken; |
|||
import de.fd.fh.server.user.User; |
|||
import de.fd.fh.server.user.UserId; |
|||
import de.fd.fh.server.user.UserService; |
|||
|
|||
import static spark.Spark.get; |
|||
import static spark.Spark.post; |
|||
|
|||
public class UserController |
|||
{ |
|||
private ObjectMapper objectMapper = new ObjectMapper(); |
|||
|
|||
public UserController(final UserService service) |
|||
{ |
|||
post("/users", |
|||
((request, response) -> |
|||
{ |
|||
final UserId userId = |
|||
((AccessToken) request.session() |
|||
.attribute("userId")) |
|||
.getUserId(); |
|||
|
|||
final ChangeUserRequest message = objectMapper.readValue(request.body(), |
|||
ChangeUserRequest.class); |
|||
|
|||
final User user = service.changePlayer( |
|||
userId, |
|||
message); |
|||
|
|||
if (user == null) |
|||
{ |
|||
response.status(400); |
|||
} |
|||
else |
|||
{ |
|||
response.status(200); |
|||
response.type("application/json"); |
|||
|
|||
return objectMapper.writeValueAsString(user); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
)); |
|||
|
|||
get("/users", |
|||
(request, response) -> |
|||
{ |
|||
final UserId userId = |
|||
((AccessToken) request.session() |
|||
.attribute("userId")) |
|||
.getUserId(); |
|||
|
|||
final User user = service.getPlayer(userId); |
|||
|
|||
if (user == null) |
|||
{ |
|||
response.status(400); |
|||
} |
|||
else |
|||
{ |
|||
response.status(200); |
|||
response.type("application/json"); |
|||
|
|||
return objectMapper.writeValueAsString(user); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
); |
|||
|
|||
get("/users/:user_id", |
|||
(request, response) -> |
|||
{ |
|||
final UserId userId = UserId.of(request.params(":user_id")); |
|||
final UserRequest user = service.getSmallPlayer(userId); |
|||
|
|||
if (user == null) |
|||
{ |
|||
response.status(404); |
|||
} |
|||
response.body(objectMapper.writeValueAsString(user)); |
|||
return response; |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
package de.fd.fh.server.user.web; |
|||
|
|||
import lombok.Getter; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
@RequiredArgsConstructor |
|||
@Getter |
|||
public class UserRequest |
|||
{ |
|||
private final String id; |
|||
|
|||
private final String name; |
|||
} |
@ -0,0 +1,36 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import de.fd.fh.server.user.UserId; |
|||
import de.fd.fh.server.user.UserRepository; |
|||
import de.fd.fh.server.user.UserService; |
|||
import de.fd.fh.server.user.events.ChangePasswordEvent; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.mockito.ArgumentCaptor; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
import static org.mockito.ArgumentMatchers.any; |
|||
import static org.mockito.BDDMockito.then; |
|||
import static org.mockito.Mockito.*; |
|||
|
|||
class AccessContextEventListenerTest |
|||
{ |
|||
@Test |
|||
void given_changePasswordEvent_when_passwordChanged_should_changePassword() |
|||
{ |
|||
final ChangePasswordEvent event = new ChangePasswordEvent(UserId.of("12345"), "newPwd"); |
|||
|
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
when(repository.findByUserId(any(UserId.class))) |
|||
.thenReturn(new Access()); |
|||
|
|||
final ArgumentCaptor<Access> captor = ArgumentCaptor.forClass(Access.class); |
|||
|
|||
new AccessContextEventListener(repository).update(null, event); |
|||
verify(repository).save(captor.capture()); |
|||
|
|||
assertEquals("newPwd", captor.getValue().getPassword(), "Have to be the new password"); |
|||
then(repository).should().findByUserId(any(UserId.class)); |
|||
then(repository).should().save(any(Access.class)); |
|||
then(repository).shouldHaveNoMoreInteractions(); |
|||
} |
|||
} |
@ -0,0 +1,42 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import de.fd.fh.server.user.UserId; |
|||
import dev.morphia.Datastore; |
|||
import dev.morphia.Key; |
|||
import org.junit.jupiter.api.BeforeEach; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.mockito.Mock; |
|||
|
|||
import static org.hamcrest.MatcherAssert.assertThat; |
|||
import static org.hamcrest.Matchers.notNullValue; |
|||
import static org.mockito.ArgumentMatchers.any; |
|||
import static org.mockito.BDDMockito.then; |
|||
import static org.mockito.Mockito.mock; |
|||
import static org.mockito.Mockito.when; |
|||
|
|||
class AccessRepositoryTest |
|||
{ |
|||
@Mock |
|||
private Datastore datastore; |
|||
|
|||
@BeforeEach |
|||
public void before() |
|||
{ |
|||
datastore = mock(Datastore.class); |
|||
} |
|||
|
|||
@Test |
|||
void given_newUser_when_saveUser_should_storeUserInDatabase() |
|||
{ |
|||
when(datastore.save(any(Access.class))) |
|||
.thenReturn(new Key<>(Access.class, "collection", "id")); |
|||
|
|||
final Access access = new Access("testId", "testName", "testPwd", UserId.of("userId"), |
|||
null, Role.USER); |
|||
|
|||
final Key<Access> result = new AccessRepository(datastore).save(access); |
|||
|
|||
assertThat("Key is null", result, notNullValue()); |
|||
then(datastore).should().save(any(Access.class)); |
|||
} |
|||
} |
@ -0,0 +1,245 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import com.mongodb.WriteResult; |
|||
import de.fd.fh.server.user.UserId; |
|||
import de.fd.fh.shared.network.messages.LoginRequest; |
|||
import de.fd.fh.shared.network.messages.RegistrateRequest; |
|||
import org.junit.jupiter.api.BeforeEach; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.mockito.ArgumentCaptor; |
|||
import spark.HaltException; |
|||
|
|||
import java.time.LocalDateTime; |
|||
import java.util.Base64; |
|||
import java.util.Observable; |
|||
import java.util.Observer; |
|||
|
|||
import static org.hamcrest.MatcherAssert.assertThat; |
|||
import static org.hamcrest.Matchers.notNullValue; |
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
import static org.mockito.ArgumentMatchers.any; |
|||
import static org.mockito.BDDMockito.then; |
|||
import static org.mockito.Mockito.*; |
|||
|
|||
class AccessServiceTest implements Observer |
|||
{ |
|||
private Object event; |
|||
|
|||
@BeforeEach |
|||
void before() |
|||
{ |
|||
this.event = null; |
|||
} |
|||
|
|||
@Test |
|||
void given_authenticatedUser_when_serverAuthenticateUser_should_authenticateUser() |
|||
{ |
|||
final Access access = new Access( |
|||
"testId", |
|||
"testName", |
|||
"testPwd", |
|||
UserId.of("12345"), |
|||
new AccessToken( |
|||
"testToken", |
|||
LocalDateTime.now(), |
|||
Role.USER, |
|||
UserId.of("12345") |
|||
), |
|||
Role.USER); |
|||
|
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
when(repository.findByToken(any())) |
|||
.thenReturn(access); |
|||
final String path = "/test/path"; |
|||
final String token = "testToken"; |
|||
|
|||
final AccessToken result = new AccessService(repository).before(path, token); |
|||
|
|||
assertThat("User is not authenticated", result, notNullValue()); |
|||
then(repository).should().findByToken(any()); |
|||
then(repository).shouldHaveNoMoreInteractions(); |
|||
} |
|||
|
|||
@Test |
|||
void given_notAuthenticatedUser_when_serverAuthenticateUser_should_denyUser() |
|||
{ |
|||
final Access access = new Access( |
|||
"testId", |
|||
"testName", |
|||
"testPwd", |
|||
UserId.of("12345"), |
|||
null, |
|||
Role.USER); |
|||
|
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
when(repository.findByToken(any())) |
|||
.thenReturn(access); |
|||
final String path = "/test/path"; |
|||
final String token = "testToken"; |
|||
|
|||
assertThrows(HaltException.class, () ->new AccessService(repository).before(path, token)); |
|||
|
|||
then(repository).should().findByToken(any()); |
|||
then(repository).shouldHaveNoMoreInteractions(); |
|||
} |
|||
|
|||
@Test |
|||
void given_newUser_when_createUser_should_storeNewUser() |
|||
{ |
|||
final RegistrateRequest request = |
|||
RegistrateRequest.of("testUser", "testPwd"); |
|||
|
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
when(repository.findByUserName(any())) |
|||
.thenReturn(null); |
|||
ArgumentCaptor<Access> accessCaptor = ArgumentCaptor.forClass(Access.class); |
|||
|
|||
final AccessService service = new AccessService(repository); |
|||
service.addObserver(this); |
|||
|
|||
final boolean result = service.createPlayer(request); |
|||
|
|||
assertTrue(result); |
|||
assertThat("No event thrown", this.event, notNullValue()); |
|||
|
|||
verify(repository).save(accessCaptor.capture()); |
|||
final Access createdAccess = accessCaptor.getValue(); |
|||
|
|||
assertNotNull(createdAccess, "No Access created"); |
|||
assertNotNull(createdAccess.get_id(), "No Id created"); |
|||
assertNotNull(createdAccess.getUserId(), "No UserId created"); |
|||
assertEquals("testUser", createdAccess.getName(), "Wrong Username"); |
|||
assertEquals("testPwd", createdAccess.getPassword(), "Wrong Password"); |
|||
assertEquals(Role.USER.name(), createdAccess.getRole().name(), "Should be USER"); |
|||
assertNull(createdAccess.getToken(), "User should not be logged in"); |
|||
|
|||
then(repository).should().findByUserName(any()); |
|||
then(repository).should().save(any(Access.class)); |
|||
then(repository).shouldHaveNoMoreInteractions(); |
|||
} |
|||
|
|||
@Test |
|||
void given_loggedInUser_when_logout_should_logoutUser() |
|||
{ |
|||
final Access access = new Access( |
|||
"testId", |
|||
"testName", |
|||
"testPwd", |
|||
UserId.of("12345"), |
|||
null, |
|||
Role.USER |
|||
); |
|||
final AccessToken token = AccessToken.of(access); |
|||
access.setToken(token); |
|||
|
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
when(repository.findByToken(any())) |
|||
.thenReturn(access); |
|||
ArgumentCaptor<Access> accessCaptor = ArgumentCaptor.forClass(Access.class); |
|||
|
|||
final AccessService service = new AccessService(repository); |
|||
|
|||
final boolean result = service.logout("testToken"); |
|||
|
|||
assertTrue(result); |
|||
|
|||
verify(repository).save(accessCaptor.capture()); |
|||
final Access createdAccess = accessCaptor.getValue(); |
|||
|
|||
assertNotNull(createdAccess, "No Access created"); |
|||
assertNotNull(createdAccess.get_id(), "No Id created"); |
|||
assertNotNull(createdAccess.getUserId(), "No UserId created"); |
|||
assertEquals("testName", createdAccess.getName(), "Wrong Username"); |
|||
assertEquals("testPwd", createdAccess.getPassword(), "Wrong Password"); |
|||
assertEquals(Role.USER.name(), createdAccess.getRole().name(), "Should be USER"); |
|||
assertNull(createdAccess.getToken(), "User should logged out"); |
|||
|
|||
then(repository).should().findByToken(any()); |
|||
then(repository).should().save(any(Access.class)); |
|||
then(repository).shouldHaveNoMoreInteractions(); |
|||
} |
|||
|
|||
@Test |
|||
void given_storedUser_when_loginUser_should_returnLoginRequest() |
|||
{ |
|||
final byte[] message = Base64.getEncoder().encode("testName:testPassword".getBytes()); |
|||
final String header = "Basic " + new String(message); |
|||
final Access access = new Access( |
|||
"testId", |
|||
"testName", |
|||
"testPassword", |
|||
UserId.of("12345"), |
|||
null, |
|||
Role.USER |
|||
); |
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
when(repository.findByUserName(any())) |
|||
.thenReturn(access); |
|||
|
|||
final LoginRequest result = new AccessService(repository).authorization(header); |
|||
|
|||
assertNotNull(result); |
|||
assertEquals(result.getName(), "testName", "Wrong UserName"); |
|||
assertEquals(result.getUserId(), "12345", "Wrong Password"); |
|||
assertNotNull(result.getToken(), "Not logged in"); |
|||
} |
|||
|
|||
@Test |
|||
void given_storedUserWithWrongPassword_when_loginUser_should_returnAccessDeny() |
|||
{ |
|||
final byte[] message = Base64.getEncoder().encode("testName:testPassword".getBytes()); |
|||
final String header = "Basic " + new String(message); |
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
|
|||
final LoginRequest result = new AccessService(repository).authorization(header); |
|||
|
|||
assertNull(result, "Return LoginRequest but wrong permissions"); |
|||
} |
|||
|
|||
@Test |
|||
void given_storedUser_when_deleteUser_should_deleteUser() |
|||
{ |
|||
final UserId userId = UserId.of("12345"); |
|||
final AccessToken token = new AccessToken(null, null, null, UserId.of("12345")); |
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
when(repository.deleteLoginByUserId(any(UserId.class))) |
|||
.thenReturn(new WriteResult(1, false, null)); |
|||
|
|||
final AccessService service = new AccessService(repository); |
|||
service.addObserver(this); |
|||
|
|||
final boolean result = service.deleteAccount(userId, token); |
|||
|
|||
assertTrue(result); |
|||
assertNotNull(event); |
|||
|
|||
then(repository).should().deleteLoginByUserId(any(UserId.class)); |
|||
then(repository).shouldHaveNoMoreInteractions(); |
|||
} |
|||
|
|||
@Test |
|||
void given_storedUser_when_deleteUserWithWrongPermission_should_doNothing() |
|||
{ |
|||
final UserId userId = UserId.of("12345"); |
|||
final AccessToken token = new AccessToken(null, null, null, UserId.of("98765")); |
|||
final AccessRepository repository = mock(AccessRepository.class); |
|||
when(repository.deleteLoginByUserId(any(UserId.class))) |
|||
.thenReturn(new WriteResult(1, false, null)); |
|||
|
|||
final AccessService service = new AccessService(repository); |
|||
service.addObserver(this); |
|||
|
|||
final boolean result = service.deleteAccount(userId, token); |
|||
|
|||
assertFalse(result); |
|||
assertNull(event); |
|||
|
|||
then(repository).shouldHaveNoInteractions(); |
|||
} |
|||
|
|||
@Override |
|||
public void update(Observable o, Object arg) |
|||
{ |
|||
this.event = arg; |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
package de.fd.fh.server.access; |
|||
|
|||
import de.fd.fh.server.user.UserId; |
|||
import org.junit.jupiter.api.Test; |
|||
|
|||
import static org.hamcrest.MatcherAssert.assertThat; |
|||
import static org.hamcrest.Matchers.equalTo; |
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
|
|||
class AccessTokenTest |
|||
{ |
|||
@Test |
|||
void given_accessData_when_createAccessToken_should_createGeneratedToken() |
|||
{ |
|||
final Access access = new Access( |
|||
"testId", |
|||
"testName", |
|||
"testPwd", |
|||
UserId.of("12345"), |
|||
null, |
|||
Role.USER); |
|||
|
|||
final AccessToken result = AccessToken.of(access); |
|||
|
|||
assertNotNull(result.getCreatedDate()); |
|||
assertNotNull(result.getToken()); |
|||
assertThat(result.getToken().length(), equalTo(64)); |
|||
assertEquals(result.getRole(), Role.USER); |
|||
assertEquals(result.getUserId(), UserId.of("12345")); |
|||
} |
|||
} |
@ -0,0 +1,51 @@ |
|||
package de.fd.fh.server.user; |
|||
|
|||
import de.fd.fh.server.access.events.AccountCreatedEvent; |
|||
import de.fd.fh.server.access.events.AccountDeletedEvent; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.mockito.ArgumentCaptor; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals; |
|||
import static org.junit.jupiter.api.Assertions.assertNotNull; |
|||
import static org.mockito.ArgumentMatchers.any; |
|||
import static org.mockito.BDDMockito.then; |
|||
import static org.mockito.Mockito.mock; |
|||
import static org.mockito.Mockito.verify; |
|||
|
|||
class UserContextEventListenerTest |
|||
{ |
|||
@Test |
|||
void given_accountCreatedEvent_when_accountWasCreated_should_createUser() |
|||
{ |
|||
final AccountCreatedEvent event = new AccountCreatedEvent("testName", UserId.of("12345")); |
|||
final UserRepository repository = mock(UserRepository.class); |
|||
|
|||
final ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class); |
|||
|
|||
new UserContextEventListener(repository).update(null, event); |
|||
verify(repository).save(captor.capture()); |
|||
|
|||
assertNotNull(captor.getValue()); |
|||
assertEquals("testName", captor.getValue().getName(), "Should have the correct name"); |
|||
assertEquals("12345", captor.getValue().getId().getIdentifier(), "Should have the correct userId"); |
|||
then(repository).should().save(any()); |
|||
then(repository).shouldHaveNoMoreInteractions(); |
|||
} |
|||
|
|||
@Test |
|||
void given_accountDeletedEvent_when_accountWasDeleted_should_deleteUser() |
|||
{ |
|||
final AccountDeletedEvent event = new AccountDeletedEvent(UserId.of("12345")); |
|||
final UserRepository repository = mock(UserRepository.class); |
|||
|
|||
final ArgumentCaptor<UserId> captor = ArgumentCaptor.forClass(UserId.class); |
|||
|
|||
new UserContextEventListener(repository).update(null, event); |
|||
verify(repository).deleteUserById(captor.capture()); |
|||
|
|||
assertNotNull(captor.getValue()); |
|||
assertEquals("12345", captor.getValue().getIdentifier(), "No correct userId"); |
|||
then(repository).should().deleteUserById(any(UserId.class)); |
|||
then(repository).shouldHaveNoMoreInteractions(); |
|||
} |
|||
} |
@ -0,0 +1,40 @@ |
|||
package de.fd.fh.server.user; |
|||
|
|||
import dev.morphia.Datastore; |
|||
import dev.morphia.Key; |
|||
import org.junit.jupiter.api.BeforeEach; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.mockito.Mock; |
|||
|
|||
import static org.hamcrest.MatcherAssert.assertThat; |
|||
import static org.hamcrest.Matchers.notNullValue; |
|||
import static org.mockito.ArgumentMatchers.any; |
|||
import static org.mockito.BDDMockito.then; |
|||
import static org.mockito.Mockito.mock; |
|||
import static org.mockito.Mockito.when; |
|||
|
|||
class UserRepositoryTest |
|||
{ |
|||
@Mock |
|||
private Datastore datastore; |
|||
|
|||
@BeforeEach |
|||
public void before() |
|||
{ |
|||
datastore = mock(Datastore.class); |
|||
} |
|||
|
|||
@Test |
|||
void given_newUser_when_saveUser_should_storeUserInDatabase() |
|||
{ |
|||
when(datastore.save(any(User.class))) |
|||
.thenReturn(new Key<>(User.class, "collection", "id")); |
|||
|
|||
final User access = new User(UserId.of("userId"), "testName"); |
|||
|
|||
final Key<User> result = new UserRepository(datastore).save(access); |
|||
|
|||
assertThat("Key is null", result, notNullValue()); |
|||
then(datastore).should().save(any(User.class)); |
|||
} |
|||
} |
@ -0,0 +1,84 @@ |
|||
package de.fd.fh.server.user; |
|||
|
|||
import de.fd.fh.server.user.web.ChangeUserRequest; |
|||
import de.fd.fh.server.user.web.UserRequest; |
|||
import org.junit.jupiter.api.BeforeEach; |
|||
import org.junit.jupiter.api.Test; |
|||
import org.mockito.ArgumentCaptor; |
|||
|
|||
import java.util.Observable; |
|||
import java.util.Observer; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
import static org.mockito.ArgumentMatchers.any; |
|||
import static org.mockito.Mockito.*; |
|||
|
|||
class UserServiceTest implements Observer |
|||
{ |
|||
private Object event; |
|||
|
|||
@BeforeEach |
|||
void before() |
|||
{ |
|||
event = null; |
|||
} |
|||
|
|||
@Test |
|||
void given_storedUser_when_changePassword_should_changePassword() |
|||
{ |
|||
final User user = |
|||
User.of("testName"); |
|||
final ChangeUserRequest request = |
|||
new ChangeUserRequest("testName", "newPassword"); |
|||
final UserRepository repository = mock(UserRepository.class); |
|||
when(repository.findUserById(any(UserId.class))) |
|||
.thenReturn(user); |
|||
|
|||
final UserService service = new UserService(repository); |
|||
service.addObserver(this); |
|||
final ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class); |
|||
|
|||
service.changePlayer(UserId.of("12345"), request); |
|||
verify(repository).save(captor.capture()); |
|||
|
|||
assertNotNull(captor.getValue(), "Should be saved"); |
|||
assertNotNull(event); |
|||
} |
|||
|
|||
@Test |
|||
void given_storedUser_when_getPlayer_should_returnPlayer() |
|||
{ |
|||
final User user = |
|||
User.of("testName"); |
|||
final UserRepository repository = mock(UserRepository.class); |
|||
when(repository.findUserById(any(UserId.class))) |
|||
.thenReturn(user); |
|||
|
|||
final User result = new UserService(repository).getPlayer(UserId.of("12345")); |
|||
|
|||
assertNotNull(result); |
|||
} |
|||
|
|||
@Test |
|||
void given_storedUser_when_getSmallPlayer_should_returnSmallPlayer() |
|||
{ |
|||
final User user = |
|||
new User(UserId.of("12345"), "testName"); |
|||
final UserRepository repository = mock(UserRepository.class); |
|||
when(repository.findUserById(any(UserId.class))) |
|||
.thenReturn(user); |
|||
|
|||
final UserRequest result = new UserService(repository).getSmallPlayer(UserId.of("12345")); |
|||
|
|||
assertNotNull(result); |
|||
assertEquals("12345", result.getId(), "Wrong UserId"); |
|||
assertEquals("testName", result.getName(), "Wrong Name"); |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void update(Observable o, Object arg) |
|||
{ |
|||
event = arg; |
|||
} |
|||
} |
@ -0,0 +1,6 @@ |
|||
package de.fd.fh.shared; |
|||
|
|||
public class Utils |
|||
{ |
|||
public static final String AUTHENTICATION_HEADER = "Authorization"; |
|||
} |
@ -0,0 +1,11 @@ |
|||
package de.fd.fh.shared.network.messages; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class LoginRequest |
|||
{ |
|||
private String name; |
|||
private String userId; |
|||
private String token; |
|||
} |
@ -0,0 +1,12 @@ |
|||
package de.fd.fh.shared.network.messages; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
@AllArgsConstructor(staticName = "of") |
|||
public class RegistrateRequest |
|||
{ |
|||
private String userName; |
|||
private String password; |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue