Package org.sonatype.nexus.rest.global

Source Code of org.sonatype.nexus.rest.global.GlobalConfigurationPlexusResource

/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2007-2014 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.rest.global;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.sonatype.configuration.ConfigurationException;
import org.sonatype.configuration.validation.InvalidConfigurationException;
import org.sonatype.micromailer.Address;
import org.sonatype.nexus.configuration.application.DefaultGlobalRemoteConnectionSettings;
import org.sonatype.nexus.configuration.application.DefaultGlobalRemoteProxySettings;
import org.sonatype.nexus.configuration.application.GlobalRemoteProxySettings;
import org.sonatype.nexus.configuration.model.CRemoteConnectionSettings;
import org.sonatype.nexus.configuration.model.CRemoteProxySettings;
import org.sonatype.nexus.configuration.model.CRestApiSettings;
import org.sonatype.nexus.configuration.model.CSmtpConfiguration;
import org.sonatype.nexus.configuration.source.ApplicationConfigurationSource;
import org.sonatype.nexus.proxy.repository.UsernamePasswordRemoteAuthenticationSettings;
import org.sonatype.nexus.rest.model.GlobalConfigurationResource;
import org.sonatype.nexus.rest.model.GlobalConfigurationResourceResponse;
import org.sonatype.nexus.rest.model.HtmlUnescapeStringConverter;
import org.sonatype.nexus.rest.model.RemoteConnectionSettings;
import org.sonatype.nexus.rest.model.RemoteProxySettingsDTO;
import org.sonatype.nexus.rest.model.RestApiSettings;
import org.sonatype.nexus.rest.model.SmtpSettings;
import org.sonatype.plexus.rest.resource.PathProtectionDescriptor;
import org.sonatype.plexus.rest.resource.PlexusResourceException;
import org.sonatype.security.configuration.source.SecurityConfigurationSource;

import com.thoughtworks.xstream.XStream;
import org.apache.commons.lang.StringUtils;
import org.restlet.Context;
import org.restlet.data.Reference;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.ResourceException;
import org.restlet.resource.Variant;

