001/* 002 * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org 003 * Copyright (C) 2011 NightLabs Consulting GmbH 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package co.codewizards.cloudstore.client; 019 020import java.util.UUID; 021 022import org.kohsuke.args4j.Argument; 023 024import co.codewizards.cloudstore.core.repo.local.LocalRepoManager; 025import co.codewizards.cloudstore.core.repo.local.LocalRepoManagerFactory; 026import co.codewizards.cloudstore.core.repo.local.LocalRepoTransaction; 027import co.codewizards.cloudstore.core.util.HashUtil; 028import co.codewizards.cloudstore.local.persistence.RemoteRepositoryRequest; 029import co.codewizards.cloudstore.local.persistence.RemoteRepositoryRequestDAO; 030 031/** 032 * {@link SubCommand} implementation for requesting a connection at a remote repository. 033 * 034 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de 035 */ 036public class AcceptRepoConnectionSubCommand extends SubCommandWithExistingLocalRepo 037{ 038 @Argument(metaVar="<remote>", index=1, required=false, usage="The unique ID of a remote repository currently requesting to be connected. If none is specified, the oldest request is accepted.") 039 private String remote; 040 041 private UUID remoteRepositoryId; 042 043 @Override 044 public String getSubCommandDescription() { 045 return "Accept a connection request from a remote repository."; 046 } 047 048 @Override 049 public void prepare() throws Exception { 050 super.prepare(); 051 remoteRepositoryId = remote == null ? null : UUID.fromString(remote); 052 } 053 054 @Override 055 public void run() throws Exception { 056 UUID localRepositoryId; 057 byte[] localPublicKey; 058 byte[] remotePublicKey; 059 String localPathPrefix; 060 LocalRepoManager localRepoManager = LocalRepoManagerFactory.Helper.getInstance().createLocalRepoManagerForExistingRepository(localRoot); 061 try { 062 localRepositoryId = localRepoManager.getRepositoryId(); 063 localPublicKey = localRepoManager.getPublicKey(); 064 LocalRepoTransaction transaction = localRepoManager.beginWriteTransaction(); 065 try { 066 RemoteRepositoryRequestDAO remoteRepositoryRequestDAO = transaction.getDAO(RemoteRepositoryRequestDAO.class); 067 RemoteRepositoryRequest request; 068 if (remoteRepositoryId == null) { 069 RemoteRepositoryRequest oldestRequest = null; 070 for (RemoteRepositoryRequest remoteRepositoryRequest : remoteRepositoryRequestDAO.getObjects()) { 071 if (oldestRequest == null || oldestRequest.getChanged().after(remoteRepositoryRequest.getChanged())) 072 oldestRequest = remoteRepositoryRequest; 073 } 074 if (oldestRequest == null) 075 throw new IllegalStateException("There is no connection request pending for this local repository: " + localRoot.getPath()); 076 077 request = oldestRequest; 078 } 079 else { 080 request = remoteRepositoryRequestDAO.getRemoteRepositoryRequestOrFail(remoteRepositoryId); 081 } 082 remoteRepositoryId = request.getRepositoryId(); 083 remotePublicKey = request.getPublicKey(); 084 localPathPrefix = request.getLocalPathPrefix(); 085 transaction.commit(); 086 } finally { 087 transaction.rollbackIfActive(); 088 } 089 localRepoManager.putRemoteRepository(remoteRepositoryId, null, remotePublicKey, localPathPrefix); // deletes the request. 090 } finally { 091 localRepoManager.close(); 092 } 093 094 System.out.println("Successfully accepted the connection request for the following local and remote repositories:"); 095 System.out.println(); 096 System.out.println(" localRepository.repositoryId = " + localRepositoryId); 097 System.out.println(" localRepository.localRoot = " + localRoot); 098 System.out.println(" localRepository.publicKeySha1 = " + HashUtil.sha1ForHuman(localPublicKey)); 099 System.out.println(); 100 System.out.println(" remoteRepository.repositoryId = " + remoteRepositoryId); 101 System.out.println(" remoteRepository.publicKeySha1 = " + HashUtil.sha1ForHuman(remotePublicKey)); 102 System.out.println(); 103 System.out.println("Please verify the 'publicKeySha1' fingerprints! If they do not match the fingerprints shown on the client, someone is attacking you and you must cancel this request immediately! To cancel the request, use this command:"); 104 System.out.println(); 105 System.out.println(String.format(" cloudstore dropRepoConnection %s %s", localRepositoryId, remoteRepositoryId)); 106 } 107}