1 /*
  2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 package org.openjdk.skara.cli;
 24 
 25 import org.openjdk.skara.ssh.SSHConfig;
 26 
 27 import java.io.IOException;
 28 import java.net.URI;
 29 import java.nio.file.Path;
 30 import java.nio.file.Files;
 31 
 32 class Remote {
 33     public static URI toWebURI(String remotePath) throws IOException {
 34         if (remotePath.startsWith("git+")) {
 35             remotePath = remotePath.substring("git+".length());
 36         }
 37         if (remotePath.startsWith("http")) {
 38             return URI.create(remotePath);
 39         } else {
 40             if (remotePath.startsWith("ssh://")) {
 41                 remotePath = remotePath.substring("ssh://".length()).replaceFirst("/", ":");
 42             }
 43             var indexOfColon = remotePath.indexOf(':');
 44             var indexOfSlash = remotePath.indexOf('/');
 45             if (indexOfColon != -1) {
 46                 if (indexOfSlash == -1 || indexOfColon < indexOfSlash) {
 47                     var path = remotePath.contains("@") ? remotePath.split("@")[1] : remotePath;
 48                     var name = path.split(":")[0];
 49 
 50                     // Could be a Host in the ~/.ssh/config file
 51                     var sshConfig = Path.of(System.getProperty("user.home"), ".ssh", "config");
 52                     if (Files.exists(sshConfig)) {
 53                         for (var host : SSHConfig.parse(sshConfig).hosts()) {
 54                             if (host.name().equals(name)) {
 55                                 var hostName = host.hostName();
 56                                 if (hostName != null) {
 57                                     return URI.create("https://" + hostName + "/" + path.split(":")[1]);
 58                                 }
 59                             }
 60                         }
 61                     }
 62 
 63                     // Otherwise is must be a domain
 64                     return URI.create("https://" + path.replace(":", "/"));
 65                 }
 66             }
 67         }
 68 
 69         throw new IOException("error: cannot find remote repository for " + remotePath);
 70     }
 71 
 72     public static URI toURI(String remotePath) throws IOException {
 73         if (remotePath.startsWith("git+")) {
 74             remotePath = remotePath.substring("git+".length());
 75         }
 76         if (remotePath.startsWith("http://") ||
 77             remotePath.startsWith("https://") ||
 78             remotePath.startsWith("ssh://") ||
 79             remotePath.startsWith("file://") ||
 80             remotePath.startsWith("git://")) {
 81             return URI.create(remotePath);
 82         }
 83 
 84         var indexOfColon = remotePath.indexOf(':');
 85         var indexOfSlash = remotePath.indexOf('/');
 86         if (indexOfColon != -1) {
 87             if (indexOfSlash == -1 || indexOfColon < indexOfSlash) {
 88                 var path = remotePath.contains("@") ? remotePath.split("@")[1] : remotePath;
 89                 var name = path.split(":")[0];
 90 
 91                 // Could be a Host in the ~/.ssh/config file
 92                 var sshConfig = Path.of(System.getProperty("user.home"), ".ssh", "config");
 93                 if (Files.exists(sshConfig)) {
 94                     for (var host : SSHConfig.parse(sshConfig).hosts()) {
 95                         if (host.name().equals(name)) {
 96                             var hostName = host.hostName();
 97                             if (hostName != null) {
 98                                 var username = host.user();
 99                                 if (username == null) {
100                                     username = remotePath.contains("@") ? remotePath.split("@")[0] : null;
101                                 }
102                                 var userPrefix = username == null ? "" : username + "@";
103                                 return URI.create("ssh://" + userPrefix + hostName + "/" + path.split(":")[1]);
104                             }
105                         }
106                     }
107                 }
108 
109                 // Otherwise is must be a domain
110                 var userPrefix = remotePath.contains("@") ? remotePath.split("@")[0] + "@" : "";
111                 return URI.create("ssh://" + userPrefix + path.replace(":", "/"));
112             }
113         }
114 
115         throw new IOException("error: cannot construct proper URI for " + remotePath);
116     }
117 }