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