Compare commits
2 Commits
7403cf671a
...
7a2a366dd5
Author | SHA1 | Date | |
---|---|---|---|
7a2a366dd5 | |||
36edc91cf3 |
@ -1,43 +0,0 @@
|
|||||||
package djmil.cordacheckers;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import djmil.cordacheckers.cordaclient.CordaClient;
|
|
||||||
import djmil.cordacheckers.cordaclient.dao.VirtualNode;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class ApiController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
CordaClient cordaClient;
|
|
||||||
|
|
||||||
@GetMapping("/api/badjokes")
|
|
||||||
public ResponseEntity<Joke> badJokes() {
|
|
||||||
|
|
||||||
List<VirtualNode> vNodeList = cordaClient.getVirtualNodeList();
|
|
||||||
|
|
||||||
Joke joke = new Joke("What do you call a fly without wings? A walk! " + vNodeList.get(1).holdingIdentity().x500Name());
|
|
||||||
|
|
||||||
return ResponseEntity.ok(joke);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return a Json list of active games
|
|
||||||
*/
|
|
||||||
@GetMapping("/api/gameproposals")
|
|
||||||
public ResponseEntity<String> dashboard(@AuthenticationPrincipal ApiUserDetails user) {
|
|
||||||
System.out.println("List of active games for "
|
|
||||||
+ "user: " + user.getUsername()
|
|
||||||
+ " with HoldingIdentity ShortHash: " + user.getHoldingIdentity().shortHash());
|
|
||||||
|
|
||||||
return ResponseEntity.ok("{ \"UnconsumedGameProposals\" : [\"id_game1\", \"id_game2\"] }" );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package djmil.cordacheckers;
|
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.User;
|
|
||||||
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 djmil.cordacheckers.cordaclient.HoldingIdentityResolver;
|
|
||||||
import djmil.cordacheckers.cordaclient.dao.HoldingIdentity;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ApiUserDetailsService implements UserDetailsService {
|
|
||||||
|
|
||||||
private final PasswordEncoder encoder;
|
|
||||||
private final HoldingIdentityResolver holdingIdentityResolver;
|
|
||||||
|
|
||||||
public ApiUserDetailsService(
|
|
||||||
PasswordEncoder encoder,
|
|
||||||
HoldingIdentityResolver holdingIdentityNameResolver) {
|
|
||||||
this.encoder = encoder;
|
|
||||||
this.holdingIdentityResolver = holdingIdentityNameResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiUserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
||||||
HoldingIdentity holdingIdentity = holdingIdentityResolver.getByCommonName(username);
|
|
||||||
if (holdingIdentity == null) {
|
|
||||||
throw new UsernameNotFoundException("Can't find HoldingIdentity for the user '"+username+ "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Load user "+username);
|
|
||||||
|
|
||||||
User.UserBuilder userBuilder = User.builder();
|
|
||||||
UserDetails user = userBuilder
|
|
||||||
.username(username)
|
|
||||||
.password(encoder.encode("qaz123"))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
return new ApiUserDetails(user, holdingIdentity);
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,6 +17,7 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import djmil.cordacheckers.cordaclient.dao.HoldingIdentity;
|
import djmil.cordacheckers.cordaclient.dao.HoldingIdentity;
|
||||||
|
import djmil.cordacheckers.cordaclient.dao.Color;
|
||||||
import djmil.cordacheckers.cordaclient.dao.VirtualNode;
|
import djmil.cordacheckers.cordaclient.dao.VirtualNode;
|
||||||
import djmil.cordacheckers.cordaclient.dao.VirtualNodeList;
|
import djmil.cordacheckers.cordaclient.dao.VirtualNodeList;
|
||||||
import djmil.cordacheckers.cordaclient.dao.flow.RequestBody;
|
import djmil.cordacheckers.cordaclient.dao.flow.RequestBody;
|
||||||
@ -72,6 +73,15 @@ public class CordaClient {
|
|||||||
return gameProposalsJsonString;
|
return gameProposalsJsonString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String sendGameProposal(
|
||||||
|
HoldingIdentity sender,
|
||||||
|
HoldingIdentity receiver,
|
||||||
|
Color receiverColor,
|
||||||
|
String message
|
||||||
|
) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
private String cordaFlowExecute(HoldingIdentity holdingIdentity, RequestBody requestBody) {
|
private String cordaFlowExecute(HoldingIdentity holdingIdentity, RequestBody requestBody) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package djmil.cordacheckers.cordaclient.dao;
|
||||||
|
|
||||||
|
public enum Color {
|
||||||
|
WHITE,
|
||||||
|
BLACK
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package djmil.cordacheckers.cordaclient.dao;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
|
||||||
|
@JsonDeserialize
|
||||||
|
public record GameProposal(
|
||||||
|
String sender,
|
||||||
|
String recipient,
|
||||||
|
Color recipientColor,
|
||||||
|
String message,
|
||||||
|
String id) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package djmil.cordacheckers.gameproposal;
|
||||||
|
|
||||||
|
import djmil.cordacheckers.cordaclient.dao.Color;
|
||||||
|
|
||||||
|
public record GameProposal(
|
||||||
|
String sender,
|
||||||
|
String recipient,
|
||||||
|
Color recipientColor,
|
||||||
|
String message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package djmil.cordacheckers.gameproposal;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
import djmil.cordacheckers.cordaclient.CordaClient;
|
||||||
|
import djmil.cordacheckers.cordaclient.dao.HoldingIdentity;
|
||||||
|
import djmil.cordacheckers.cordaclient.dao.Color;
|
||||||
|
import djmil.cordacheckers.user.HoldingIdentityResolver;
|
||||||
|
import djmil.cordacheckers.user.User;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("gameproposal")
|
||||||
|
public class GameProposalController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
CordaClient cordaClient;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HoldingIdentityResolver holdingIdentityResolver;
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public ResponseEntity<String> findAllUnconsumed(
|
||||||
|
@AuthenticationPrincipal User player
|
||||||
|
) {
|
||||||
|
String gpList = cordaClient.listGameProposals(player.getHoldingIdentity());
|
||||||
|
|
||||||
|
return ResponseEntity.ok(gpList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @PostMapping()
|
||||||
|
// public ResponseEntity<String> gameproposalSend(@AuthenticationPrincipal ApiUserDetails user) {
|
||||||
|
|
||||||
|
// return ResponseEntity.ok("");
|
||||||
|
// }
|
||||||
|
|
||||||
|
@PostMapping()
|
||||||
|
public ResponseEntity<Void> createGameProposal(
|
||||||
|
@AuthenticationPrincipal User sender,
|
||||||
|
@RequestBody GameProposal gpRequest,
|
||||||
|
UriComponentsBuilder ucb
|
||||||
|
) {
|
||||||
|
|
||||||
|
//sender.get
|
||||||
|
final HoldingIdentity gpSender = sender.getHoldingIdentity();
|
||||||
|
// TODO: throw execption with custom type
|
||||||
|
final HoldingIdentity gpReceiver = holdingIdentityResolver.getByUsername(gpRequest.recipient());
|
||||||
|
final Color gpReceiverColor = gpRequest.recipientColor();
|
||||||
|
|
||||||
|
String newGameProposalUuid = cordaClient.sendGameProposal(
|
||||||
|
gpSender,
|
||||||
|
gpReceiver,
|
||||||
|
gpReceiverColor,
|
||||||
|
gpRequest.message()
|
||||||
|
);
|
||||||
|
|
||||||
|
URI locationOfNewGameProposal = ucb
|
||||||
|
.path("gameproposal/{id}")
|
||||||
|
.buildAndExpand(newGameProposalUuid)
|
||||||
|
.toUri();
|
||||||
|
|
||||||
|
return ResponseEntity
|
||||||
|
.created(locationOfNewGameProposal)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package djmil.cordacheckers.cordaclient;
|
package djmil.cordacheckers.user;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -9,6 +9,7 @@ import javax.naming.InvalidNameException;
|
|||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import djmil.cordacheckers.cordaclient.CordaClient;
|
||||||
import djmil.cordacheckers.cordaclient.dao.HoldingIdentity;
|
import djmil.cordacheckers.cordaclient.dao.HoldingIdentity;
|
||||||
import djmil.cordacheckers.cordaclient.dao.VirtualNode;
|
import djmil.cordacheckers.cordaclient.dao.VirtualNode;
|
||||||
|
|
||||||
@ -18,10 +19,10 @@ public class HoldingIdentityResolver {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: Proof-of-Concept impementation
|
* NOTE: Proof-of-Concept impementation
|
||||||
* Ideally, we want to be able to update HoldingIdentity cache, had the
|
* Ideally, we want to be able to force update cache, had the corda
|
||||||
* corda cluster configuration changed (aka in case of a cache miss)
|
* cluster configuration changed (aka in case of a cache miss)
|
||||||
*/
|
*/
|
||||||
final Map<String, HoldingIdentity> cache;
|
final Map<String, HoldingIdentity> cache; // PlayerName to ShortHash
|
||||||
|
|
||||||
HoldingIdentityResolver(CordaClient cordaClient) {
|
HoldingIdentityResolver(CordaClient cordaClient) {
|
||||||
this.cache = setCache(cordaClient);
|
this.cache = setCache(cordaClient);
|
||||||
@ -37,27 +38,29 @@ public class HoldingIdentityResolver {
|
|||||||
var identity = vNode.holdingIdentity();
|
var identity = vNode.holdingIdentity();
|
||||||
|
|
||||||
if (identity.isPlayer()) {
|
if (identity.isPlayer()) {
|
||||||
map.put(identity.getName().toLowerCase(locale), identity);
|
map.put(
|
||||||
|
identity.getName().toLowerCase(locale),
|
||||||
|
identity
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InvalidNameException e) {
|
} catch (InvalidNameException e) {
|
||||||
// TODO: logs
|
// TODO: logs
|
||||||
System.out.println("Unable to get ShorHash map for Corda virtual nodes: "+e.getExplanation());
|
System.out.println("Unable to get ShorHash list of Corda VirtualNodes: "+e.getMessage());
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param apiUserName
|
* @param playerName
|
||||||
* HoldingIdentity x500 name typically looks like
|
* HoldingIdentity x500 name typically looks like
|
||||||
* "CN=Bob, OU=Player, O=Checkers, L=Kviv, C=UA"
|
* "CN=Bob, OU=Player, O=Checkers, L=Kviv, C=UA"
|
||||||
* CN - is a common name, expected to be unique for CordaCheckers setup.
|
* CN - is a common name, expected to be unique for CordaCheckers setup.
|
||||||
*
|
*
|
||||||
* @return HoldingIdentity
|
* @return HoldingIdentity
|
||||||
*/
|
*/
|
||||||
public HoldingIdentity getByCommonName(String apiUserName) {
|
public HoldingIdentity getByUsername(String userName) {
|
||||||
return this.cache.get(apiUserName.toLowerCase(locale));
|
return this.cache.get(userName.toLowerCase(locale));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +1,13 @@
|
|||||||
package djmil.cordacheckers;
|
package djmil.cordacheckers.user;
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.User;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
import djmil.cordacheckers.cordaclient.dao.HoldingIdentity;
|
import djmil.cordacheckers.cordaclient.dao.HoldingIdentity;
|
||||||
|
|
||||||
public class ApiUserDetails extends User {
|
public class User extends org.springframework.security.core.userdetails.User {
|
||||||
private final HoldingIdentity holdingIdentity;
|
private final HoldingIdentity holdingIdentity;
|
||||||
|
|
||||||
public ApiUserDetails(UserDetails user, HoldingIdentity holdingIdentity) {
|
public User(UserDetails user, HoldingIdentity holdingIdentity) {
|
||||||
super(user.getUsername(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(), user.getAuthorities());
|
super(user.getUsername(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(), user.getAuthorities());
|
||||||
|
|
||||||
this.holdingIdentity = holdingIdentity;
|
this.holdingIdentity = holdingIdentity;
|
||||||
@ -17,5 +16,4 @@ public class ApiUserDetails extends User {
|
|||||||
public HoldingIdentity getHoldingIdentity() {
|
public HoldingIdentity getHoldingIdentity() {
|
||||||
return this.holdingIdentity;
|
return this.holdingIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package djmil.cordacheckers.user;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserService implements UserDetailsService {
|
||||||
|
|
||||||
|
private final PasswordEncoder encoder;
|
||||||
|
private final HoldingIdentityResolver holdingIdentityResolver;
|
||||||
|
|
||||||
|
public UserService(
|
||||||
|
PasswordEncoder encoder,
|
||||||
|
HoldingIdentityResolver holdingIdentityResolver) {
|
||||||
|
this.encoder = encoder;
|
||||||
|
this.holdingIdentityResolver = holdingIdentityResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
final var holdingIdentity = this.holdingIdentityResolver.getByUsername(username);
|
||||||
|
if (holdingIdentity == null) {
|
||||||
|
throw new UsernameNotFoundException("Can't find HoldingIdentity for the user '"+username+ "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Load user "+username);
|
||||||
|
|
||||||
|
org.springframework.security.core.userdetails.User.UserBuilder userBuilder = org.springframework.security.core.userdetails.User.builder();
|
||||||
|
UserDetails baseUser = userBuilder
|
||||||
|
.username(username)
|
||||||
|
.password(this.encoder.encode("qaz123"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return new User(baseUser, holdingIdentity);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user