<commit_before>package org.subshare.rest.server.service;

import static co.codewizards.cloudstore.core.util.AssertUtil.assertNotNull;

import java.util.UUID;

import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.subshare.core.Cryptree;
import org.subshare.core.CryptreeFactory;
import org.subshare.core.CryptreeFactoryRegistry;
import org.subshare.core.dto.SsRequestRepoConnectionRepositoryDto;
import org.subshare.core.sign.SignableVerifier;

import co.codewizards.cloudstore.core.dto.RepositoryDto;
import co.codewizards.cloudstore.core.repo.local.ContextWithLocalRepoManager;
import co.codewizards.cloudstore.core.repo.local.LocalRepoManager;
import co.codewizards.cloudstore.core.repo.local.LocalRepoTransaction;
import co.codewizards.cloudstore.core.repo.transport.RepoTransport;
import co.codewizards.cloudstore.rest.server.service.RequestRepoConnectionService;

@Path("_requestRepoConnection/{repositoryName}")
public class SsRequestRepoConnectionService extends RequestRepoConnectionService {

	@Override
	protected void requestConnection(final RepoTransport repoTransport, final String pathPrefix, final RepositoryDto clientRepositoryDto) {
		verifyRepositoryDto(repoTransport, clientRepositoryDto);
		super.requestConnection(repoTransport, pathPrefix, clientRepositoryDto);
		acceptConnection(repoTransport, pathPrefix, clientRepositoryDto);
	}

	private void verifyRepositoryDto(final RepoTransport repoTransport, final RepositoryDto clientRepositoryDto) {
		assertNotNull("repoTransport", repoTransport);
		assertNotNull("clientRepositoryDto", clientRepositoryDto);
		final UUID clientRepositoryId = assertNotNull("repoTransport.clientRepositoryId", repoTransport.getClientRepositoryId());

		if (! clientRepositoryId.equals(clientRepositoryDto.getRepositoryId()))
			throw new IllegalArgumentException("repoTransport.clientRepositoryId != clientRepositoryDto.clientRepositoryId");

		if (! (clientRepositoryDto instanceof SsRequestRepoConnectionRepositoryDto))
			throw new WebApplicationException(Response.status(Status.FORBIDDEN).type(MediaType.TEXT_PLAIN_TYPE).entity("clientRepositoryDto is not an instance of SsRequestRepoConnectionRepositoryDto!").build());

		final LocalRepoManager localRepoManager = ((ContextWithLocalRepoManager) repoTransport).getLocalRepoManager();
		try (final LocalRepoTransaction transaction = localRepoManager.beginReadTransaction();) {

			final SsRequestRepoConnectionRepositoryDto rrcRepositoryDto = (SsRequestRepoConnectionRepositoryDto) clientRepositoryDto;

			final CryptreeFactory cryptreeFactory = CryptreeFactoryRegistry.getInstance().getCryptreeFactoryOrFail();
			final Cryptree cryptree = cryptreeFactory.getCryptreeOrCreate(transaction, clientRepositoryId);

			// This (the server-side) might be a virgin repository! Hence, we perform this check only, if it's not empty.
			// TODO is this the right way to check for its virginity?!

			if (! cryptree.isEmpty()) {
				final SignableVerifier signableVerifier = new SignableVerifier(cryptree.getUserRepoKeyPublicKeyLookup());
				signableVerifier.verify(rrcRepositoryDto);
			}
		}
	}

