View Javadoc
1   package civitas.bboard.server.controllers;
2   
3   import java.security.PublicKey;
4   import java.util.ArrayList;
5   import java.util.Base64;
6   import java.util.List;
7   
8   import org.bouncycastle.crypto.CryptoException;
9   import org.springframework.beans.factory.annotation.Autowired;
10  import org.springframework.stereotype.Controller;
11  import org.springframework.web.bind.annotation.PathVariable;
12  import org.springframework.web.bind.annotation.PostMapping;
13  
14  import civitas.bboard.server.Board;
15  import civitas.bboard.server.BoardRepository;
16  import civitas.bboard.server.GetBoardForId;
17  import civitas.common.board.BoardClosedContentCommitment;
18  import civitas.common.election.ElectionID;
19  import civitas.crypto.CryptoBase;
20  import civitas.crypto.messagedigest.CryptoHash;
21  import civitas.crypto.rsapublickey.ConvertStringToPublicKey;
22  import civitas.crypto.rsapublickey.VerifyPublicKeySignature;
23  import civitas.crypto.signature.Signature;
24  import jakarta.annotation.Nonnull;
25  
26  @Controller
27  public class CloseBoardController {
28  
29  	@Autowired
30  	VerifyPublicKeySignature verifyPublicKeySignature;
31  
32  	@Autowired
33  	BoardRepository boardRepository;
34  
35  	@Autowired
36  	CryptoBase cryptoBase;
37  
38  	@Autowired
39  	CryptoHash cryptoHash;
40  
41  	@Autowired
42  	GetBoardForId getBoardForId;
43  
44  	@Autowired
45  	GetRestTemplate getRestTemplate;
46  
47  	@Autowired
48  	ConvertStringToPublicKey convertStringToPublicKey;
49  
50  	@PostMapping("/boards/close/{bbid}")
51  	public boolean apply(
52  			@PathVariable("bbid") final String bbid,
53  			@Nonnull final ElectionID postHashTo,
54  			final int numVoterBlocks,
55  			@Nonnull final Signature sig)
56  			throws CommunicableException {
57  		if (null == sig) {
58  			throw new NullPointerException();
59  		}
60  		if (numVoterBlocks < 0) {
61  			throw new IllegalArgumentException("number of voter blocks is negative");
62  		}
63  		Board board = getBoardForId.apply(bbid, true);
64  		PublicKey key;
65  		boolean res;
66  		try {
67  			key = convertStringToPublicKey.apply(board.keyString);
68  			res = verifyPublicKeySignature.apply(sig, key, bbid);
69  		} catch (CryptoException e) {
70  			throw new CommunicableException("cannot verify signature");
71  		}
72  		if (res) {
73  
74  			List<String> hashes = new ArrayList<>();
75  			for (int i = 0; i < numVoterBlocks; i++) {
76  				String meta = "voterSubmission-voterBlock" + i;
77  				hashes.add(Base64.getEncoder().encodeToString(cryptoHash.apply(bbid.getBytes(), meta.getBytes())));
78  			}
79  			BoardClosedContentCommitment bccc = new BoardClosedContentCommitment(postHashTo, bbid, hashes);
80  			String uriBase = postHashTo.uriBase();
81  			String uri = uriBase + "/post";
82  
83  			getRestTemplate.apply().postForObject(uri, bccc, Boolean.class);
84  			board.isOpen = false;
85  			boardRepository.save(board);
86  		}
87  		return res;
88  	}
89  }