/**
* The GlobalConfiguration resource. It simply gets and builds the requested config REST model (DTO) and passes
* serializes it using underlying representation mechanism.
*
* @author cstamas
* @author tstevens
*/
@Named
@Singleton
@Path(GlobalConfigurationPlexusResource.RESOURCE_URI)
@Produces({"application/xml", "application/json"})
@Consumes({"application/xml", "application/json"})
public class GlobalConfigurationPlexusResource
    extends AbstractGlobalConfigurationPlexusResource
{
  /**
   * The config key used in URI and request attributes
   */
  public static final String CONFIG_NAME_KEY = "configName";

  public static final String RESOURCE_URI = "/global_settings/{" + CONFIG_NAME_KEY + "}";

  /**
   * Name denoting current Nexus configuration
   */
  public static final String CURRENT_CONFIG_NAME = "current";

  /**
   * Name denoting default Nexus configuration
   */
  public static final String DEFAULT_CONFIG_NAME = "default";

  private final SecurityConfigurationSource defaultSecurityConfigurationSource;

  private final ApplicationConfigurationSource configurationSource;

  @Inject
  public GlobalConfigurationPlexusResource(final @Named("static") SecurityConfigurationSource defaultSecurityConfigurationSource,
                                           final @Named("static") ApplicationConfigurationSource configurationSource)
  {
    this.defaultSecurityConfigurationSource = defaultSecurityConfigurationSource;
    this.configurationSource = configurationSource;

    this.setModifiable(true);
  }

  // ----------------------------------------------------------------------------
  // Default Configuration
  // ----------------------------------------------------------------------------

  public boolean isDefaultAnonymousAccessEnabled() {
    return this.defaultSecurityConfigurationSource.getConfiguration().isAnonymousAccessEnabled();
  }

  public String getDefaultAnonymousUsername() {
    return this.defaultSecurityConfigurationSource.getConfiguration().getAnonymousUsername();
  }

  public String getDefaultAnonymousPassword() {
    return this.defaultSecurityConfigurationSource.getConfiguration().getAnonymousPassword();
  }

  public List<String> getDefaultRealms() {
    return this.defaultSecurityConfigurationSource.getConfiguration().getRealms();
  }

  public CRemoteConnectionSettings readDefaultGlobalRemoteConnectionSettings() {
    return configurationSource.getConfiguration().getGlobalConnectionSettings();
  }

  public CRemoteProxySettings readDefaultRemoteProxySettings() {
    return configurationSource.getConfiguration().getRemoteProxySettings();
  }

  public CRestApiSettings readDefaultRestApiSettings() {
    return configurationSource.getConfiguration().getRestApi();
  }

  public CSmtpConfiguration readDefaultSmtpConfiguration() {
    return configurationSource.getConfiguration().getSmtpConfiguration();
  }

  // ==

  @Override
  public Object getPayloadInstance() {
    return new GlobalConfigurationResourceResponse();
  }

  @Override
  public String getResourceUri() {
    return RESOURCE_URI;
  }

  @Override
  public PathProtectionDescriptor getResourceProtection() {
    return new PathProtectionDescriptor("/global_settings/*", "authcBasic,perms[nexus:settings]");
  }

  /**
   * Get the specified global configuration (i.e. current or default)
   *
   * @param configName The name of the config (as returned by the global configuration list resource) to get.
   */
  @Override
  @GET
  public GlobalConfigurationResourceResponse get(Context context, Request request, Response response, Variant variant)
      throws ResourceException
  {
    String configurationName = request.getAttributes().get(CONFIG_NAME_KEY).toString();

    if (!DEFAULT_CONFIG_NAME.equals(configurationName) && !CURRENT_CONFIG_NAME.equals(configurationName)) {
      throw new ResourceException(Status.CLIENT_ERROR_NOT_FOUND);
    }
    else {
      GlobalConfigurationResource resource = new GlobalConfigurationResource();

      if (DEFAULT_CONFIG_NAME.equals(configurationName)) {
        fillDefaultConfiguration(request, resource);
      }
      else {
        fillCurrentConfiguration(request, resource);
      }

      GlobalConfigurationResourceResponse result = new GlobalConfigurationResourceResponse();

      result.setData(resource);

      return result;
    }
  }

  /**
   * Update the global configuration.
   *
   * @param configName The name of the config (as returned by the global configuration list resource) to update.
   */
  @Override
  @PUT
  public GlobalConfigurationResourceResponse put(Context context, Request request, Response response, Object payload)
      throws ResourceException
  {
    String configurationName = request.getAttributes().get(CONFIG_NAME_KEY).toString();

    if (!DEFAULT_CONFIG_NAME.equals(configurationName) && !CURRENT_CONFIG_NAME.equals(configurationName)) {
      throw new ResourceException(Status.CLIENT_ERROR_NOT_FOUND);
    }
    else if (!CURRENT_CONFIG_NAME.equals(configurationName)) {
      throw new ResourceException(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
    }
    else {
      GlobalConfigurationResourceResponse configRequest = (GlobalConfigurationResourceResponse) payload;

      if (configRequest != null) {
        GlobalConfigurationResource resource = configRequest.getData();

        try {
          if (resource.getSmtpSettings() != null) {
            SmtpSettings settings = resource.getSmtpSettings();

            getNexusEmailer().setSMTPHostname(settings.getHost());

            // lookup old password
            String oldPassword = getNexusEmailer().getSMTPPassword();

            if (settings.getPassword() == null) {
              settings.setPassword("");
            }
            getNexusEmailer().setSMTPPassword(this.getActualPassword(settings.getPassword(), oldPassword));

            getNexusEmailer().setSMTPPort(settings.getPort());

            getNexusEmailer().setSMTPSslEnabled(settings.isSslEnabled());

            getNexusEmailer().setSMTPTlsEnabled(settings.isTlsEnabled());

            if (settings.getUsername() == null) {
              settings.setUsername("");
            }
            getNexusEmailer().setSMTPUsername(settings.getUsername());

            getNexusEmailer().setSMTPSystemEmailAddress(
                new Address(settings.getSystemEmailAddress().trim()));
          }

          if (resource.getGlobalConnectionSettings() != null) {
            RemoteConnectionSettings s = resource.getGlobalConnectionSettings();

            getGlobalRemoteConnectionSettings().setConnectionTimeout(s.getConnectionTimeout() * 1000);

            getGlobalRemoteConnectionSettings().setRetrievalRetryCount(s.getRetrievalRetryCount());

            getGlobalRemoteConnectionSettings().setQueryString(s.getQueryString());

            getGlobalRemoteConnectionSettings().setUserAgentCustomizationString(s.getUserAgentString());
          }

          setGlobalProxySettings(resource.getRemoteProxySettings(), getGlobalRemoteProxySettings());

          getNexusConfiguration().setRealms(resource.getSecurityRealms());

          final String anonymousUsername = resource.getSecurityAnonymousUsername();
          final String anonymousPassword =
              getActualPassword(resource.getSecurityAnonymousPassword(),
                  getNexusConfiguration().getAnonymousPassword());

          if (resource.isSecurityAnonymousAccessEnabled() && !StringUtils.isEmpty(anonymousUsername)
              && !StringUtils.isEmpty(anonymousPassword)) {
            getNexusConfiguration().setAnonymousAccess(true, anonymousUsername, anonymousPassword);
          }
          else if (resource.isSecurityAnonymousAccessEnabled()) {
            // the supplied anon auth info is wrong/empty
            getLogger().warn(
                "Nexus refused to apply configuration, the supplied anonymous username/pwd information is empty.");

            throw new PlexusResourceException(Status.CLIENT_ERROR_BAD_REQUEST, getNexusErrorResponse(
                "securityAnonymousUsername", "Cannot be empty when Anonynous access is enabled"));
          }
          else {
            getNexusConfiguration().setAnonymousAccess(false, null, null);
          }

          if (resource.getGlobalRestApiSettings() != null) {
            RestApiSettings restApiSettings = resource.getGlobalRestApiSettings();

            getGlobalRestApiSettings().setForceBaseUrl(restApiSettings.isForceBaseUrl());

            if (StringUtils.isEmpty(resource.getGlobalRestApiSettings().getBaseUrl())) {
              getGlobalRestApiSettings().setBaseUrl(null);
            }
            else {
              getGlobalRestApiSettings().setBaseUrl(
                  new Reference(restApiSettings.getBaseUrl()).getTargetRef().toString());
            }

            getGlobalRestApiSettings().setUITimeout(restApiSettings.getUiTimeout() * 1000);
          }
          else {
            getGlobalRestApiSettings().disable();
          }

          // NEXUS-3064: to "inform" global remote storage context (and hence, all affected proxy
          // repositories) about the change, but only if config is saved okay
          // TODO: this is wrong, the config framework should "tell" this changed, but we have some
          // design flaw here: the globalRemoteStorageContext is NOT a component, while the settings are
          boolean remoteConnectionSettingsIsDirty = ((DefaultGlobalRemoteConnectionSettings)getGlobalRemoteConnectionSettings()).isDirty();

          boolean remoteProxySettingsIsDirty = ((DefaultGlobalRemoteProxySettings)getGlobalRemoteProxySettings()).isDirty();

          getNexusConfiguration().saveConfiguration();

          // NEXUS-3064: to "inform" global remote storage context (and hence, all affected proxy
          // repositories) about the change, but only if config is saved okay
          // TODO: this is wrong, the config framework should "tell" this changed, but we have some
          // design flaw here: the globalRemoteStorageContext is NOT a component, while the settings are
          if (remoteConnectionSettingsIsDirty) {
            getNexusConfiguration().getGlobalRemoteStorageContext().setRemoteConnectionSettings(
                getGlobalRemoteConnectionSettings());
          }

          if (remoteProxySettingsIsDirty) {
            getNexusConfiguration().getGlobalRemoteStorageContext().setRemoteProxySettings(
                getGlobalRemoteProxySettings()
            );
          }
        }
        catch (IOException e) {
          getLogger().warn("Got IO Exception during update of Nexus configuration.", e);

          throw new ResourceException(Status.SERVER_ERROR_INTERNAL);
        }
        catch (InvalidConfigurationException e) {
          // TODO: this should be removed from the Global config, as it is NO longer part of the nexus.xml
          getLogger().debug("Configuraiton Exception while setting security values", e);
          this.handleInvalidConfigurationException(e);
        }
        catch (ConfigurationException e) {
          getLogger().warn("Nexus refused to apply configuration.", e);

          throw new PlexusResourceException(Status.CLIENT_ERROR_BAD_REQUEST, e.getMessage(),
              getNexusErrorResponse("*", e.getMessage()));
        }
      }
    }
    // TODO: this method needs some serious cleaning up...
    response.setStatus(Status.SUCCESS_NO_CONTENT);
    return null;
  }

  private void setGlobalProxySettings(final RemoteProxySettingsDTO remoteProxySettings,
                                      final GlobalRemoteProxySettings remoteProxySettingsConfiguration)
      throws ConfigurationException
  {
    if (remoteProxySettings != null
        && remoteProxySettings.getHttpProxySettings() != null
        && !StringUtils.isEmpty(remoteProxySettings.getHttpProxySettings().getProxyHostname())) {
      String oldHttpProxyPassword = null;
      if (remoteProxySettingsConfiguration.getHttpProxySettings() != null
          && remoteProxySettingsConfiguration.getHttpProxySettings().getProxyAuthentication() != null) {
        oldHttpProxyPassword =
            ((UsernamePasswordRemoteAuthenticationSettings) remoteProxySettingsConfiguration.getHttpProxySettings()
                .getProxyAuthentication()).getPassword();
      }

      String oldHttpsProxyPassword = null;
      if (remoteProxySettingsConfiguration.getHttpsProxySettings() != null
          && remoteProxySettingsConfiguration.getHttpsProxySettings().getProxyAuthentication() != null) {
        oldHttpsProxyPassword =
            ((UsernamePasswordRemoteAuthenticationSettings) remoteProxySettingsConfiguration.getHttpsProxySettings()
                .getProxyAuthentication()).getPassword();
      }

      remoteProxySettingsConfiguration.setHttpProxySettings(
          convert(remoteProxySettings.getHttpProxySettings(), oldHttpProxyPassword)
      );

      remoteProxySettingsConfiguration.setHttpsProxySettings(
          convert(remoteProxySettings.getHttpsProxySettings(), oldHttpsProxyPassword)
      );

      List<String> nonProxyHosts = remoteProxySettings.getNonProxyHosts();
      if (nonProxyHosts != null && !nonProxyHosts.isEmpty()) {
        // removing nulls and empty strings
        HashSet<String> cleanNonProxyHosts = new HashSet<String>();
        for (String host : nonProxyHosts) {
          if (StringUtils.isNotEmpty(host)) {
            cleanNonProxyHosts.add(host);
          }
        }
        remoteProxySettingsConfiguration.setNonProxyHosts(cleanNonProxyHosts);
      }
      else {
        // clear it out
        remoteProxySettingsConfiguration.setNonProxyHosts(null);
      }
    }
    else {
      remoteProxySettingsConfiguration.setHttpProxySettings(null);
      remoteProxySettingsConfiguration.setHttpsProxySettings(null);
      remoteProxySettingsConfiguration.setNonProxyHosts(null);
    }
  }

  /**
   * Externalized Nexus object to DTO's conversion, using default Nexus configuration.
   */
  protected void fillDefaultConfiguration(Request request, GlobalConfigurationResource resource) {

    resource.setSecurityAnonymousAccessEnabled(isDefaultAnonymousAccessEnabled());

    resource.setSecurityRealms(getDefaultRealms());

    resource.setSecurityAnonymousUsername(getDefaultAnonymousUsername());

    resource.setSecurityAnonymousPassword(PASSWORD_PLACE_HOLDER);

    resource.setGlobalConnectionSettings(convert(readDefaultGlobalRemoteConnectionSettings()));

    resource.setRemoteProxySettings(convert(readDefaultRemoteProxySettings()));

    RestApiSettings restApiSettings = convert(readDefaultRestApiSettings());
    if (restApiSettings != null) {
      restApiSettings.setBaseUrl(getContextRoot(request).getTargetRef().toString());
    }
    resource.setGlobalRestApiSettings(restApiSettings);

    resource.setSmtpSettings(convert(readDefaultSmtpConfiguration()));
  }

  /**
   * Externalized Nexus object to DTO's conversion, using current Nexus configuration.
   */
  protected void fillCurrentConfiguration(Request request, GlobalConfigurationResource resource) {

    resource.setSecurityAnonymousAccessEnabled(getNexusConfiguration().isAnonymousAccessEnabled());

    resource.setSecurityRealms(getNexusConfiguration().getRealms());

    resource.setSecurityAnonymousUsername(getNexusConfiguration().getAnonymousUsername());

    resource.setSecurityAnonymousPassword(PASSWORD_PLACE_HOLDER);

    resource.setGlobalConnectionSettings(convert(getGlobalRemoteConnectionSettings()));

    resource.setRemoteProxySettings(convert(getGlobalRemoteProxySettings()));

    RestApiSettings restApiSettings = convert(getGlobalRestApiSettings());
    if (restApiSettings != null && StringUtils.isEmpty(restApiSettings.getBaseUrl())) {
      restApiSettings.setBaseUrl(getContextRoot(request).getTargetRef().toString());
    }
    resource.setGlobalRestApiSettings(restApiSettings);

    resource.setSmtpSettings(convert(getNexusEmailer()));
  }

  protected String getSecurityConfiguration(boolean enabled, String authSourceType) {
    if (!enabled) {
      return SECURITY_OFF;
    }
    else {
      if (SECURITY_SIMPLE.equals(authSourceType)) {
        return SECURITY_SIMPLE;
      }
      else {
        return SECURITY_CUSTOM;
      }
    }
  }

  @Override
  public void configureXStream(final XStream xstream) {
    xstream.registerLocalConverter(SmtpSettings.class, "username", new HtmlUnescapeStringConverter(true));
    xstream.registerLocalConverter(SmtpSettings.class, "password", new HtmlUnescapeStringConverter(true));
  }
}
TOP

Related Classes of org.sonatype.nexus.rest.global.GlobalConfigurationPlexusResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.