blob: 4b0283d61bb819e1fdc5061fbf9d4b88e229c96e [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.cvsSupport2.connections.pserver;
import com.intellij.CvsBundle;
import com.intellij.cvsSupport2.config.CvsApplicationLevelConfiguration;
import com.intellij.cvsSupport2.connections.login.CvsLoginWorker;
import com.intellij.cvsSupport2.connections.login.CvsLoginWorkerImpl;
import com.intellij.cvsSupport2.connections.ssh.SolveableAuthenticationException;
import com.intellij.cvsSupport2.javacvsImpl.io.ReadWriteStatistics;
import com.intellij.cvsSupport2.javacvsImpl.io.StreamLogger;
import com.intellij.cvsSupport2.util.CvsFileUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.Nullable;
import org.netbeans.lib.cvsclient.connection.AuthenticationException;
import org.netbeans.lib.cvsclient.connection.IConnection;
import org.netbeans.lib.cvsclient.connection.PServerPasswordScrambler;
import org.netbeans.lib.cvsclient.connection.UnknownUserException;
import java.io.*;
import java.util.List;
/**
* author: lesya
*/
public class PServerLoginProviderImpl extends PServerLoginProvider {
private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.connections.pserver.PServerLoginProviderImpl");
@Override
@Nullable
public String getScrambledPasswordForCvsRoot(String cvsRoot) {
return getPassword(cvsRoot);
}
@Nullable
private static String requestForPassword(String cvsRoot) {
final String password = Messages.showPasswordDialog(CvsBundle.message("prompt.text.enter.password.for.cvs.root", cvsRoot), CvsBundle.message("prompt.title.enter.password.for.cvs.root"));
return password != null ? PServerPasswordScrambler.getInstance().scramble(password) : null;
}
@Override
public CvsLoginWorker getLoginWorker(final Project project, final PServerCvsSettings pServerCvsSettings) {
return new PServerLoginWorker(project, pServerCvsSettings);
}
private static class PServerLoginWorker extends CvsLoginWorkerImpl<PServerCvsSettings> {
private PServerLoginWorker(final Project project, final PServerCvsSettings settings) {
super(project, settings);
}
@Override
protected void silentLoginImpl(final boolean forceCheck) throws AuthenticationException {
final String cvsRoot = mySettings.getCvsRootAsString();
final String stored = getPassword(cvsRoot);
if (stored == null) throw new SolveableAuthenticationException(null);
if (forceCheck) {
tryConnection();
}
}
private void tryConnection() throws AuthenticationException {
final IConnection connection = mySettings.createConnection(new ReadWriteStatistics());
try {
connection.open(new StreamLogger());
mySettings.setOffline(false);
}
catch (UnknownUserException e) {
throw new SolveableAuthenticationException(e.getMessage(), e);
}
finally {
try {
connection.close();
}
catch (IOException e) {
LOG.info(e);
}
}
}
@Override
public boolean promptForPassword() {
final String cvsRoot = mySettings.getCvsRootAsString();
final String password = requestForPassword(cvsRoot);
if (password == null) return false;
try {
removeAllPasswordsForThisCvsRootFromPasswordFile(cvsRoot);
storePassword(cvsRoot, password);
}
catch (IOException e) {
showConnectionErrorMessage(myProject, CvsBundle.message("error.message.cannot.store.password", e.getLocalizedMessage()));
return false;
}
mySettings.storePassword(password);
return true;
}
@Override
protected void clearOldCredentials() {
mySettings.releasePassword();
}
}
// TODO do release password ! when opening a connection and there's a problem with authorization
private static void removeAllPasswordsForThisCvsRootFromPasswordFile(String cvsRoot) throws IOException {
final File passFile = getPassFile();
if (!passFile.isFile()) {
return;
}
final List<String> lines = CvsFileUtil.readLinesFrom(passFile, cvsRoot);
try {
CvsFileUtil.storeLines(lines, passFile);
}
catch (IOException e) {
LOG.error(e);
}
}
private static void storePassword(String stringConfiguration, String scrambledPassword) throws IOException {
final File passFile = getPassFile();
FileUtil.createIfDoesntExist(passFile);
final List<String> lines = CvsFileUtil.readLinesFrom(passFile);
lines.add(stringConfiguration + " " + scrambledPassword);
CvsFileUtil.storeLines(lines, passFile);
}
@Nullable
private static String getPassword(String config) {
final File passFile = getPassFile();
try {
final BufferedReader reader =
new BufferedReader(new InputStreamReader(new FileInputStream(passFile), CvsApplicationLevelConfiguration.getCharset()));
try {
return findPasswordIn(reader, config);
}
finally {
reader.close();
}
}
catch (IOException e) {
return null;
}
}
private static File getPassFile() {
return CvsApplicationLevelConfiguration.getInstance().getPassFile();
}
@Nullable
private static String findPasswordIn(BufferedReader reader, String config) throws IOException {
String line;
while ((line = reader.readLine()) != null) {
final int position = line.indexOf(config);
if (position == -1) {
continue;
}
final String result = line.substring(position + config.length());
if (result.isEmpty()) {
continue;
}
return result.substring(1);
}
return null;
}
}