/** * Copyright (c) 2012 Perforce Software. All rights reserved. */ package com.perforce.p4java.server; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.perforce.p4java.Log; import com.perforce.p4java.impl.generic.sys.ISystemFileCommandsHelper; import com.perforce.p4java.impl.mapbased.rpc.sys.helper.SysFileHelperBridge; /** * This super class is designed to lookup auth entries from file or memory. * */ public abstract class AbstractAuthHelper { protected static final String SERVER_ADDRESS_MAP_KEY = "serverAddress"; protected static final String USER_NAME_MAP_KEY = "userName"; protected static final String AUTH_VALUE_MAP_KEY = "authValue"; /** * Get the auth entry in the specified auth map that matches the specified * user name and server address. The user name be non-null and the server * address must be non-null and be of the form server:port. * * @param authMap * @return - list of auth entries found in the specified auth map */ protected static synchronized Map<String, String> getMemoryEntry(String userName, String serverAddress, Map<String, String> authMap) { Map<String, String> entryMap = null; if (userName != null && serverAddress != null && authMap != null) { if (serverAddress.lastIndexOf(':') == -1) { serverAddress += "localhost:" + serverAddress; } String prefix = serverAddress + "=" + userName; if (authMap.containsKey(prefix)) { String authValue = authMap.get(prefix); entryMap = new HashMap<String,String>(); entryMap.put(SERVER_ADDRESS_MAP_KEY, serverAddress); entryMap.put(USER_NAME_MAP_KEY, userName); entryMap.put(AUTH_VALUE_MAP_KEY, authValue); } } return entryMap; } /** * Get all the auth entries found in the specified auth store in memory. * * @param authMap * @return - list of auth entries found in the specified auth map */ protected static synchronized List<Map<String, String>> getMemoryEntries(Map<String, String> authMap) { List<Map<String, String>> authList = new ArrayList<Map<String, String>>(); if (authMap != null) { for (Map.Entry<String, String> entry : authMap.entrySet()) { String line = entry.getKey() + ":" + entry.getValue(); // Auth entry pattern is: // server_address=user_name:auth_value int equals = line.indexOf('='); if (equals != -1) { int colon = line.indexOf(':', equals); if (colon != -1 && colon + 1 < line.length()) { String serverAddress = line.substring(0, equals); String userName = line.substring(equals + 1, colon); String authValue = line .substring(colon + 1); Map<String,String> entryMap = new HashMap<String,String>(); entryMap.put(SERVER_ADDRESS_MAP_KEY, serverAddress); entryMap.put(USER_NAME_MAP_KEY, userName); entryMap.put(AUTH_VALUE_MAP_KEY, authValue); authList.add(entryMap); } } } } return authList; } /** * Save the specified parameters as an entry into the specified auth * map. This method will add or replace the current entry for the user name * and server address in the auth map. If the specified auth value is null * then the current entry (if exits) in the specified map will be removed. * * @param userName * - non-null user name * @param serverAddress * - non-null server address * @param authValue * - possibly null auth value * @param authMap * - non-null auth map */ protected static synchronized void saveMemoryEntry(String userName, String serverAddress, String authValue, Map<String, String> authMap) { if (userName != null && serverAddress != null && authMap != null) { if (serverAddress.lastIndexOf(':') == -1) { serverAddress += "localhost:" + serverAddress; } String prefix = serverAddress + "=" + userName; if (authValue != null) { // save entry authMap.put(prefix, authValue); } else { if (authMap.containsKey(prefix)) { // delete entry authMap.remove(prefix); } } } } /** * Get all the auth entries found in the specified auth file. * * @param authFile * @return - list of auth entries found in the specified auth file * @throws IOException * - io exception from reading auth file */ protected static synchronized List<Map<String, String>> getFileEntries(File authFile) throws IOException { List<Map<String, String>> authList = new ArrayList<Map<String, String>>(); if (authFile != null && authFile.exists()) { BufferedReader reader = new BufferedReader(new FileReader( authFile)); try { String line = reader.readLine(); while (line != null) { // Auth entry pattern is: // server_address=user_name:auth_value int equals = line.indexOf('='); if (equals != -1) { int colon = line.indexOf(':', equals); if (colon != -1 && colon + 1 < line.length()) { String serverAddress = line.substring(0, equals); String userName = line.substring(equals + 1, colon); String authValue = line .substring(colon + 1); Map<String,String> map = new HashMap<String,String>(); map.put(SERVER_ADDRESS_MAP_KEY, serverAddress); map.put(USER_NAME_MAP_KEY, userName); map.put(AUTH_VALUE_MAP_KEY, authValue); authList.add(map); } } line = reader.readLine(); } } finally { reader.close(); } } return authList; } /** * Save the specified parameters as an entry into the specified auth * file. This method will replace the current entry for the user name and * server address in the auth file. If a current entry is not found then * the specified entry will be appended to the file. If the specified auth * value is null then the current entry in the specified file will be * removed if found. * * @param userName * - non-null user name * @param serverAddress * - non-null server address * @param authValue * - possibly null auth value * @param authFile * - non-null file * @throws IOException */ protected static synchronized void saveFileEntry(String userName, String serverAddress, String authValue, File authFile) throws IOException { if (userName != null && serverAddress != null && authFile != null) { if (serverAddress.lastIndexOf(':') == -1) { serverAddress += "localhost:" + serverAddress; } String prefix = serverAddress + "=" + userName + ":"; String value = null; if (authValue != null) { value = prefix + authValue; } BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(authFile)); } catch (FileNotFoundException fnfe) { // File is non-existent or not readable so ignored contents reader = null; } // Put contents in temp file File tempAuth = File.createTempFile("p4auth", ".txt"); PrintWriter writer = new PrintWriter(tempAuth, "utf-8"); boolean renamed = false; try { boolean processed = false; // Only add current auth file content if a reader was // successfully created if (reader != null) { String line = reader.readLine(); while (line != null) { // Replace existing entry in the auth file if (!processed && line.startsWith(prefix)) { // value being null means that the entry should be // removed if (value != null) { writer.println(value); } processed = true; } else { writer.println(line); } line = reader.readLine(); } } if (!processed && value != null) { writer.println(value); } } finally { writer.flush(); writer.close(); if (reader != null) { try { reader.close(); } catch (IOException e) { // ignore } } try { // Rename to original auth file if no exceptions occur renamed = tempAuth.renameTo(authFile); if (!renamed) { // If a straight up rename fails then try to copy the new // auth file into the current p4 auth file. This seems to // happen on windows. renamed = copy(tempAuth, authFile); } } finally { if (tempAuth.exists()) { if (!tempAuth.delete()) { Log.warn("Unable to delete temp auth file '" + tempAuth.getPath() + "' in AbstractAuthHelper.saveFileEntry() -- unknown cause"); } } } } // Update read bit of actual auth file updateReadBit(authFile); if (!renamed) { throw new IOException("P4 auth file: " + authFile.getAbsolutePath() + " could not be overwritten."); } } } private static boolean copy(File source, File destination) throws IOException { boolean copied = false; if (source != null && destination != null) { FileInputStream reader = null; FileOutputStream writer = null; try { ISystemFileCommandsHelper helper = ServerFactory.getRpcFileSystemHelper(); if (helper == null) { helper = SysFileHelperBridge.getSysFileCommands(); } if (helper != null) { helper.setWritable(destination.getAbsolutePath(), true); } reader = new FileInputStream(source); writer = new FileOutputStream(destination); long targetCount = reader.getChannel().size(); long transferCount = writer.getChannel().transferFrom(reader.getChannel(), 0, targetCount); copied = transferCount == targetCount; } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { Log.warn("reader close error in AbstractAuthHelper.copy(): " + e.getLocalizedMessage()); Log.exception(e); } } if (writer != null) { try { writer.close(); } catch (IOException e) { Log.warn("writer close error in AbstractAuthHelper.copy(): " + e.getLocalizedMessage()); Log.exception(e); } } } } return copied; } private static void updateReadBit(File file) throws IOException { if (file != null) { // The goal is to set the file permissions bits to only have owner // read set (-r-------- or 400) but currently // java.io.File.setReadOnly may leave the group and other read bits // set. Try to leverage the registered helper to clear the remaining // read bits.Document this in the release notes. file.setReadOnly(); ISystemFileCommandsHelper helper = ServerFactory .getRpcFileSystemHelper(); if (helper == null) { helper = SysFileHelperBridge.getSysFileCommands(); } if (helper != null) { helper.setOwnerReadOnly(file.getAbsolutePath()); } } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 19903 | stuartrowe |
Branching //guest/perforce_software/p4java/... to //guest/stuartrowe/p4java/... |
||
//guest/perforce_software/p4java/r14.1/src/main/java/com/perforce/p4java/server/AbstractAuthHelper.java | |||||
#1 | 12541 | Matt Attaway | Initial add of the 14.1 p4java source code |