View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.scm.provider.git.util;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.util.regex.Matcher;
24  import java.util.regex.Pattern;
25  
26  import org.apache.commons.lang3.StringUtils;
27  import org.apache.maven.scm.providers.gitlib.settings.Settings;
28  import org.apache.maven.scm.providers.gitlib.settings.io.xpp3.GitXpp3Reader;
29  import org.codehaus.plexus.util.ReaderFactory;
30  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
31  
32  /**
33   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
34   */
35  public class GitUtil {
36      public static final String GIT_SETTINGS_FILENAME = "git-settings.xml";
37  
38      public static final File DEFAULT_SETTINGS_DIRECTORY = new File(System.getProperty("user.home"), ".scm");
39  
40      /**
41       * The password placeholder must contain delimiters.
42       * Otherwise replacing may replace other portions of the URL as well
43       * and in worst case passwords could be guessed.
44       */
45      public static final String PASSWORD_PLACE_HOLDER_WITH_DELIMITERS = ":********@";
46  
47      private static final Pattern PASSWORD_IN_URL_PATTERN = Pattern.compile("^.*(:[^/].*@).*$");
48  
49      private static File settingsDirectory = DEFAULT_SETTINGS_DIRECTORY;
50  
51      private static Settings settings;
52  
53      private GitUtil() {
54          // no op
55      }
56  
57      public static Settings getSettings() {
58          if (settings == null) {
59              settings = readSettings();
60          }
61          return settings;
62      }
63  
64      public static Settings readSettings() {
65          File settingsFile = getSettingsFile();
66  
67          if (settingsFile.exists()) {
68              GitXpp3Reader reader = new GitXpp3Reader();
69              try {
70                  return reader.read(ReaderFactory.newXmlReader(settingsFile));
71              } catch (IOException e) {
72                  // Nothing to do
73              } catch (XmlPullParserException e) {
74                  String message = settingsFile.getAbsolutePath() + " isn't well formed. SKIPPED." + e.getMessage();
75  
76                  System.err.println(message);
77              }
78          }
79  
80          return new Settings();
81      }
82  
83      public static void setSettingsDirectory(File directory) {
84          settingsDirectory = directory;
85          settings = readSettings();
86      }
87  
88      public static File getSettingsFile() {
89          return new File(settingsDirectory, GIT_SETTINGS_FILENAME);
90      }
91  
92      /**
93       * Provides an anonymous output to mask password. Considering URL of type :
94       * &lt;&lt;protocol&gt;&gt;://&lt;&lt;user&gt;&gt;:&lt;&lt;password&gt;&gt;@
95       * &lt;&lt;host_definition&gt;&gt;
96       *
97       * @param urlWithCredentials
98       * @return urlWithCredentials but password masked with stars
99       */
100     public static String maskPasswordInUrl(String urlWithCredentials) {
101         String output = urlWithCredentials;
102         final Matcher passwordMatcher = PASSWORD_IN_URL_PATTERN.matcher(output);
103         if (passwordMatcher.find()) {
104             // clear password with delimiters
105             final String clearPasswordWithDelimiters = passwordMatcher.group(1);
106             // to be replaced in output by stars with delimiters
107             output = StringUtils.replace(output, clearPasswordWithDelimiters, PASSWORD_PLACE_HOLDER_WITH_DELIMITERS);
108         }
109         return output;
110     }
111 }