GameCreate request

- use HTTP POST request
- diable CSRF on server
This commit is contained in:
djmil 2023-10-29 21:45:48 +01:00
parent 7d4aaf10df
commit 3d9dbd2683
3 changed files with 65 additions and 28 deletions

View File

@ -2,9 +2,11 @@ package djmil.cordacheckers;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@ -15,4 +17,22 @@ public class SecurityConfig {
return PasswordEncoderFactories.createDelegatingPasswordEncoder(); return PasswordEncoderFactories.createDelegatingPasswordEncoder();
} }
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.and()
.httpBasic();
http.csrf().disable();
// GiteaIssue #2: Enable CSRF
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
return http.build();
}
} }

View File

@ -1,12 +1,10 @@
package djmil.cordacheckers.api; package djmil.cordacheckers.api;
import java.net.URI; import java.net.URI;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -24,7 +22,6 @@ import djmil.cordacheckers.cordaclient.dao.flow.arguments.ReqGameProposalCreate;
import djmil.cordacheckers.user.HoldingIdentityResolver; import djmil.cordacheckers.user.HoldingIdentityResolver;
import djmil.cordacheckers.user.User; import djmil.cordacheckers.user.User;
@RestController @RestController
@RequestMapping("api/gameproposal") @RequestMapping("api/gameproposal")
public class GameProposalController { public class GameProposalController {
@ -34,34 +31,33 @@ public class GameProposalController {
@Autowired @Autowired
HoldingIdentityResolver holdingIdentityResolver; HoldingIdentityResolver holdingIdentityResolver;
@PostMapping() @PostMapping()
public ResponseEntity<Void> createGameProposal( public ResponseEntity<GameView> createGameProposal(
@AuthenticationPrincipal User sender, @AuthenticationPrincipal User sender,
@RequestBody ReqGameProposalCreate gpRequest, @RequestBody ReqGameProposalCreate gpRequest,
UriComponentsBuilder ucb UriComponentsBuilder ucb) throws JsonMappingException, JsonProcessingException {
) throws JsonMappingException, JsonProcessingException {
final HoldingIdentity gpSender = sender.getHoldingIdentity(); final HoldingIdentity gpSender = sender.getHoldingIdentity();
// TODO: throw execption with custom type
final HoldingIdentity gpReceiver = holdingIdentityResolver.getByUsername(gpRequest.opponentName()); final HoldingIdentity gpReceiver = holdingIdentityResolver.getByUsername(gpRequest.opponentName());
final Stone.Color gpReceiverColor = gpRequest.opponentColor(); final Stone.Color gpReceiverColor = gpRequest.opponentColor();
// TODO handle expectionns here // GiteaIssue #4: Exception handling
GameView gameStateView = cordaClient.gameProposalCreate( GameView gameStateView = cordaClient.gameProposalCreate(
gpSender, gpSender,
gpReceiver, gpReceiver,
gpReceiverColor, gpReceiverColor,
gpRequest.message() // gpRequest.board() // GireaIssue #3: use provided board configuration
); gpRequest.message());
URI locationOfNewGameProposal = ucb URI locationOfNewGameProposal = ucb
.path("api/gameproposal/{id}") .path("api/gameproposal/{id}")
.buildAndExpand(gameStateView) .buildAndExpand(gameStateView.uuid())
.toUri(); .toUri();
return ResponseEntity return ResponseEntity
.created(locationOfNewGameProposal) .created(locationOfNewGameProposal)
.build(); .body(gameStateView);
} }
} }

View File

@ -7,14 +7,18 @@ export default function Create() {
const ctx = Definitions() const ctx = Definitions()
const onClick = () => { const onClick = () => {
if (!ctx.hasPlayers) if (!ctx.hasPlayers)
return alert("Choose both black and white players"); return alert("Choose both black and white players");
if (!ctx.hasCurrentUser) if (!ctx.hasCurrentUser)
return alert("You must be one of the players"); return alert("You must be one of the players");
const request = ctx.get_GameProposalRequest() const request = ctx.get_GameProposalRequest()
console.log("TODO: send GameCreateRequest to the server!", request)
postData("/api/gameproposal", request)
.then((responce) => {
console.log("responce", responce); // JSON data parsed by `data.json()` call
});
} }
return ( return (
@ -34,13 +38,13 @@ function Definitions() {
const isCurrentUser = data.isCurrentUser const isCurrentUser = data.isCurrentUser
const whitePlayerName = ctx.newGame.whitePlayer const whitePlayerName = ctx.newGame.whitePlayer
const blackPlayerName = ctx.newGame.blackPlayer const blackPlayerName = ctx.newGame.blackPlayer
const hasPlayers = whitePlayerName !== blackPlayerName const hasPlayers = whitePlayerName !== blackPlayerName
&& whitePlayerName !== '' && whitePlayerName !== ''
&& blackPlayerName !== '' && blackPlayerName !== ''
const hasCurrentUser = isCurrentUser(whitePlayerName) || isCurrentUser(blackPlayerName) const hasCurrentUser = isCurrentUser(whitePlayerName) || isCurrentUser(blackPlayerName)
const isEnabled = hasPlayers && hasCurrentUser const isEnabled = hasPlayers && hasCurrentUser
const get_GameProposalRequest = () => { const get_GameProposalRequest = () => {
@ -53,7 +57,7 @@ function Definitions() {
message: "let's play a game" message: "let's play a game"
} }
} }
return { return {
hasPlayers, hasPlayers,
hasCurrentUser, hasCurrentUser,
@ -74,4 +78,21 @@ function get_Opponent(isCurrentUser, whitePlayerName, blackPlayerName) {
return ['', ''] return ['', '']
} }
async function postData(url = "", data = {}) {
console.log("POST", url, data)
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
if (response.ok)
return response.json()// parses JSON response into native JavaScript objects
console.log("recponce", response)
return {}
}