package org.zaproxy.zap.authentication;
import java.awt.BorderLayout;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JOptionPane;
import net.sf.json.JSONObject;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control;
import org.zaproxy.zap.extension.api.ApiDynamicActionImplementor;
import org.zaproxy.zap.extension.api.ApiException;
import org.zaproxy.zap.extension.api.ApiResponse;
import org.zaproxy.zap.extension.api.ApiResponseSet;
import org.zaproxy.zap.extension.users.ExtensionUserManagement;
import org.zaproxy.zap.extension.users.UsersAPI;
import org.zaproxy.zap.model.Context;
import org.zaproxy.zap.users.User;
import org.zaproxy.zap.utils.ApiUtils;
import org.zaproxy.zap.utils.EncodingUtils;
import org.zaproxy.zap.view.DynamicFieldsPanel;
public class GenericAuthenticationCredentials implements AuthenticationCredentials {
private static final String API_NAME = "GenericAuthenticationCredentials";
private String[] paramNames;
private Map<String, String> paramValues;
public GenericAuthenticationCredentials(String[] paramNames) {
super();
this.paramNames = paramNames;
this.paramValues = new HashMap<String, String>(paramNames.length);
}
public String getParam(String paramName) {
return paramValues.get(paramName);
}
public String setParam(String paramName, String paramValue) {
return paramValues.put(paramName, paramValue);
}
@Override
public boolean isConfigured() {
return true;
}
@Override
public String encode(String parentFieldSeparator) {
return EncodingUtils.mapToString(paramValues);
}
@Override
public void decode(String encodedCredentials) {
this.paramValues = EncodingUtils.stringToMap(encodedCredentials);
this.paramNames = this.paramValues.keySet().toArray(new String[this.paramValues.size()]);
}
@Override
public ApiResponse getApiResponseRepresentation() {
Map<String, String> values = new HashMap<>(paramValues);
values.put("type", API_NAME);
return new ApiResponseSet<String>("credentials", values);
}
/**
* The Options Panel used for configuring a {@link GenericAuthenticationCredentials}.
*/
protected static class GenericAuthenticationCredentialsOptionsPanel extends
AbstractCredentialsOptionsPanel<GenericAuthenticationCredentials> {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = -6486907666459197059L;
/** The dynamic fields panel. */
private DynamicFieldsPanel fieldsPanel;
public GenericAuthenticationCredentialsOptionsPanel(GenericAuthenticationCredentials credentials) {
super(credentials);
initialize();
}
/**
* Initialize the options panel, creating the views.
*/
private void initialize() {
this.setLayout(new BorderLayout());
this.fieldsPanel = new DynamicFieldsPanel(credentials.paramNames);
this.fieldsPanel.bindFieldValues(this.credentials.paramValues);
this.add(fieldsPanel, BorderLayout.CENTER);
}
@Override
public boolean validateFields() {
try {
this.fieldsPanel.validateFields();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, ex.getMessage(),
Constant.messages.getString("authentication.method.fb.dialog.error.title"),
JOptionPane.WARNING_MESSAGE);
return false;
}
return true;
}
@Override
public void saveCredentials() {
this.credentials.paramValues = new HashMap<>(this.fieldsPanel.getFieldValues());
}
}
private static final String ACTION_SET_CREDENTIALS = "scriptBasedAuthenticationCredentials";
private static final String PARAM_CONFIG_PARAMS = "authenticationCredentialsParams";
/**
* Gets the api action for setting a {@link GenericAuthenticationCredentials} for an User.
*
* @param methodType the method type for which this is called
* @return api action implementation
*/
public static ApiDynamicActionImplementor getSetCredentialsForUserApiAction(
final AuthenticationMethodType methodType) {
return new ApiDynamicActionImplementor(ACTION_SET_CREDENTIALS, null,
new String[] { PARAM_CONFIG_PARAMS }) {
@Override
public void handleAction(JSONObject params) throws ApiException {
Context context = ApiUtils.getContextByParamId(params, UsersAPI.PARAM_CONTEXT_ID);
int userId = ApiUtils.getIntParam(params, UsersAPI.PARAM_USER_ID);
// Make sure the type of authentication method is compatible
if (!methodType.isTypeForMethod(context.getAuthenticationMethod()))
throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER,
"User's credentials should match authentication method type of the context: "
+ context.getAuthenticationMethod().getType().getName());
// NOTE: no need to check if extension is loaded as this method is called only if
// the Users extension is loaded
ExtensionUserManagement extensionUserManagement = (ExtensionUserManagement) Control
.getSingleton().getExtensionLoader().getExtension(ExtensionUserManagement.NAME);
User user = extensionUserManagement.getContextUserAuthManager(context.getIndex())
.getUserById(userId);
if (user == null)
throw new ApiException(ApiException.Type.USER_NOT_FOUND, UsersAPI.PARAM_USER_ID);
// Build and set the credentials
GenericAuthenticationCredentials credentials = (GenericAuthenticationCredentials) context
.getAuthenticationMethod().createAuthenticationCredentials();
for (String paramName : credentials.paramNames)
credentials.setParam(paramName, ApiUtils.getNonEmptyStringParam(params, paramName));
user.setAuthenticationCredentials(credentials);
}
};
}
}