/*
* Copyright (C) 2015 Square, Inc.
*
* 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 keywhiz.cli;
import com.beust.jcommander.JCommander;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.inject.name.Named;
import java.io.IOException;
import java.net.HttpCookie;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Inject;
import keywhiz.cli.commands.*;
import keywhiz.cli.configs.*;
import keywhiz.client.KeywhizClient;
import keywhiz.client.KeywhizClient.UnauthorizedException;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import static com.google.common.base.StandardSystemProperty.USER_HOME;
import static com.google.common.base.StandardSystemProperty.USER_NAME;
import static java.lang.String.format;
public class CommandExecutor {
public static final String APP_VERSION = "2.1";
public enum Command { LOGIN, LIST, DESCRIBE, ADD, UPDATE, DELETE, ASSIGN, UNASSIGN, VERSIONS, ROLLBACK }
private final Path cookieDir = Paths.get(USER_HOME.value());
private final String command;
private final Map commands;
private final JCommander parentCommander;
private final JCommander commander;
private final CliConfiguration config;
private final ObjectMapper mapper;
@Inject
public CommandExecutor(CliConfiguration config, @Named("Command") @Nullable String command,
@Named("CommandMap") Map commands, @Named("ParentCommander") JCommander parentCommander,
@Named("Commander") @Nullable JCommander commander, ObjectMapper mapper) {
this.command = command;
this.commands = commands;
this.parentCommander = parentCommander;
this.commander = commander;
this.config = config;
this.mapper = mapper;
}
public void executeCommand() throws IOException {
if (command == null) {
if (config.version) {
System.out.println("Version: " + APP_VERSION);
} else {
System.err.println("Must specify a command.");
parentCommander.usage();
}
return;
}
HttpUrl url;
if (Strings.isNullOrEmpty(config.url)) {
url = HttpUrl.parse("https://localhost:4444");
System.out.println("Server URL not specified (--url flag), assuming " + url);
} else {
url = HttpUrl.parse(config.url);
if (url == null) {
System.err.print("Invalid URL " + config.url);
return;
}
}
KeywhizClient client;
OkHttpClient httpClient;
String user = config.getUser().orElse(USER_NAME.value());
Path cookiePath = cookieDir.resolve(format(".keywhiz.%s.cookie", user));
try {
List<HttpCookie> cookieList = ClientUtils.loadCookies(cookiePath);
httpClient = ClientUtils.sslOkHttpClient(config.getDevTrustStore(), cookieList);
client = new KeywhizClient(mapper, httpClient, url);
// Try a simple get request to determine whether or not the cookies are still valid
if(!client.isLoggedIn()) {
throw new UnauthorizedException();
}
} catch (IOException e) {
// Either could not find the cookie file, or the cookies were expired -- must login manually.
httpClient = ClientUtils.sslOkHttpClient(config.getDevTrustStore(), ImmutableList.of());
client = new KeywhizClient(mapper, httpClient, url);
char[] password = ClientUtils.readPassword(user);
client.login(user, password);
Arrays.fill(password, '\0');
}
// Save/update the cookies if we logged in successfully
ClientUtils.saveCookies(cookiePath);
Printing printing = new Printing(client);
Command cmd = Command.valueOf(command.toUpperCase().trim());
switch (cmd) {
case LIST:
new ListAction((ListActionConfig) commands.get(command), client, printing).run();
break;
case DESCRIBE:
new DescribeAction((DescribeActionConfig) commands.get(command), client, printing).run();
break;
case ADD:
new AddAction((AddActionConfig) commands.get(command), client, mapper).run();
break;
case UPDATE:
new UpdateAction((UpdateActionConfig) commands.get(command), client, mapper).run();
break;
case DELETE:
new DeleteAction((DeleteActionConfig) commands.get(command), client).run();
break;
case ASSIGN:
new AssignAction((AssignActionConfig) commands.get(command), client).run();
break;
case UNASSIGN:
new UnassignAction((UnassignActionConfig) commands.get(command), client).run();
break;
case VERSIONS:
new ListVersionsAction((ListVersionsActionConfig) commands.get(command), client, printing).run();
break;
case ROLLBACK:
new RollbackAction((RollbackActionConfig) commands.get(command), client).run();
break;
case LOGIN:
// User is already logged in at this point
break;
default:
commander.usage();
}
}
}