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      protected 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      /** The password placeholder must contain delimiters.
41       *  Otherwise replacing may replace other portions of the URL as well
42       *  and in worst case passwords could be guessed. */
43      public static final String PASSWORD_PLACE_HOLDER_WITH_DELIMITERS = ":********@";
44  
45      private static final Pattern PASSWORD_IN_URL_PATTERN = Pattern.compile("^.*(:[^/].*@).*$");
46  
47      private static File settingsDirectory = DEFAULT_SETTINGS_DIRECTORY;
48  
49      private static Settings settings;
50  
51      private GitUtil() {
52          // no op
53      }
54  
55      public static Settings getSettings() {
56          if (settings == null) {
57              settings = readSettings();
58          }
59          return settings;
60      }
61  
62      public static Settings readSettings() {
63          File settingsFile = getSettingsFile();
64  
65          if (settingsFile.exists()) {
66              GitXpp3Reader reader = new GitXpp3Reader();
67              try {
68                  return reader.read(ReaderFactory.newXmlReader(settingsFile));
69              } catch (IOException e) {
70                  // Nothing to do
71              } catch (XmlPullParserException e) {
72                  String message = settingsFile.getAbsolutePath() + " isn't well formed. SKIPPED." + e.getMessage();
73  
74                  System.err.println(message);
75              }
76          }
77  
78          return new Settings();
79      }
80  
81      public static void setSettingsDirectory(File directory) {
82          settingsDirectory = directory;
83          settings = readSettings();
84      }
85  
86      public static File getSettingsFile() {
87          return new File(settingsDirectory, GIT_SETTINGS_FILENAME);
88      }
89  
90      /**
91       * Provides an anonymous output to mask password. Considering URL of type :
92       * &lt;&lt;protocol&gt;&gt;://&lt;&lt;user&gt;&gt;:&lt;&lt;password&gt;&gt;@
93       * &lt;&lt;host_definition&gt;&gt;
94       *
95       * @param urlWithCredentials
96       * @return urlWithCredentials but password masked with stars
97       */
98      public static String maskPasswordInUrl(String urlWithCredentials) {
99          String output = urlWithCredentials;
100         final Matcher passwordMatcher = PASSWORD_IN_URL_PATTERN.matcher(output);
101         if (passwordMatcher.find()) {
102             // clear password with delimiters
103             final String clearPasswordWithDelimiters = passwordMatcher.group(1);
104             // to be replaced in output by stars with delimiters
105             output = StringUtils.replace(output, clearPasswordWithDelimiters, PASSWORD_PLACE_HOLDER_WITH_DELIMITERS);
106         }
107         return output;
108     }
109 }