	private void acceptConnection(final RepoTransport repoTransport, final String pathPrefix, final RepositoryDto clientRepositoryDto) {
		assertNotNull("repoTransport", repoTransport);
		assertNotNull("clientRepositoryDto", clientRepositoryDto);
		final UUID clientRepositoryId = assertNotNull("clientRepositoryId", repoTransport.getClientRepositoryId());
		final LocalRepoManager localRepoManager = ((ContextWithLocalRepoManager) repoTransport).getLocalRepoManager();
		final byte[] remotePublicKey = clientRepositoryDto.getPublicKey();
		final String localPathPrefix = pathPrefix;
		localRepoManager.putRemoteRepository(clientRepositoryId, null, remotePublicKey, localPathPrefix); // deletes the request.<commit_msg>Removed out-dated TODO.<commit_after>package org.subshare.rest.server.service;

import static co.codewizards.cloudstore.core.util.AssertUtil.assertNotNull;

import java.util.UUID;

import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.subshare.core.Cryptree;
import org.subshare.core.CryptreeFactory;
import org.subshare.core.CryptreeFactoryRegistry;
import org.subshare.core.dto.SsRequestRepoConnectionRepositoryDto;
import org.subshare.core.sign.SignableVerifier;

import co.codewizards.cloudstore.core.dto.RepositoryDto;
import co.codewizards.cloudstore.core.repo.local.ContextWithLocalRepoManager;
import co.codewizards.cloudstore.core.repo.local.LocalRepoManager;
import co.codewizards.cloudstore.core.repo.local.LocalRepoTransaction;
import co.codewizards.cloudstore.core.repo.transport.RepoTransport;
import co.codewizards.cloudstore.rest.server.service.RequestRepoConnectionService;

@Path("_requestRepoConnection/{repositoryName}")
public class SsRequestRepoConnectionService extends RequestRepoConnectionService {

	@Override
	protected void requestConnection(final RepoTransport repoTransport, final String pathPrefix, final RepositoryDto clientRepositoryDto) {
		verifyRepositoryDto(repoTransport, clientRepositoryDto);
		super.requestConnection(repoTransport, pathPrefix, clientRepositoryDto);
		acceptConnection(repoTransport, pathPrefix, clientRepositoryDto);
	}

	private void verifyRepositoryDto(final RepoTransport repoTransport, final RepositoryDto clientRepositoryDto) {
		assertNotNull("repoTransport", repoTransport);
		assertNotNull("clientRepositoryDto", clientRepositoryDto);
		final UUID clientRepositoryId = assertNotNull("repoTransport.clientRepositoryId", repoTransport.getClientRepositoryId());

		if (! clientRepositoryId.equals(clientRepositoryDto.getRepositoryId()))
			throw new IllegalArgumentException("repoTransport.clientRepositoryId != clientRepositoryDto.clientRepositoryId");

		if (! (clientRepositoryDto instanceof SsRequestRepoConnectionRepositoryDto))
			throw new WebApplicationException(Response.status(Status.FORBIDDEN).type(MediaType.TEXT_PLAIN_TYPE).entity("clientRepositoryDto is not an instance of SsRequestRepoConnectionRepositoryDto!").build());

		final LocalRepoManager localRepoManager = ((ContextWithLocalRepoManager) repoTransport).getLocalRepoManager();
		try (final LocalRepoTransaction transaction = localRepoManager.beginReadTransaction();) {

			final SsRequestRepoConnectionRepositoryDto rrcRepositoryDto = (SsRequestRepoConnectionRepositoryDto) clientRepositoryDto;

			final CryptreeFactory cryptreeFactory = CryptreeFactoryRegistry.getInstance().getCryptreeFactoryOrFail();
			final Cryptree cryptree = cryptreeFactory.getCryptreeOrCreate(transaction, clientRepositoryId);

			// This (the server-side) might be a virgin repository! Hence, we perform this check only, if it's not empty.
			if (! cryptree.isEmpty()) {
				final SignableVerifier signableVerifier = new SignableVerifier(cryptree.getUserRepoKeyPublicKeyLookup());
				signableVerifier.verify(rrcRepositoryDto);
			}
		}
	}

	private void acceptConnection(final RepoTransport repoTransport, final String pathPrefix, final RepositoryDto clientRepositoryDto) {
		assertNotNull("repoTransport", repoTransport);
		assertNotNull("clientRepositoryDto", clientRepositoryDto);
		final UUID clientRepositoryId = assertNotNull("clientRepositoryId", repoTransport.getClientRepositoryId());
		final LocalRepoManager localRepoManager = ((ContextWithLocalRepoManager) repoTransport).getLocalRepoManager();
		final byte[] remotePublicKey = clientRepositoryDto.getPublicKey();
		final String localPathPrefix = pathPrefix;
		localRepoManager.putRemoteRepository(clientRepositoryId, null, remotePublicKey, localPathPrefix); // deletes the request.
{'fraction_non_alphanumeric': 0.08410857652606092, 'fraction_numerical': 0.0, 'mean_word_length': 8.051903114186851, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1380118', 'n_tokens_mistral': 2119, 'n_tokens_neox': 2095, 'n_words': 394}