* Updates to repositories and proxy connector configuration / admin screens.

git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@535418 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Joakim Erdfelt 2007-05-05 00:05:23 +00:00
parent 42b4801878
commit f8b9e076b3
59 changed files with 2631 additions and 1269 deletions

View File

@ -0,0 +1,55 @@
package org.apache.maven.archiva.configuration.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.commons.collections.Predicate;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
/**
* Predicate for {@link RepositoryConfiguration} objects that are local (aka managed)
* {@link RepositoryConfiguration#isManaged()}
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class LocalRepositoryPredicate
implements Predicate
{
public static final Predicate INSTANCE = new LocalRepositoryPredicate();
public static Predicate getInstance()
{
return INSTANCE;
}
public boolean evaluate( Object object )
{
boolean satisfies = false;
if ( object instanceof RepositoryConfiguration )
{
RepositoryConfiguration repoconfig = (RepositoryConfiguration) object;
return repoconfig.isManaged();
}
return satisfies;
}
}

View File

@ -0,0 +1,59 @@
package org.apache.maven.archiva.configuration.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
/**
* ProxyConnectorPredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ProxyConnectorSelectionPredicate
implements Predicate
{
private String sourceId;
private String targetId;
public ProxyConnectorSelectionPredicate( String sourceId, String targetId )
{
this.sourceId = sourceId;
this.targetId = targetId;
}
public boolean evaluate( Object object )
{
boolean satisfies = false;
if ( object instanceof ProxyConnectorConfiguration )
{
ProxyConnectorConfiguration connector = (ProxyConnectorConfiguration) object;
return ( StringUtils.equals( sourceId, connector.getSourceRepoId() ) && StringUtils
.equals( targetId, connector.getTargetRepoId() ) );
}
return satisfies;
}
}

View File

@ -0,0 +1,54 @@
package org.apache.maven.archiva.configuration.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.commons.collections.Predicate;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
/**
* Predicate for {@link RepositoryConfiguration} objects that are remote
* {@link RepositoryConfiguration#isRemote()}
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class RemoteRepositoryPredicate
implements Predicate
{
public static final Predicate INSTANCE = new RemoteRepositoryPredicate();
public static Predicate getInstance()
{
return INSTANCE;
}
public boolean evaluate( Object object )
{
boolean satisfies = false;
if ( object instanceof RepositoryConfiguration )
{
RepositoryConfiguration repoconfig = (RepositoryConfiguration) object;
return repoconfig.isRemote();
}
return satisfies;
}
}

View File

@ -0,0 +1,63 @@
package org.apache.maven.archiva.configuration.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import java.util.Comparator;
/**
* RepositoryConfigurationComparator
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class RepositoryConfigurationComparator
implements Comparator
{
public int compare( Object o1, Object o2 )
{
if ( o1 == null && o2 == null )
{
return 0;
}
if ( o1 == null && o2 != null )
{
return 1;
}
if ( o1 != null && o2 == null )
{
return -1;
}
if ( ( o1 instanceof RepositoryConfiguration ) && ( o2 instanceof RepositoryConfiguration ) )
{
String id1 = ( (RepositoryConfiguration) o1 ).getId();
String id2 = ( (RepositoryConfiguration) o2 ).getId();
return id1.compareToIgnoreCase( id2 );
}
return 0;
}
}

View File

@ -0,0 +1,56 @@
package org.apache.maven.archiva.configuration.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.commons.collections.Closure;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import java.util.List;
/**
* RepositoryIdListClosure
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class RepositoryIdListClosure
implements Closure
{
private List list;
public RepositoryIdListClosure( List list )
{
this.list = list;
}
public void execute( Object input )
{
if ( input instanceof RepositoryConfiguration )
{
RepositoryConfiguration repoconfig = (RepositoryConfiguration) input;
list.add( repoconfig.getId() );
}
}
public List getList()
{
return list;
}
}

View File

@ -365,7 +365,7 @@
<field>
<name>policies</name>
<version>1.0.0+</version>
<type>Properties</type>
<type>Map</type>
<description>Policy configuration for the connector.</description>
<association xml.mapStyle="inline">
<type>String</type>
@ -375,7 +375,7 @@
<field>
<name>properties</name>
<version>1.0.0+</version>
<type>Properties</type>
<type>Map</type>
<description>Configuration for the connector.</description>
<association xml.mapStyle="inline">
<type>String</type>
@ -401,7 +401,14 @@
return null;
}
return this.getPolicies().getProperty( policyId, defaultValue );
Object value = this.getPolicies().get( policyId );
if ( value == null )
{
return defaultValue;
}
return (String) value;
}
]]></code>
</codeSegment>

View File

@ -24,10 +24,10 @@ import org.apache.maven.archiva.common.utils.VersionUtil;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
* AbstractUpdatePolicy
@ -76,21 +76,26 @@ public abstract class AbstractUpdatePolicy
*/
public static final String ONCE = "once";
private Set validPolicyCodes = new HashSet();
private List options = new ArrayList();
public AbstractUpdatePolicy()
{
validPolicyCodes.add( IGNORED );
validPolicyCodes.add( DISABLED );
validPolicyCodes.add( DAILY );
validPolicyCodes.add( HOURLY );
validPolicyCodes.add( ONCE );
options.add( IGNORED );
options.add( DISABLED );
options.add( DAILY );
options.add( HOURLY );
options.add( ONCE );
}
protected abstract boolean isSnapshotPolicy();
protected abstract String getUpdateMode();
public List getOptions()
{
return options;
}
public boolean applyPolicy( String policySetting, Properties request, File localFile )
{
String version = request.getProperty( "version", "" );
@ -101,7 +106,7 @@ public abstract class AbstractUpdatePolicy
isSnapshotVersion = VersionUtil.isSnapshot( version );
}
if ( !validPolicyCodes.contains( policySetting ) )
if ( !options.contains( policySetting ) )
{
// No valid code? false it is then.
getLogger().error( "Unknown artifact-update policyCode [" + policySetting + "]" );

View File

@ -24,9 +24,9 @@ import org.apache.maven.archiva.policies.urlcache.UrlFailureCache;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import java.io.File;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
* {@link PreDownloadPolicy} to check if the requested url has failed before.
@ -53,17 +53,17 @@ public class CachedFailuresPolicy
*/
private UrlFailureCache urlFailureCache;
private Set validPolicyCodes = new HashSet();
private List options = new ArrayList();
public CachedFailuresPolicy()
{
validPolicyCodes.add( IGNORED );
validPolicyCodes.add( CACHED );
options.add( IGNORED );
options.add( CACHED );
}
public boolean applyPolicy( String policySetting, Properties request, File localFile )
{
if ( !validPolicyCodes.contains( policySetting ) )
if ( !options.contains( policySetting ) )
{
// No valid code? false it is then.
getLogger().error( "Unknown checksum policyCode [" + policySetting + "]" );
@ -93,8 +93,18 @@ public class CachedFailuresPolicy
return true;
}
public String getDefaultPolicySetting()
public String getDefaultOption()
{
return IGNORED;
}
public String getId()
{
return "cache-failures";
}
public List getOptions()
{
return options;
}
}

View File

@ -27,9 +27,9 @@ import org.codehaus.plexus.logging.AbstractLogEnabled;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
* ChecksumPolicy
@ -73,18 +73,18 @@ public class ChecksumPolicy
*/
private ChecksumFile checksumFile;
private Set validPolicyCodes = new HashSet();
private List options = new ArrayList();
public ChecksumPolicy()
{
validPolicyCodes.add( FAIL );
validPolicyCodes.add( FIX );
validPolicyCodes.add( IGNORED );
options.add( FAIL );
options.add( FIX );
options.add( IGNORED );
}
public boolean applyPolicy( String policySetting, Properties request, File localFile )
{
if ( !validPolicyCodes.contains( policySetting ) )
if ( !options.contains( policySetting ) )
{
// No valid code? false it is then.
getLogger().error( "Unknown checksum policyCode [" + policySetting + "]" );
@ -275,9 +275,19 @@ public class ChecksumPolicy
}
}
public String getDefaultPolicySetting()
public String getDefaultOption()
{
return FIX;
}
public String getId()
{
return "checksum";
}
public List getOptions()
{
return options;
}
}

View File

@ -20,6 +20,7 @@ package org.apache.maven.archiva.policies;
*/
import java.io.File;
import java.util.List;
import java.util.Properties;
/**
@ -39,11 +40,25 @@ public interface DownloadPolicy
public static final boolean FAIL = false;
/**
* Get the default policy setting.
* Get the list of options for this policy.
*
* @return the default policy setting.
* @return the list of options for this policy.
*/
public String getDefaultPolicySetting();
public List getOptions();
/**
* Get the default option for this policy.
*
* @return the default policy for this policy.
*/
public String getDefaultOption();
/**
* Get the id for this policy.
*
* @return the id for this policy.
*/
public String getId();
/**
* Apply the download policy.

View File

@ -33,7 +33,7 @@ public class ReleasesPolicy
extends AbstractUpdatePolicy
implements PreDownloadPolicy
{
public String getDefaultPolicySetting()
public String getDefaultOption()
{
return AbstractUpdatePolicy.IGNORED;
}
@ -47,4 +47,9 @@ public class ReleasesPolicy
{
return "releases";
}
public String getId()
{
return "releases";
}
}

View File

@ -33,7 +33,7 @@ public class SnapshotsPolicy
extends AbstractUpdatePolicy
implements PreDownloadPolicy
{
public String getDefaultPolicySetting()
public String getDefaultOption()
{
return AbstractUpdatePolicy.IGNORED;
}
@ -47,4 +47,9 @@ public class SnapshotsPolicy
{
return "snapshots";
}
public String getId()
{
return "snapshots";
}
}

View File

@ -20,6 +20,7 @@ package org.apache.maven.archiva.proxy;
*/
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.ConfigurationNames;
import org.apache.maven.archiva.configuration.NetworkProxyConfiguration;
@ -494,7 +495,7 @@ public class DefaultRepositoryProxyConnectors
}
}
private boolean applyPolicies( Properties policySettings, Map downloadPolicies, Properties request, File localFile )
private boolean applyPolicies( Map policySettings, Map downloadPolicies, Properties request, File localFile )
{
Iterator it = downloadPolicies.entrySet().iterator();
while ( it.hasNext() )
@ -502,8 +503,8 @@ public class DefaultRepositoryProxyConnectors
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
DownloadPolicy policy = (DownloadPolicy) entry.getValue();
String defaultSetting = policy.getDefaultPolicySetting();
String setting = policySettings.getProperty( key, defaultSetting );
String defaultSetting = policy.getDefaultOption();
String setting = StringUtils.defaultString( (String) policySettings.get( key ), defaultSetting );
getLogger().debug( "Applying [" + key + "] policy with [" + setting + "]" );
if ( !policy.applyPolicy( setting, request, localFile ) )

View File

@ -22,9 +22,9 @@ package org.apache.maven.archiva.proxy;
import org.apache.maven.archiva.model.ArchivaRepository;
import org.apache.maven.archiva.repository.connector.RepositoryConnector;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Map;
/**
* This represents a connector for a repository to repository proxy.
@ -45,7 +45,7 @@ public class ProxyConnector
private String proxyId;
private Properties policies;
private Map policies;
public List getBlacklist()
{
@ -87,12 +87,12 @@ public class ProxyConnector
this.whitelist = whitelist;
}
public Properties getPolicies()
public Map getPolicies()
{
return policies;
}
public void setPolicies( Properties policies )
public void setPolicies( Map policies )
{
this.policies = policies;
}
@ -116,12 +116,12 @@ public class ProxyConnector
sb.append( " target:" ).append( this.targetRepository ).append( "\n" );
sb.append( " proxyId:" ).append( this.proxyId ).append( "\n" );
Enumeration keys = this.policies.propertyNames();
while ( keys.hasMoreElements() )
Iterator keys = this.policies.keySet().iterator();
while ( keys.hasNext() )
{
String name = (String) keys.nextElement();
String name = (String) keys.next();
sb.append( " policy[" ).append( name ).append( "]:" );
sb.append( this.policies.getProperty( name ) ).append( "\n" );
sb.append( this.policies.get( name ) ).append( "\n" );
}
sb.append( "]" );
@ -131,6 +131,6 @@ public class ProxyConnector
public void setPolicy( String policyId, String policySetting )
{
// TODO Auto-generated method stub
this.policies.put( policyId, policySetting );
}
}

View File

@ -1,150 +0,0 @@
package org.apache.maven.archiva.web.action.admin;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
//import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.InvalidConfigurationException;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.codehaus.plexus.rbac.profile.RoleProfileManager;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.security.rbac.Resource;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import java.io.IOException;
/**
* Base action for repository removal actions.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
*/
public abstract class AbstractDeleteRepositoryAction
extends PlexusActionSupport
implements SecureAction
{
/**
* @plexus.requirement
*/
private ArchivaConfiguration archivaConfiguration;
/**
* The repository ID to lookup when editing a repository.
*/
protected String repoId;
/**
* Which operation to select.
*/
private String operation = "unmodified";
/**
* @plexus.requirement role-hint="archiva"
*/
protected RoleProfileManager roleProfileManager;
public String execute()
throws IOException, InvalidConfigurationException, RegistryException
{
// TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
if ( "delete-entry".equals( operation ) || "delete-contents".equals( operation ) )
{
Configuration configuration = archivaConfiguration.getConfiguration();
// AbstractRepositoryConfiguration existingRepository = getRepository( configuration );
// if ( existingRepository == null )
// {
// addActionError( "A repository with that id does not exist" );
// return ERROR;
// }
//
// // TODO: remove from index too!
//
// removeRepository( configuration, existingRepository );
//
// archivaConfiguration.save( configuration );
//
// if ( "delete-contents".equals( operation ) )
// {
// removeContents( existingRepository );
// }
}
return SUCCESS;
}
// protected abstract void removeContents( AbstractRepositoryConfiguration existingRepository )
// throws IOException;
//
// protected abstract AbstractRepositoryConfiguration getRepository( Configuration configuration );
//
// protected abstract void removeRepository( Configuration configuration,
// AbstractRepositoryConfiguration existingRepository );
public String input()
{
return INPUT;
}
public String getRepoId()
{
return repoId;
}
public void setRepoId( String repoId )
{
this.repoId = repoId;
}
public String getOperation()
{
return operation;
}
public void setOperation( String operation )
{
this.operation = operation;
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();
bundle.setRequiresAuthentication( true );
if ( getRepoId() != null )
{
// TODO: not right. We only care about this permission on managed repositories. Otherwise, it's configuration
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY, getRepoId() );
}
else
{
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
}
return bundle;
}
}

View File

@ -1,208 +0,0 @@
package org.apache.maven.archiva.web.action.admin;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.ModelDriven;
import com.opensymphony.xwork.Preparable;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.InvalidConfigurationException;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.apache.maven.archiva.web.action.admin.models.AdminRepositoryConfiguration;
import org.codehaus.plexus.rbac.profile.RoleProfileException;
import org.codehaus.plexus.rbac.profile.RoleProfileManager;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.security.authorization.AuthorizationException;
import org.codehaus.plexus.security.authorization.AuthorizationResult;
import org.codehaus.plexus.security.rbac.RbacManagerException;
import org.codehaus.plexus.security.rbac.Resource;
import org.codehaus.plexus.security.system.SecuritySession;
import org.codehaus.plexus.security.system.SecuritySystem;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import java.io.File;
import java.io.IOException;
/**
* AbstractRepositoryAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public abstract class AbstractRepositoryAction
extends PlexusActionSupport
implements ModelDriven, Preparable, SecureAction
{
protected static final String SUCCESS = "success";
/**
* @plexus.requirement role-hint="archiva"
*/
private RoleProfileManager roleProfileManager;
/**
* @plexus.requirement
*/
private SecuritySystem securitySystem;
private String repoid;
private String mode;
/**
* @plexus.requirement
*/
protected ArchivaConfiguration archivaConfiguration;
/**
* The model for this action.
*/
protected AdminRepositoryConfiguration repository;
public String getMode()
{
return this.mode;
}
public Object getModel()
{
return getRepository();
}
public String getRepoid()
{
return repoid;
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();
bundle.setRequiresAuthentication( true );
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
return bundle;
}
public String input()
{
getLogger().info( "input()" );
return INPUT;
}
public abstract void prepare()
throws Exception;
public void setMode( String mode )
{
this.mode = mode;
}
public void setRepoid( String repoid )
{
this.repoid = repoid;
}
protected void addRepository( AdminRepositoryConfiguration repository )
throws IOException, RoleProfileException
{
getLogger().info( ".addRepository(" + repository + ")" );
if ( repository.isManaged() )
{
// Normalize the path
File file = new File( repository.getDirectory() );
repository.setDirectory( file.getCanonicalPath() );
if ( !file.exists() )
{
file.mkdirs();
// TODO: error handling when this fails, or is not a directory!
}
}
archivaConfiguration.getConfiguration().addRepository( repository );
// TODO: double check these are configured on start up
roleProfileManager.getDynamicRole( "archiva-repository-manager", repository.getId() );
roleProfileManager.getDynamicRole( "archiva-repository-observer", repository.getId() );
}
protected AdminRepositoryConfiguration getRepository()
{
if ( repository == null )
{
repository = new AdminRepositoryConfiguration();
}
return repository;
}
protected boolean operationAllowed( String permission, String repoid )
{
ActionContext context = ActionContext.getContext();
SecuritySession securitySession = (SecuritySession) context.get( SecuritySession.ROLE );
AuthorizationResult authzResult;
try
{
authzResult = securitySystem.authorize( securitySession, permission, repoid );
return authzResult.isAuthorized();
}
catch ( AuthorizationException e )
{
getLogger().info(
"Unable to authorize permission: " + permission + " against repo: " + repoid
+ " due to: " + e.getMessage() );
return false;
}
}
protected void removeRepository( String repoId )
{
getLogger().info( ".removeRepository()" );
RepositoryConfiguration toremove = archivaConfiguration.getConfiguration().findRepositoryById( repoId );
if ( toremove != null )
{
archivaConfiguration.getConfiguration().removeRepository( toremove );
}
}
protected String saveConfiguration()
throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException,
RegistryException
{
getLogger().info( ".saveConfiguration()" );
archivaConfiguration.save( archivaConfiguration.getConfiguration() );
addActionMessage( "Successfully saved configuration" );
return SUCCESS;
}
}

View File

@ -1,291 +0,0 @@
package org.apache.maven.archiva.web.action.admin;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.opensymphony.xwork.ModelDriven;
import com.opensymphony.xwork.Preparable;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.InvalidConfigurationException;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.apache.maven.archiva.web.action.admin.models.AdminRepositoryConfiguration;
import org.codehaus.plexus.rbac.profile.RoleProfileException;
import org.codehaus.plexus.rbac.profile.RoleProfileManager;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.security.rbac.RbacManagerException;
import org.codehaus.plexus.security.rbac.Resource;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import java.io.File;
import java.io.IOException;
/**
* Configures the application repositories.
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureRepositoryAction"
*/
public class ConfigureRepositoryAction
extends PlexusActionSupport
implements ModelDriven, Preparable, SecureAction
{
/**
* @plexus.requirement
*/
private ArchivaConfiguration archivaConfiguration;
/**
* @plexus.requirement role-hint="archiva"
*/
private RoleProfileManager roleProfileManager;
/**
* The repository.
*/
private AdminRepositoryConfiguration repository;
/**
* The repository ID to lookup when editing a repository.
*/
private String repoId;
/**
* The previously read configuration.
*/
private Configuration configuration;
public String add()
throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException,
RegistryException
{
// TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
getLogger().info( ".add()" );
AdminRepositoryConfiguration existingRepository = getRepository( repository.getId() );
if ( existingRepository != null )
{
addFieldError( "id", "A repository with that id already exists" );
return INPUT;
}
return saveConfiguration();
}
public String edit()
throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException,
RegistryException
{
// TODO: if this didn't come from the form, go to configure.action instead of going through with re-saving what was just loaded
getLogger().info( ".edit()" );
if ( StringUtils.isBlank( repository.getId() ) )
{
addFieldError( "id", "A repository with a blank id cannot be editted." );
return INPUT;
}
removeRepository( getRepository() );
addRepository();
return saveConfiguration();
}
public Configuration getConfiguration()
{
return configuration;
}
public Object getModel()
{
getLogger().info( ".getModel()" );
if( repository == null )
{
repository = createRepository();
}
return repository;
}
public String getRepoId()
{
return repoId;
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();
bundle.setRequiresAuthentication( true );
if ( getRepoId() != null )
{
// TODO: this is not right. It needs to change based on method. But is this really the right way to restrict this area?
// TODO: not right. We only care about this permission on managed repositories. Otherwise, it's configuration
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY, getRepoId() );
}
else
{
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
}
return bundle;
}
public String input()
{
getLogger().info( ".input()" );
return INPUT;
}
public String doDefault()
throws Exception
{
getLogger().info( ".doDefault()" );
return super.doDefault();
}
public String doInput()
throws Exception
{
getLogger().info( ".doInput()" );
return super.doInput();
}
public void validate()
{
getLogger().info( ".validate()" );
// super.validate();
}
public String execute()
throws Exception
{
getLogger().info( ".execute()" );
return super.execute();
}
public void prepare()
{
getLogger().info( ".prepare()" );
configuration = archivaConfiguration.getConfiguration();
if ( repository == null )
{
repository = getRepository( repoId );
}
if ( repository == null )
{
repository = createRepository();
}
}
public void setRepoId( String repoId )
{
this.repoId = repoId;
}
private void addRepository()
throws IOException, RoleProfileException
{
getLogger().info( ".addRepository()" );
AdminRepositoryConfiguration repository = (AdminRepositoryConfiguration) getRepository();
if ( repository.isManaged() )
{
// Normalize the path
File file = new File( repository.getDirectory() );
repository.setDirectory( file.getCanonicalPath() );
if ( !file.exists() )
{
file.mkdirs();
// TODO: error handling when this fails, or is not a directory!
}
}
configuration.addRepository( repository );
// TODO: double check these are configured on start up
roleProfileManager.getDynamicRole( "archiva-repository-manager", repository.getId() );
roleProfileManager.getDynamicRole( "archiva-repository-observer", repository.getId() );
}
private AdminRepositoryConfiguration createRepository()
{
getLogger().info( ".createRepository()" );
AdminRepositoryConfiguration repository = new AdminRepositoryConfiguration();
repository.setIndexed( false );
return repository;
}
private AdminRepositoryConfiguration getRepository()
{
return repository;
}
private AdminRepositoryConfiguration getRepository( String id )
{
getLogger().info( ".getRepository(" + id + ")" );
RepositoryConfiguration repoconfig = configuration.findRepositoryById( id );
if ( repoconfig == null )
{
return createRepository();
}
return new AdminRepositoryConfiguration( repoconfig );
}
private boolean removeRepository( RepositoryConfiguration existingRepository )
{
getLogger().info( ".removeRepository()" );
RepositoryConfiguration toremove = configuration.findRepositoryById( existingRepository.getId() );
if ( toremove != null )
{
configuration.removeRepository( toremove );
return true;
}
return false;
}
private String saveConfiguration()
throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException,
RegistryException
{
getLogger().info( ".saveConfiguration()" );
addRepository();
archivaConfiguration.save( configuration );
// TODO: do we need to check if indexing is needed?
addActionMessage( "Successfully saved configuration" );
return SUCCESS;
}
}

View File

@ -1,79 +0,0 @@
package org.apache.maven.archiva.web.action.admin;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
//import org.apache.maven.archiva.configuration.AbstractRepositoryConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import org.codehaus.plexus.rbac.profile.RoleProfileException;
import org.codehaus.plexus.util.FileUtils;
import java.io.IOException;
/**
* Configures the application repositories.
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="deleteRepositoryAction"
*/
public class DeleteRepositoryAction
extends AbstractDeleteRepositoryAction
{
// protected AbstractRepositoryConfiguration getRepository( Configuration configuration )
// {
// return configuration.getRepositoryById( repoId );
// }
//
// protected void removeRepository( Configuration configuration, AbstractRepositoryConfiguration existingRepository )
// {
// configuration.removeRepository( (RepositoryConfiguration) existingRepository );
//
// try
// {
// removeRepositoryRoles( existingRepository );
// }
// catch ( RoleProfileException e )
// {
// getLogger().error( "Error removing user roles associated with repository " + existingRepository.getId() );
// }
// }
//
// protected void removeContents( AbstractRepositoryConfiguration existingRepository )
// throws IOException
// {
// RepositoryConfiguration repository = (RepositoryConfiguration) existingRepository;
// getLogger().info( "Removing " + repository.getDirectory() );
// FileUtils.deleteDirectory( repository.getDirectory() );
// }
/**
* Remove user roles associated with the repository
*
* @param existingRepository
* @throws RoleProfileException
*/
// private void removeRepositoryRoles( AbstractRepositoryConfiguration existingRepository )
// throws RoleProfileException
// {
// roleProfileManager.deleteDynamicRole( "archiva-repository-manager", existingRepository.getId() );
// roleProfileManager.deleteDynamicRole( "archiva-repository-observer", existingRepository.getId() );
//
// getLogger().info( "removed user roles associated with repository " + existingRepository.getId() );
// }
}

View File

@ -1,71 +0,0 @@
package org.apache.maven.archiva.web.action.admin;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.apache.maven.archiva.web.action.admin.models.AdminRepositoryConfiguration;
/**
* EditRepositoryAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="editRepositoryAction"
*/
public class EditRepositoryAction
extends AbstractRepositoryAction
{
public String edit()
{
getLogger().info( ".edit()" );
if ( operationAllowed( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY, getRepoid() ) )
{
addActionError( "You do not have the appropriate permissions to edit the " + getRepoid() + " repository." );
return ERROR;
}
return INPUT;
}
public void prepare()
throws Exception
{
String id = getRepoid();
if ( id == null )
{
// TODO: Throw error?
return;
}
RepositoryConfiguration repoconfig = archivaConfiguration.getConfiguration().findRepositoryById( id );
if ( repoconfig != null )
{
this.repository = new AdminRepositoryConfiguration( repoconfig );
}
}
public String getMode()
{
return "edit";
}
}

View File

@ -1,93 +0,0 @@
package org.apache.maven.archiva.web.action.admin;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.InvalidConfigurationException;
import org.codehaus.plexus.rbac.profile.RoleProfileException;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.security.rbac.RbacManagerException;
import java.io.IOException;
/**
* SaveRepositoryAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="saveRepositoryAction"
*/
public class SaveRepositoryAction
extends AbstractRepositoryAction
{
public void prepare()
throws Exception
{
/* nothing to do here */
}
public String save()
{
String mode = getMode();
String repoId = getRepository().getId();
getLogger().info( "edit(" + mode + ":" + repoId + ")" );
if ( StringUtils.isBlank( repository.getId() ) )
{
addFieldError( "id", "A repository with a blank id cannot be saved." );
return SUCCESS;
}
if( StringUtils.equalsIgnoreCase( "edit", mode ) )
{
removeRepository( repoId );
}
try
{
addRepository( getRepository() );
saveConfiguration();
}
catch ( IOException e )
{
addActionError( "I/O Exception: " + e.getMessage() );
}
catch ( RoleProfileException e )
{
addActionError( "Role Profile Exception: " + e.getMessage() );
}
catch ( InvalidConfigurationException e )
{
addActionError( "Invalid Configuration Exception: " + e.getMessage() );
}
catch ( RbacManagerException e )
{
addActionError( "RBAC Manager Exception: " + e.getMessage() );
}
catch ( RegistryException e )
{
addActionError( "Configuration Registry Exception: " + e.getMessage() );
}
return SUCCESS;
}
}

View File

@ -0,0 +1,606 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.opensymphony.xwork.Preparable;
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.functors.IfClosure;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.InvalidConfigurationException;
import org.apache.maven.archiva.configuration.NetworkProxyConfiguration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.util.ProxyConnectorSelectionPredicate;
import org.apache.maven.archiva.configuration.util.RemoteRepositoryPredicate;
import org.apache.maven.archiva.configuration.util.RepositoryIdListClosure;
import org.apache.maven.archiva.policies.DownloadPolicy;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.security.rbac.Resource;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* ConfigureProxyConnectorAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureProxyConnectorAction"
*/
public class ConfigureProxyConnectorAction
extends PlexusActionSupport
implements SecureAction, Preparable, Initializable
{
private static final String DIRECT_CONNECTION = "(direct connection)";
/**
* @plexus.requirement
*/
private ArchivaConfiguration archivaConfiguration;
/**
* @plexus.requirement role="org.apache.maven.archiva.policies.PreDownloadPolicy"
*/
private Map preDownloadPolicyMap;
/**
* @plexus.requirement role="org.apache.maven.archiva.policies.PostDownloadPolicy"
*/
private Map postDownloadPolicyMap;
/**
* The model for this action.
*/
private ProxyConnectorConfiguration connector;
private Map policyMap;
private String source;
private String target;
private String mode;
private String propertyKey;
private String propertyValue;
private String pattern;
/**
* The list of possible proxy ids.
*/
private List proxyIdOptions = new ArrayList();
/**
* The list of local repository ids.
*/
private List localRepoIdList = new ArrayList();
/**
* The list of remote repository ids.
*/
private List remoteRepoIdList = new ArrayList();
/**
* The blacklist pattern to add.
*/
private String blackListPattern;
/**
* The whitelist pattern to add.
*/
private String whiteListPattern;
public String add()
{
getLogger().info( ".add()" );
this.mode = "add";
return INPUT;
}
public String confirm()
{
getLogger().info( ".confirm()" );
return INPUT;
}
public String delete()
{
getLogger().info( ".delete()" );
return INPUT;
}
public String addProperty()
{
getLogger().info( ".addProperty()" );
String key = getPropertyKey();
String value = getPropertyValue();
if ( StringUtils.isBlank( key ) )
{
addActionError( "Unable to add property with blank key." );
}
if ( StringUtils.isBlank( value ) )
{
addActionError( "Unable to add property with blank value." );
}
if ( !hasActionErrors() )
{
getConnector().getProperties().put( key, value );
setPropertyKey( null );
setPropertyValue( null );
}
return INPUT;
}
public String removeProperty()
{
getLogger().info( ".removeProperty()" );
String key = getPropertyKey();
if ( StringUtils.isBlank( key ) )
{
addActionError( "Unable to remove property with blank key." );
}
if ( !hasActionErrors() )
{
getConnector().getProperties().remove( key );
setPropertyKey( null );
setPropertyValue( null );
}
return INPUT;
}
public String addWhiteListPattern()
{
getLogger().info( ".addWhiteListPattern()" );
String pattern = getWhiteListPattern();
if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot add an blank white list pattern." );
}
if ( !hasActionErrors() )
{
getLogger().info(
"whitelist patterns: (" + getConnector().getWhiteListPatterns().size() + "): "
+ getConnector().getWhiteListPatterns() );
getConnector().getWhiteListPatterns().add( pattern );
setWhiteListPattern( null );
}
return INPUT;
}
public String removeWhiteListPattern()
{
String pattern = getPattern();
getLogger().info( ".removeWhiteListPattern(" + pattern + ")" );
if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot remove an blank white list pattern." );
}
if ( !hasActionErrors() )
{
getConnector().getWhiteListPatterns().remove( pattern );
setWhiteListPattern( null );
}
return INPUT;
}
public String addBlackListPattern()
{
getLogger().info( ".addBlackListPattern()" );
String pattern = getBlackListPattern();
if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot add an blank black list pattern." );
}
if ( !hasActionErrors() )
{
getConnector().getBlackListPatterns().add( pattern );
setBlackListPattern( null );
}
return INPUT;
}
public String removeBlackListPattern()
{
getLogger().info( ".removeBlackListPattern()" );
String pattern = getBlackListPattern();
if ( StringUtils.isBlank( pattern ) )
{
addActionError( "Cannot remove an blank black list pattern." );
}
if ( !hasActionErrors() )
{
getConnector().getBlackListPatterns().remove( pattern );
setBlackListPattern( null );
}
return INPUT;
}
public String edit()
{
getLogger().info( ".edit()" );
this.mode = "edit";
return INPUT;
}
public String getBlackListPattern()
{
return blackListPattern;
}
public ProxyConnectorConfiguration getConnector()
{
return connector;
}
public List getLocalRepoIdList()
{
return localRepoIdList;
}
public String getMode()
{
return this.mode;
}
public Map getPolicyMap()
{
return policyMap;
}
public String getPropertyKey()
{
return propertyKey;
}
public String getPropertyValue()
{
return propertyValue;
}
public List getProxyIdOptions()
{
return proxyIdOptions;
}
public List getRemoteRepoIdList()
{
return remoteRepoIdList;
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();
bundle.setRequiresAuthentication( true );
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
return bundle;
}
public String getSource()
{
return source;
}
public String getTarget()
{
return target;
}
public String getWhiteListPattern()
{
return whiteListPattern;
}
public void initialize()
throws InitializationException
{
policyMap = new HashMap();
policyMap.putAll( preDownloadPolicyMap );
policyMap.putAll( postDownloadPolicyMap );
}
public String input()
{
getLogger().info( "input()" );
return INPUT;
}
public void prepare()
throws Exception
{
String sourceId = getSource();
String targetId = getTarget();
getLogger().info( ".prepare() - sourceId [" + sourceId + "], targetId [" + targetId + "]" );
if ( StringUtils.isBlank( sourceId ) || StringUtils.isBlank( targetId ) )
{
if ( this.connector == null )
{
getLogger().info( "Creating new connector." );
this.connector = new ProxyConnectorConfiguration();
}
}
else
{
this.connector = findProxyConnector( sourceId, targetId );
}
getLogger().info( "Connector: " + connector );
Configuration config = archivaConfiguration.getConfiguration();
// Gather Network Proxy Ids.
this.proxyIdOptions = new ArrayList();
this.proxyIdOptions.add( DIRECT_CONNECTION );
Closure addProxyIds = new Closure()
{
public void execute( Object input )
{
if ( input instanceof NetworkProxyConfiguration )
{
NetworkProxyConfiguration netproxy = (NetworkProxyConfiguration) input;
proxyIdOptions.add( netproxy.getId() );
}
}
};
CollectionUtils.forAllDo( config.getNetworkProxies(), addProxyIds );
// Gather Local & Remote Repo Ids.
RepositoryIdListClosure remoteRepoIdList = new RepositoryIdListClosure( new ArrayList() );
RepositoryIdListClosure localRepoIdList = new RepositoryIdListClosure( new ArrayList() );
Closure repoIfClosure = IfClosure.getInstance( RemoteRepositoryPredicate.getInstance(), remoteRepoIdList,
localRepoIdList );
CollectionUtils.forAllDo( config.getRepositories(), repoIfClosure );
this.remoteRepoIdList = remoteRepoIdList.getList();
this.localRepoIdList = localRepoIdList.getList();
}
public String save()
{
String mode = getMode();
String sourceId = getConnector().getSourceRepoId();
String targetId = getConnector().getTargetRepoId();
getLogger().info( ".save(" + mode + ":" + sourceId + "->" + targetId + ")" );
if ( !isValid( getConnector() ) )
{
return INPUT;
}
if ( StringUtils.equalsIgnoreCase( "edit", mode ) )
{
removeConnector( sourceId, targetId );
}
try
{
if ( StringUtils.equals( DIRECT_CONNECTION, getConnector().getProxyId() ) )
{
getConnector().setProxyId( null );
}
addProxyConnector( getConnector() );
saveConfiguration();
}
catch ( IOException e )
{
addActionError( "I/O Exception: " + e.getMessage() );
}
catch ( InvalidConfigurationException e )
{
addActionError( "Invalid Configuration Exception: " + e.getMessage() );
}
catch ( RegistryException e )
{
addActionError( "Configuration Registry Exception: " + e.getMessage() );
}
return SUCCESS;
}
public void setBlackListPattern( String blackListPattern )
{
this.blackListPattern = blackListPattern;
}
public void setConnector( ProxyConnectorConfiguration connector )
{
this.connector = connector;
}
public void setLocalRepoIdList( List localRepoIdList )
{
this.localRepoIdList = localRepoIdList;
}
public void setMode( String mode )
{
this.mode = mode;
}
public void setPropertyKey( String propertyKey )
{
this.propertyKey = propertyKey;
}
public void setPropertyValue( String propertyValue )
{
this.propertyValue = propertyValue;
}
public void setRemoteRepoIdList( List remoteRepoIdList )
{
this.remoteRepoIdList = remoteRepoIdList;
}
public void setSource( String source )
{
this.source = source;
}
public void setTarget( String target )
{
this.target = target;
}
public void setWhiteListPattern( String whiteListPattern )
{
this.whiteListPattern = whiteListPattern;
}
private void addProxyConnector( ProxyConnectorConfiguration proxyConnector )
throws IOException
{
archivaConfiguration.getConfiguration().addProxyConnector( proxyConnector );
}
private ProxyConnectorConfiguration findProxyConnector( String sourceId, String targetId )
{
Configuration config = archivaConfiguration.getConfiguration();
ProxyConnectorSelectionPredicate selectedProxy = new ProxyConnectorSelectionPredicate( sourceId, targetId );
return (ProxyConnectorConfiguration) CollectionUtils.find( config.getProxyConnectors(), selectedProxy );
}
private boolean isValid( ProxyConnectorConfiguration proxyConnector )
{
if ( proxyConnector.getPolicies() == null )
{
addActionError( "Policies must be set." );
return false;
}
Iterator it = policyMap.entrySet().iterator();
while ( it.hasNext() )
{
Map.Entry entry = (Entry) it.next();
String policyId = (String) entry.getKey();
DownloadPolicy policy = (DownloadPolicy) entry.getValue();
List options = policy.getOptions();
if ( !proxyConnector.getPolicies().containsKey( policyId ) )
{
addActionError( "Policy [" + policyId + "] must be set (missing id)." );
continue;
}
String arr[] = (String[]) proxyConnector.getPolicies().get( policyId );
String value = arr[0];
proxyConnector.getPolicies().put( policyId, value );
if ( StringUtils.isBlank( value ) )
{
addActionError( "Policy [" + policyId + "] must be set (missing value)." );
continue;
}
if ( !options.contains( value ) )
{
addActionError( "Value of [" + value + "] is invalid for policy [" + policyId + "], valid values: "
+ options );
continue;
}
}
if ( hasActionErrors() || hasActionMessages() )
{
return false;
}
return true;
}
private void removeConnector( String sourceId, String targetId )
{
ProxyConnectorSelectionPredicate selectedProxy = new ProxyConnectorSelectionPredicate( sourceId, targetId );
NotPredicate notSelectedProxy = new NotPredicate( selectedProxy );
CollectionUtils.filter( archivaConfiguration.getConfiguration().getProxyConnectors(), notSelectedProxy );
}
private String saveConfiguration()
throws IOException, InvalidConfigurationException, RegistryException
{
archivaConfiguration.save( archivaConfiguration.getConfiguration() );
addActionMessage( "Successfully saved configuration" );
return SUCCESS;
}
public String getPattern()
{
return pattern;
}
public void setPattern( String pattern )
{
this.pattern = pattern;
}
}

View File

@ -0,0 +1,151 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.opensymphony.xwork.Preparable;
import org.apache.commons.collections.Closure;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.apache.maven.archiva.web.action.admin.repositories.AdminRepositoryConfiguration;
import org.codehaus.plexus.security.rbac.Resource;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* ProxyConnectorsAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="proxyConnectorsAction"
*/
public class ProxyConnectorsAction
extends PlexusActionSupport
implements SecureAction, Preparable
{
/**
* @plexus.requirement role-hint="adminrepoconfig"
*/
private Transformer repoConfigToAdmin;
/**
* @plexus.requirement
*/
private ArchivaConfiguration archivaConfiguration;
private Map /*<String,AdminRepositoryConfiguration>*/repoMap;
/**
* Map of Proxy Connectors.
*/
private Map /*<String,AdminProxyConnector>*/proxyConnectorMap;
public void prepare()
throws Exception
{
Configuration config = archivaConfiguration.getConfiguration();
repoMap = new HashMap();
Closure addToRepoMap = new Closure()
{
public void execute( Object input )
{
if ( input instanceof RepositoryConfiguration )
{
AdminRepositoryConfiguration arepo = (AdminRepositoryConfiguration) repoConfigToAdmin
.transform( input );
repoMap.put( arepo.getId(), arepo );
}
}
};
CollectionUtils.forAllDo( config.getRepositories(), addToRepoMap );
proxyConnectorMap = new HashMap();
Closure addToProxyConnectorMap = new Closure()
{
public void execute( Object input )
{
if ( input instanceof ProxyConnectorConfiguration )
{
ProxyConnectorConfiguration proxyConfig = (ProxyConnectorConfiguration) input;
String key = proxyConfig.getSourceRepoId();
List connectors = (List) proxyConnectorMap.get( key );
if ( connectors == null )
{
connectors = new ArrayList();
proxyConnectorMap.put( key, connectors );
}
connectors.add( proxyConfig );
}
}
};
CollectionUtils.forAllDo( config.getProxyConnectors(), addToProxyConnectorMap );
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();
bundle.setRequiresAuthentication( true );
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
return bundle;
}
public Map getRepoMap()
{
return repoMap;
}
public void setRepoMap( Map repoMap )
{
this.repoMap = repoMap;
}
public Map getProxyConnectorMap()
{
return proxyConnectorMap;
}
public void setProxyConnectorMap( Map proxyConnectorMap )
{
this.proxyConnectorMap = proxyConnectorMap;
}
}

View File

@ -0,0 +1,56 @@
package org.apache.maven.archiva.web.action.admin.connectors.proxy;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.commons.collections.Transformer;
/**
* Ensure that input strings are never arrays.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class SingleSelectTransformer
implements Transformer
{
private static Transformer INSTANCE = new SingleSelectTransformer();
public Object transform( Object input )
{
if ( input instanceof String )
{
if ( input.getClass().isArray() )
{
String arr[] = (String[]) input;
if ( arr.length > 0 )
{
return arr[0];
}
}
}
return null;
}
public static Transformer getInstance()
{
return INSTANCE;
}
}

View File

@ -0,0 +1,73 @@
package org.apache.maven.archiva.web.action.admin.database;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.opensymphony.webwork.interceptor.ServletRequestAware;
import com.opensymphony.xwork.ModelDriven;
import com.opensymphony.xwork.Preparable;
import com.opensymphony.xwork.Validateable;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import javax.servlet.http.HttpServletRequest;
/**
* DatabaseAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="databaseAction"
*/
public class DatabaseAction
extends PlexusActionSupport
implements ModelDriven, Preparable, Validateable, SecureAction, ServletRequestAware
{
public Object getModel()
{
// TODO Auto-generated method stub
return null;
}
public void prepare()
throws Exception
{
// TODO Auto-generated method stub
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
// TODO Auto-generated method stub
return null;
}
public void setServletRequest( HttpServletRequest request )
{
// TODO Auto-generated method stub
}
}

View File

@ -1,110 +0,0 @@
package org.apache.maven.archiva.web.action.admin.models;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* AdminModel
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class AdminModel
{
private String baseUrl;
private List managedRepositories = new ArrayList();
private List remoteRepositories = new ArrayList();
private Map repoMap = new HashMap();
public AdminModel()
{
/* do nothing */
}
public AdminModel( Configuration configuration )
{
repoMap.putAll( configuration.createRepositoryMap() );
Iterator it = configuration.getRepositories().iterator();
while ( it.hasNext() )
{
RepositoryConfiguration repoconfig = (RepositoryConfiguration) it.next();
if ( repoconfig.isManaged() )
{
managedRepositories.add( new AdminRepositoryConfiguration( repoconfig ) );
}
else if ( repoconfig.isRemote() )
{
remoteRepositories.add( repoconfig );
}
else
{
// Should never occur, but it is possible that the configuration could
// contain a repository configuration which is null.
}
}
}
public List getManagedRepositories()
{
return managedRepositories;
}
public void setManagedRepositories( List managedRepositories )
{
this.managedRepositories = managedRepositories;
}
public List getRemoteRepositories()
{
return remoteRepositories;
}
public void setRemoteRepositories( List remoteRepositories )
{
this.remoteRepositories = remoteRepositories;
}
public String getBaseUrl()
{
return baseUrl;
}
public void setBaseUrl( String baseUrl )
{
this.baseUrl = baseUrl;
}
public String toString()
{
return "[ActionModel]";
}
}

View File

@ -0,0 +1,73 @@
package org.apache.maven.archiva.web.action.admin.networkproxies;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.opensymphony.webwork.interceptor.ServletRequestAware;
import com.opensymphony.xwork.ModelDriven;
import com.opensymphony.xwork.Preparable;
import com.opensymphony.xwork.Validateable;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import javax.servlet.http.HttpServletRequest;
/**
* NetworkProxiesAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="networkProxiesAction"
*/
public class NetworkProxiesAction
extends PlexusActionSupport
implements ModelDriven, Preparable, Validateable, SecureAction, ServletRequestAware
{
public Object getModel()
{
// TODO Auto-generated method stub
return null;
}
public void prepare()
throws Exception
{
// TODO Auto-generated method stub
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
// TODO Auto-generated method stub
return null;
}
public void setServletRequest( HttpServletRequest request )
{
// TODO Auto-generated method stub
}
}

View File

@ -1,4 +1,4 @@
package org.apache.maven.archiva.web.action.admin.models;
package org.apache.maven.archiva.web.action.admin.repositories;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -36,8 +36,6 @@ import java.io.File;
public class AdminRepositoryConfiguration
extends RepositoryConfiguration
{
private String directory;
private RepositoryContentStatistics stats;
public AdminRepositoryConfiguration()
@ -70,23 +68,33 @@ public class AdminRepositoryConfiguration
public boolean isDirectoryExists()
{
if ( StringUtils.isBlank( directory ) )
if ( StringUtils.isBlank( getDirectory() ) )
{
return false;
}
File dir = new File( directory );
File dir = new File( getDirectory() );
return ( dir.exists() && dir.isDirectory() );
}
public String getDirectory()
{
return directory;
if ( this.isManaged() )
{
if ( StringUtils.isBlank( this.getUrl() ) )
{
return null;
}
RepositoryURL url = new RepositoryURL( this.getUrl() );
return url.getPath();
}
return null;
}
public void setDirectory( String directory )
{
this.directory = directory;
this.setUrl( PathUtil.toUrl( directory ) );
}

View File

@ -0,0 +1,370 @@
package org.apache.maven.archiva.web.action.admin.repositories;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.Preparable;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.common.utils.PathUtil;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.InvalidConfigurationException;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.codehaus.plexus.rbac.profile.RoleProfileException;
import org.codehaus.plexus.rbac.profile.RoleProfileManager;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.security.authorization.AuthorizationException;
import org.codehaus.plexus.security.authorization.AuthorizationResult;
import org.codehaus.plexus.security.rbac.RbacManagerException;
import org.codehaus.plexus.security.rbac.Resource;
import org.codehaus.plexus.security.system.SecuritySession;
import org.codehaus.plexus.security.system.SecuritySystem;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import java.io.File;
import java.io.IOException;
/**
* Configures the application repositories.
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="configureRepositoryAction"
*/
public class ConfigureRepositoryAction
extends PlexusActionSupport
implements Preparable, SecureAction
{
/**
* @plexus.requirement role-hint="archiva"
*/
private RoleProfileManager roleProfileManager;
/**
* @plexus.requirement
*/
private SecuritySystem securitySystem;
/**
* @plexus.requirement
*/
private ArchivaConfiguration archivaConfiguration;
private String repoid;
private String mode;
/**
* The model for this action.
*/
private AdminRepositoryConfiguration repository;
public String add()
{
getLogger().info( ".add()" );
this.mode = "add";
return INPUT;
}
public String confirm()
{
getLogger().info( ".confirm()" );
if ( operationAllowed( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY, getRepoid() ) )
{
addActionError( "You do not have the appropriate permissions to delete the " + getRepoid() + " repository." );
return ERROR;
}
return INPUT;
}
public String delete()
{
getLogger().info( ".delete()" );
if ( operationAllowed( ArchivaRoleConstants.OPERATION_DELETE_REPOSITORY, getRepoid() ) )
{
addActionError( "You do not have the appropriate permissions to delete the " + getRepoid() + " repository." );
return ERROR;
}
if ( StringUtils.equals( mode, "delete-entry" ) || StringUtils.equals( mode, "delete-contents" ) )
{
AdminRepositoryConfiguration existingRepository = getRepository();
if ( existingRepository == null )
{
addActionError( "A repository with that id does not exist" );
return ERROR;
}
// TODO: remove from index too!
try
{
removeRepository( getRepoid() );
removeRepositoryRoles( existingRepository );
saveConfiguration();
if ( StringUtils.equals( mode, "delete-contents" ) )
{
removeContents( existingRepository );
}
}
catch ( IOException e )
{
addActionError( "Unable to delete repository: " + e.getMessage() );
}
catch ( RoleProfileException e )
{
addActionError( "Unable to delete repository: " + e.getMessage() );
}
catch ( InvalidConfigurationException e )
{
addActionError( "Unable to delete repository: " + e.getMessage() );
}
catch ( RbacManagerException e )
{
addActionError( "Unable to delete repository: " + e.getMessage() );
}
catch ( RegistryException e )
{
addActionError( "Unable to delete repository: " + e.getMessage() );
}
}
return SUCCESS;
}
public String edit()
{
getLogger().info( ".edit()" );
this.mode = "edit";
if ( operationAllowed( ArchivaRoleConstants.OPERATION_EDIT_REPOSITORY, getRepoid() ) )
{
addActionError( "You do not have the appropriate permissions to edit the " + getRepoid() + " repository." );
return ERROR;
}
return INPUT;
}
public String getMode()
{
return this.mode;
}
public String getRepoid()
{
return repoid;
}
public AdminRepositoryConfiguration getRepository()
{
return repository;
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
SecureActionBundle bundle = new SecureActionBundle();
bundle.setRequiresAuthentication( true );
bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_MANAGE_CONFIGURATION, Resource.GLOBAL );
return bundle;
}
public void prepare()
throws Exception
{
String id = getRepoid();
if ( id == null )
{
this.repository = new AdminRepositoryConfiguration();
}
RepositoryConfiguration repoconfig = archivaConfiguration.getConfiguration().findRepositoryById( id );
if ( repoconfig != null )
{
this.repository = new AdminRepositoryConfiguration( repoconfig );
}
}
public String save()
{
String mode = getMode();
String repoId = getRepository().getId();
getLogger().info( ".save(" + mode + ":" + repoId + ")" );
if ( StringUtils.isBlank( repository.getId() ) )
{
addFieldError( "id", "A repository with a blank id cannot be saved." );
return SUCCESS;
}
if ( StringUtils.equalsIgnoreCase( "edit", mode ) )
{
removeRepository( repoId );
}
try
{
addRepository( getRepository() );
saveConfiguration();
}
catch ( IOException e )
{
addActionError( "I/O Exception: " + e.getMessage() );
}
catch ( RoleProfileException e )
{
addActionError( "Role Profile Exception: " + e.getMessage() );
}
catch ( InvalidConfigurationException e )
{
addActionError( "Invalid Configuration Exception: " + e.getMessage() );
}
catch ( RbacManagerException e )
{
addActionError( "RBAC Manager Exception: " + e.getMessage() );
}
catch ( RegistryException e )
{
addActionError( "Configuration Registry Exception: " + e.getMessage() );
}
return SUCCESS;
}
public void setMode( String mode )
{
this.mode = mode;
}
public void setRepoid( String repoid )
{
this.repoid = repoid;
}
public void setRepository( AdminRepositoryConfiguration repository )
{
this.repository = repository;
}
private void addRepository( AdminRepositoryConfiguration repository )
throws IOException, RoleProfileException
{
getLogger().info( ".addRepository(" + repository + ")" );
// Fix the URL entry (could possibly be a filesystem path)
String rawUrlEntry = repository.getUrl();
repository.setUrl( PathUtil.toUrl( rawUrlEntry ) );
if ( repository.isManaged() )
{
// Normalize the path
File file = new File( repository.getDirectory() );
repository.setDirectory( file.getCanonicalPath() );
if ( !file.exists() )
{
file.mkdirs();
// TODO: error handling when this fails, or is not a directory!
}
}
archivaConfiguration.getConfiguration().addRepository( repository );
// TODO: double check these are configured on start up
roleProfileManager.getDynamicRole( "archiva-repository-manager", repository.getId() );
roleProfileManager.getDynamicRole( "archiva-repository-observer", repository.getId() );
}
private boolean operationAllowed( String permission, String repoid )
{
ActionContext context = ActionContext.getContext();
SecuritySession securitySession = (SecuritySession) context.get( SecuritySession.ROLE );
AuthorizationResult authzResult;
try
{
authzResult = securitySystem.authorize( securitySession, permission, repoid );
return authzResult.isAuthorized();
}
catch ( AuthorizationException e )
{
getLogger().info(
"Unable to authorize permission: " + permission + " against repo: " + repoid
+ " due to: " + e.getMessage() );
return false;
}
}
private void removeContents( AdminRepositoryConfiguration existingRepository )
throws IOException
{
if ( existingRepository.isManaged() )
{
getLogger().info( "Removing " + existingRepository.getDirectory() );
FileUtils.deleteDirectory( new File( existingRepository.getDirectory() ) );
}
}
private void removeRepository( String repoId )
{
getLogger().info( ".removeRepository()" );
RepositoryConfiguration toremove = archivaConfiguration.getConfiguration().findRepositoryById( repoId );
if ( toremove != null )
{
archivaConfiguration.getConfiguration().removeRepository( toremove );
}
}
private void removeRepositoryRoles( RepositoryConfiguration existingRepository )
throws RoleProfileException
{
roleProfileManager.deleteDynamicRole( "archiva-repository-manager", existingRepository.getId() );
roleProfileManager.deleteDynamicRole( "archiva-repository-observer", existingRepository.getId() );
getLogger().info( "removed user roles associated with repository " + existingRepository.getId() );
}
private String saveConfiguration()
throws IOException, InvalidConfigurationException, RbacManagerException, RoleProfileException,
RegistryException
{
getLogger().info( ".saveConfiguration()" );
archivaConfiguration.save( archivaConfiguration.getConfiguration() );
addActionMessage( "Successfully saved configuration" );
return SUCCESS;
}
}

View File

@ -1,4 +1,4 @@
package org.apache.maven.archiva.web.action.admin;
package org.apache.maven.archiva.web.action.admin.repositories;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -20,17 +20,17 @@ package org.apache.maven.archiva.web.action.admin;
*/
import com.opensymphony.webwork.interceptor.ServletRequestAware;
import com.opensymphony.xwork.ModelDriven;
import com.opensymphony.xwork.Preparable;
import com.opensymphony.xwork.Validateable;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.list.TransformedList;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.database.ArchivaDAO;
import org.apache.maven.archiva.database.constraints.MostRecentRepositoryScanStatistics;
import org.apache.maven.archiva.model.RepositoryContentStatistics;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.util.LocalRepositoryPredicate;
import org.apache.maven.archiva.configuration.util.RemoteRepositoryPredicate;
import org.apache.maven.archiva.configuration.util.RepositoryConfigurationComparator;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
import org.apache.maven.archiva.web.action.admin.models.AdminModel;
import org.apache.maven.archiva.web.action.admin.models.AdminRepositoryConfiguration;
import org.apache.maven.archiva.web.util.ContextUtils;
import org.codehaus.plexus.security.rbac.Resource;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
@ -38,7 +38,8 @@ import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@ -53,44 +54,27 @@ import javax.servlet.http.HttpServletRequest;
*/
public class RepositoriesAction
extends PlexusActionSupport
implements ModelDriven, Preparable, Validateable, SecureAction, ServletRequestAware
implements SecureAction, ServletRequestAware, Preparable
{
/**
* @plexus.requirement role-hint="jdo"
* @plexus.requirement role-hint="adminrepoconfig"
*/
private ArchivaDAO dao;
private Transformer repoConfigToAdmin;
/**
* @plexus.requirement
*/
private ArchivaConfiguration archivaConfiguration;
private AdminModel model;
private List managedRepositories;
private List remoteRepositories;
private String baseUrl;
public Object getModel()
public void setServletRequest( HttpServletRequest request )
{
return getAdminModel();
}
public void prepare()
throws Exception
{
model = null;
getModel();
}
public void validate()
{
super.validate();
}
public String execute()
throws Exception
{
getLogger().info( ".execute()" );
return super.execute();
this.baseUrl = ContextUtils.getBaseURL( request, "repository" );
}
public SecureActionBundle getSecureActionBundle()
@ -104,46 +88,33 @@ public class RepositoriesAction
return bundle;
}
public void setServletRequest( HttpServletRequest request )
public void prepare()
throws Exception
{
this.baseUrl = ContextUtils.getBaseURL( request, "repository" );
Configuration config = archivaConfiguration.getConfiguration();
remoteRepositories = TransformedList.decorate( new ArrayList(), repoConfigToAdmin );
managedRepositories = TransformedList.decorate( new ArrayList(), repoConfigToAdmin );
remoteRepositories.addAll( CollectionUtils.select( config.getRepositories(), RemoteRepositoryPredicate.getInstance() ) );
managedRepositories.addAll( CollectionUtils.select( config.getRepositories(), LocalRepositoryPredicate.getInstance() ) );
Collections.sort( managedRepositories, new RepositoryConfigurationComparator() );
Collections.sort( remoteRepositories, new RepositoryConfigurationComparator() );
}
public AdminModel getAdminModel()
public List getManagedRepositories()
{
if ( model == null )
{
model = new AdminModel( archivaConfiguration.getConfiguration() );
model.setBaseUrl( baseUrl );
updateLastIndexed( model.getManagedRepositories() );
return managedRepositories;
}
return model;
public List getRemoteRepositories()
{
return remoteRepositories;
}
private void updateLastIndexed( List managedRepositories )
{
Iterator it = managedRepositories.iterator();
while ( it.hasNext() )
{
AdminRepositoryConfiguration config = (AdminRepositoryConfiguration) it.next();
List results = dao.query( new MostRecentRepositoryScanStatistics( config.getId() ) );
if ( !results.isEmpty() )
{
RepositoryContentStatistics stats = (RepositoryContentStatistics) results.get( 0 );
config.setStats( stats );
}
}
}
public String getBaseUrlB()
public String getBaseUrl()
{
return baseUrl;
}
public void setBaseUrlB( String baseUrl )
{
this.baseUrl = baseUrl;
}
}

View File

@ -0,0 +1,75 @@
package org.apache.maven.archiva.web.action.admin.repositories;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import org.apache.commons.collections.Transformer;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import org.apache.maven.archiva.database.ArchivaDAO;
import org.apache.maven.archiva.database.constraints.MostRecentRepositoryScanStatistics;
import org.apache.maven.archiva.model.RepositoryContentStatistics;
import java.util.List;
/**
* RepositoryConfigurationAdminTransformer
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="org.apache.commons.collections.Transformer"
* role-hint="adminrepoconfig"
*/
public class RepositoryConfigurationAdminTransformer
implements Transformer
{
/**
* @plexus.requirement role-hint="jdo"
*/
private ArchivaDAO dao;
public Object transform( Object input )
{
if ( input instanceof RepositoryConfiguration )
{
RepositoryConfiguration repoconfig = (RepositoryConfiguration) input;
AdminRepositoryConfiguration arepo = new AdminRepositoryConfiguration( repoconfig );
if ( arepo.isManaged() )
{
arepo.setStats( getLatestStats( arepo.getId() ) );
}
return arepo;
}
return null;
}
private RepositoryContentStatistics getLatestStats( String repoId )
{
List results = dao.query( new MostRecentRepositoryScanStatistics( repoId ) );
if ( results.isEmpty() )
{
return null;
}
return (RepositoryContentStatistics) results.get( 0 );
}
}

View File

@ -0,0 +1,73 @@
package org.apache.maven.archiva.web.action.admin.scanning;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.opensymphony.webwork.interceptor.ServletRequestAware;
import com.opensymphony.xwork.ModelDriven;
import com.opensymphony.xwork.Preparable;
import com.opensymphony.xwork.Validateable;
import org.codehaus.plexus.security.ui.web.interceptor.SecureAction;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionBundle;
import org.codehaus.plexus.security.ui.web.interceptor.SecureActionException;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import javax.servlet.http.HttpServletRequest;
/**
* RepositoryScanningAction
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="repositoryScanningAction"
*/
public class RepositoryScanningAction
extends PlexusActionSupport
implements ModelDriven, Preparable, Validateable, SecureAction, ServletRequestAware
{
public Object getModel()
{
// TODO Auto-generated method stub
return null;
}
public void prepare()
throws Exception
{
// TODO Auto-generated method stub
}
public SecureActionBundle getSecureActionBundle()
throws SecureActionException
{
// TODO Auto-generated method stub
return null;
}
public void setServletRequest( HttpServletRequest request )
{
// TODO Auto-generated method stub
}
}

View File

@ -36,11 +36,15 @@
<interceptor name="pssSecureActions" class="pssSecureActionInterceptor"/>
<interceptor name="pssAutoLogin" class="pssAutoLoginInterceptor"/>
<interceptor name="pssPolicyEnforcement" class="pssPolicyEnforcementInterceptor"/>
<interceptor name="paramFilter" class="com.opensymphony.xwork.interceptor.ParameterFilterInterceptor" />
<interceptor-stack name="configuredArchivaStack">
<interceptor-ref name="pssForceAdminUser"/>
<interceptor-ref name="pssAutoLogin"/>
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="paramFilter">
<param name="blocked">externalResult</param>
</interceptor-ref>
<interceptor-ref name="pssSecureActions"/>
<interceptor-ref name="pssPolicyEnforcement"/>
<interceptor-ref name="configuration"/>
@ -225,8 +229,11 @@
<result name="input">/WEB-INF/jsp/admin/repositories.jsp</result>
</action>
<!-- .\ REPOSITORIES \.____________________________________________ -->
<action name="repositories" class="repositoriesAction" method="input">
<result name="input">/WEB-INF/jsp/admin/repositories.jsp</result>
<result name="confirm" type="redirect-action">deleteRepository</result>
</action>
<action name="indexRepository" class="indexRepositoryAction" method="run">
@ -235,26 +242,85 @@
<action name="addRepository" class="configureRepositoryAction" method="add">
<result name="input">/WEB-INF/jsp/admin/addRepository.jsp</result>
<result type="redirect-action">repositories</result>
<!-- <interceptor-ref name="unconfiguredArchivaStack"/> -->
<result name="success" type="redirect-action">repositories</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="editRepository" class="editRepositoryAction" method="edit">
<action name="editRepository" class="configureRepositoryAction" method="edit">
<result name="input">/WEB-INF/jsp/admin/editRepository.jsp</result>
<result name="error" type="redirect-action">repositories</result>
<result name="success" type="redirect-action">repositories</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="saveRepository" class="saveRepositoryAction" method="save">
<action name="saveRepository" class="configureRepositoryAction" method="save">
<result name="success" type="redirect-action">repositories</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="deleteRepository" class="deleteRepositoryAction">
<action name="deleteRepository" class="configureRepositoryAction" method="confirm">
<result name="input">/WEB-INF/jsp/admin/deleteRepository.jsp</result>
<result type="redirect-action">repositories</result>
<result name="success" type="redirect-action">repositories</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<!-- .\ PROXY CONNECTORS \.________________________________________ -->
<action name="proxyConnectors" class="proxyConnectorsAction" method="input">
<result name="input">/WEB-INF/jsp/admin/proxyConnectors.jsp</result>
</action>
<action name="addProxyConnector" class="configureProxyConnectorAction" method="add">
<result name="input">/WEB-INF/jsp/admin/addProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="configureProxyConnector" class="configureProxyConnectorAction" method="input">
<result name="input">/WEB-INF/jsp/admin/editProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="editProxyConnector" class="configureProxyConnectorAction" method="edit">
<result name="input">/WEB-INF/jsp/admin/editProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="saveProxyConnector" class="configureProxyConnectorAction" method="save">
<result name="input">/WEB-INF/jsp/admin/editProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="deleteProxyConnector" class="configureProxyConnectorAction" method="confirm">
<result name="input">/WEB-INF/jsp/admin/deleteProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<!-- .\ NETWORK PROXIES \._________________________________________ -->
<action name="networkProxies" class="networkProxiesAction" method="input">
<result name="input">/WEB-INF/jsp/admin/networkProxies.jsp</result>
</action>
<!-- .\ REPOSITORY SCANNING \._____________________________________ -->
<action name="repositoryScanning" class="repositoryScanningAction" method="input">
<result name="input">/WEB-INF/jsp/admin/repositoryScanning.jsp</result>
</action>
<!-- .\ DATABASE \.________________________________________________ -->
<action name="database" class="databaseAction" method="input">
<result name="input">/WEB-INF/jsp/admin/database.jsp</result>
</action>
<!-- .\ CONFIGURATION \.___________________________________________ -->
<action name="configure" class="configureAction" method="input">
<result name="input">/WEB-INF/jsp/admin/configure.jsp</result>
<interceptor-ref name="unconfiguredArchivaStack"/>

View File

@ -21,27 +21,28 @@
<html>
<head>
<title>Configuration</title>
<title>Admin: Add Repository</title>
<ww:head/>
</head>
<body>
<h1>Configuration</h1>
<h1>Admin: Add Repository</h1>
<div id="contentArea">
<h2>Add Managed Repository</h2>
<h2>Add Repository</h2>
<ww:actionmessage/>
<ww:form method="post" action="addRepository" namespace="/admin" validate="true">
<ww:textfield name="model.id" label="Identifier" size="10" required="true"/>
<%@ include file="/WEB-INF/jsp/admin/include/managedRepositoryForm.jspf" %>
<ww:form method="post" action="saveRepository" namespace="/admin" validate="true">
<ww:hidden name="mode" value="add"/>
<ww:textfield name="repository.id" label="Identifier" size="10" required="true"/>
<%@ include file="/WEB-INF/jsp/admin/include/repositoryForm.jspf" %>
<ww:submit value="Add Repository"/>
</ww:form>
<script type="text/javascript">
document.getElementById("addRepository_id").focus();
document.getElementById("saveRepository_id").focus();
</script>
</div>

View File

@ -37,11 +37,11 @@
<strong><span class="statusFailed">WARNING:</span> This operation can not be undone.</strong>
</blockquote>
<ww:form method="post" action="deleteRepository" namespace="/admin" validate="true">
<ww:hidden name="repoId"/>
<ww:form method="post" action="deleteRepository!delete" namespace="/admin" validate="true">
<ww:hidden name="repoid"/>
<ww:radio list="#@java.util.LinkedHashMap@{'delete-contents' : 'Remove the repository and delete its contents from disk',
'delete-entry' : 'Remove the repository from the management list, but leave the contents unmodified',
'unmodified' : 'Leave the repository unmodified'}" name="operation" theme="archiva"/>
'unmodified' : 'Leave the repository unmodified'}" name="mode" theme="archiva"/>
<ww:submit value="Go"/>
</ww:form>
</div>

View File

@ -0,0 +1,52 @@
<%--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
--%>
<%@ taglib prefix="ww" uri="/webwork" %>
<html>
<head>
<title>Admin : Edit Proxy Connector</title>
<ww:head/>
</head>
<body>
<h1>Admin : Edit Proxy Connector</h1>
<div id="contentArea">
<h2>Edit Proxy Connector</h2>
<ww:actionerror/>
<ww:actionmessage/>
<ww:form method="post" action="saveProxyConnector" namespace="/admin" validate="false">
<ww:hidden name="mode"/>
<%@ include file="/WEB-INF/jsp/admin/include/proxyConnectorForm.jspf" %>
<ww:submit value="Save Proxy Connector"/>
</ww:form>
<script type="text/javascript">
document.getElementById("saveProxyConnector_proxyId").focus();
</script>
</div>
</body>
</html>

View File

@ -21,28 +21,28 @@
<html>
<head>
<title>Configuration</title>
<title>Admin: Edit Repository</title>
<ww:head/>
</head>
<body>
<h1>Configuration</h1>
<h1>Admin: Edit Repository</h1>
<div id="contentArea">
<h2>Edit Managed Repository</h2>
<h2>Edit Repository</h2>
<ww:actionmessage/>
<ww:form method="post" action="saveRepository" namespace="/admin" validate="false">
<ww:hidden name="mode"/>
<ww:hidden name="id"/>
<%@ include file="/WEB-INF/jsp/admin/include/managedRepositoryForm.jspf" %>
<ww:hidden name="mode" value="edit"/>
<ww:hidden name="repository.id"/>
<%@ include file="/WEB-INF/jsp/admin/include/repositoryForm.jspf" %>
<ww:submit value="Update Repository"/>
</ww:form>
<script type="text/javascript">
document.getElementById("editRepository_name").focus();
document.getElementById("saveRepository_name").focus();
</script>
</div>

View File

@ -1,42 +0,0 @@
<%--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
--%>
<%@ taglib prefix="ww" uri="/webwork" %>
<ww:textfield name="name" label="Name" size="50" required="true"/>
<ww:textfield name="url" label="URL" size="50" required="true"/>
<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
name="layout" label="Type"/>
<ww:select name="snapshotsPolicy" label="Snapshots" list="#@java.util.LinkedHashMap@{
'disabled' : 'Disabled',
'daily' : 'Enabled, updated daily',
'hourly' : 'Enabled, updated hourly',
'never' : 'Enabled, never updated',
'interval' : 'Enabled, updated on given interval'}"/>
<ww:textfield label="Snapshot update interval" name="snapshotsInterval" size="4"/>
<ww:select name="releasesPolicy" label="Releases" list="#@java.util.LinkedHashMap@{
'disabled' : 'Disabled',
'daily' : 'Enabled, updated daily',
'hourly' : 'Enabled, updated hourly',
'never' : 'Enabled, never updated',
'interval' : 'Enabled, updated on given interval'}"/>
<ww:textfield label="Release update interval" name="releasesInterval" size="4"/>
<ww:select list="configuration.repositoriesMap" name="managedRepository" label="Proxied through"/>
<ww:checkbox name="useNetworkProxy" fieldValue="true" label="Use HTTP Proxy"/>
<ww:checkbox name="cacheFailures" fieldValue="true" label="Cache Failures"/>
<ww:checkbox name="hardFail" fieldValue="true" label="Fail Whole Group"/>

View File

@ -0,0 +1,196 @@
<%--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
--%>
<%@ taglib prefix="ww" uri="/webwork" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:url var="iconDeleteUrl" value="/images/icons/delete.gif" />
<input type="hidden" name="pattern"/>
<ww:select name="connector.proxyId" list="proxyIdOptions" label="Network Proxy" required="true"/>
<ww:select name="connector.sourceRepoId" list="localRepoIdList" label="Local Repository" required="true"/>
<ww:select name="connector.targetRepoId" list="remoteRepoIdList" label="Remote Repository" required="true" />
<script type="text/javascript">
<!--
function setAndSubmit(id, value, action)
{
var f = document.forms.saveProxyConnector;
f.action = action;
f[id].value = value;
f.submit();
}
//-->
</script>
<tr><td valign="top"><label>Policies:</label></td>
<td>
<table>
<c:forEach items="${policyMap}" var="policy" varStatus="i">
<tr>
<td>
<ww:label for="policy_${policy.key}" required="true"
theme="simple">${policy.key}:</ww:label>
</td>
<td>
<ww:select name="connector.policies['${policy.key}']"
list="policyMap['${policy.key}'].options"
value="connector.policies['${policy.key}']"
id="policy_${policy.key}"
theme="simple"
cssStyle="width: 10em" />
</td>
</tr>
</c:forEach>
</table>
</td></tr>
<tr class="seperator">
<td valign="top">
<label for="propertiesEntry">Properties:</label>
</td>
<td>
<ww:textfield name="propertyKey" size="15" id="propertiesEntry" theme="simple" /> :
<ww:textfield name="propertyValue" size="15" id="propertiesValue" theme="simple" />
<ww:submit name="action:editProxyConnector!addProperty" value="Add Property" theme="simple" />
</td>
</tr>
<tr>
<td>
</td>
<td>
<c:choose>
<c:when test="${empty(connector.properties)}">
<i>No properties have been set.</i>
</c:when>
<c:otherwise>
<ww:url id="removePropertyUrl"
action="editProxyConnector"
method="removeProperty" />
<table>
<c:forEach items="${connector.properties}" var="property" varStatus="i">
<tr>
<td>
<ww:label for="property_${property.key}"
theme="simple">${property.key}</ww:label>
</td>
<td>
<ww:textfield name="connector.properties['${property.key}']"
size="15"
id="property_${property.key}"
theme="simple" />
</td>
<td>
<ww:a href="#" title="Remove [${property.key}] Property"
onclick="setAndSubmit('propertyKey', '${property.key}', '%{removePropertyUrl}')"
theme="simple">
<img src="${iconDeleteUrl}" /></ww:a>
</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>
<tr class="seperator">
<td valign="top">
<label for="blackListEntry">Black List:</label>
</td>
<td>
<ww:textfield name="blackListPattern" size="30" id="blackListEntry" theme="simple" />
<ww:submit name="action:editProxyConnector!addBlackListPattern" value="Add Pattern" theme="simple" />
</td>
</tr>
<tr>
<td>
</td>
<td>
<ww:url id="removeBlackListPatternUrl"
action="editProxyConnector"
method="removeBlackListPattern" />
<c:choose>
<c:when test="${empty(connector.blackListPatterns)}">
<i>No black list patterns have been set.</i>
</c:when>
<c:otherwise>
<table>
<c:forEach items="${connector.blackListPatterns}" var="pattern" varStatus="i">
<tr>
<td>
<ww:hidden name="connector.blackListPatterns" value="${pattern}"/>
<code>"${pattern}"</code>
</td>
<td>
<ww:a href="#" title="Remove [${pattern}] Pattern"
onclick="setAndSubmit('pattern', '${pattern}', '%{removeBlackListPatternUrl}')"
theme="simple">
<img src="${iconDeleteUrl}" /></ww:a>
</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>
<tr class="seperator">
<td valign="top">
<label for="whiteListEntry">White List:</label>
</td>
<td>
<ww:textfield name="whiteListPattern" size="30" id="whiteListEntry" theme="simple" />
<ww:submit name="action:editProxyConnector!addWhiteListPattern" value="Add Pattern" theme="simple" />
</td>
</tr>
<tr>
<td>
</td>
<td>
<ww:url id="removeWhiteListPatternUrl"
action="editProxyConnector"
method="removeWhiteListPattern" />
<c:choose>
<c:when test="${empty(connector.whiteListPatterns)}">
<i>No white list patterns have been set.</i>
</c:when>
<c:otherwise>
<table>
<c:forEach items="${connector.whiteListPatterns}" var="pattern" varStatus="i">
<tr>
<td>
<ww:hidden name="connector.whiteListPatterns" value="${pattern}"/>
<code>"${pattern}"</code>
</td>
<td>
<ww:a href="#" title="Remove [${pattern}] Pattern"
onclick="setAndSubmit('pattern', '${pattern}', '%{removeWhiteListPatternUrl}')"
theme="simple">
<img src="${iconDeleteUrl}" /></ww:a>
</td>
</tr>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</td>
</tr>

View File

@ -19,11 +19,11 @@
<%@ taglib prefix="ww" uri="/webwork" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<ww:textfield name="name" label="Name" size="50" required="true"/>
<ww:textfield name="directory" label="Directory" size="100" required="true"/>
<ww:textfield name="repository.name" label="Name" size="50" required="true"/>
<ww:textfield name="repository.url" label="Directory or URL" size="100" required="true"/>
<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
name="layout" label="Type"/>
<ww:textfield name="refreshCronExpression" label="Cron" size="100" required="true" />
<ww:checkbox name="releases" fieldValue="true" label="Releases Included"/>
<ww:checkbox name="snapshots" fieldValue="false" label="Snapshots Included"/>
<ww:checkbox name="indexed" fieldValue="true" label="Indexed"/>
name="repository.layout" label="Type"/>
<ww:textfield name="repository.refreshCronExpression" label="Cron" size="100" required="true" />
<ww:checkbox name="repository.releases" fieldValue="true" label="Releases Included"/>
<ww:checkbox name="repository.snapshots" fieldValue="false" label="Snapshots Included"/>
<ww:checkbox name="repository.indexed" fieldValue="true" label="Indexed"/>

View File

@ -1,46 +0,0 @@
<%--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
--%>
<ww:hidden name="method"/>
<ww:textfield name="name" label="Name" size="50"/>
<ww:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
name="layout" label="Type"/>
<ww:select list="configuration.repositoriesMap" name="managedRepository" label="Synced to"/>
<ww:textfield name="cronExpression" label="Schedule"/>
<ww:set name="method" value="method"/>
<c:choose>
<c:when test="${method == 'cvs'}">
<ww:textfield name="properties['cvsRoot']" label="CVS Root" size="100"/>
</c:when>
<c:when test="${method == 'svn'}">
<ww:textfield name="properties['svnUrl']" label="Subversion URL" size="100"/>
<ww:textfield name="properties['username']" label="Subversion Username" size="30"/>
</c:when>
<c:when test="${method == 'rsync'}">
<ww:textfield name="properties['rsyncHost']" label="Rsync Host"/>
<ww:textfield name="properties['rsyncDirectory']" label="Rsync Directory" size="100"/>
<ww:select name="properties['rsyncMethod']" label="Rsync Method"
list="#@java.util.LinkedHashMap@{'rsync' : 'Anonymous', 'ssh' : 'SSH'}"/>
<ww:textfield name="properties['username']" label="Rsync Username" size="30"/>
</c:when>
<c:when test="${method == 'file'}">
<ww:textfield name="properties['directory']" label="Directory" size="100"/>
</c:when>
</c:choose>

View File

@ -0,0 +1,170 @@
<%--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
--%>
<%@ taglib prefix="ww" uri="/webwork" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="pss" uri="/plexusSecuritySystem" %>
<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
<html>
<head>
<title>Administration - Proxy Connectors</title>
<ww:head/>
</head>
<body>
<h1>Administration - Proxy Connectors</h1>
<div id="contentArea">
<ww:actionerror />
<ww:actionmessage />
<div style="float:right">
<pss:ifAnyAuthorized permissions="archiva-manage-configuration">
<ww:url id="addProxyConnectorUrl" action="addProxyConnector" />
<ww:a href="%{addProxyConnectorUrl}" cssClass="create">
<img src="<c:url value="/images/icons/create.png" />" />
Add Proxy Connector
</ww:a>
</pss:ifAnyAuthorized>
</div>
<h2>Repository Proxy Connectors</h2>
<c:choose>
<c:when test="${empty(proxyConnectorMap)}">
<strong>No Repository Proxy Connectors Defined.</strong>
</c:when>
<c:otherwise>
<table width="100%">
<c:forEach items="${proxyConnectorMap}" var="repository" varStatus="i">
<c:forEach items="${repository.value}" var="connector" varStatus="pc">
<tr class="proxyConnector">
<c:if test="${pc.first}">
<td class="managedRepo" rowspan="${fn:length(repository.value)}">
<div>
<img src="<c:url value="/images/archiva-splat-32.gif"/>" />
<p class="id">${repository.key}</p>
<p class="name">${repoMap[repository.key].name}</p>
</div>
</td>
</c:if>
<td class="connector">
<div class="wrap">
<div class="controls">
<pss:ifAnyAuthorized permissions="archiva-manage-configuration">
<ww:url id="editProxyConnectorUrl" action="editProxyConnector">
<ww:param name="target" value="%{'${connector.targetRepoId}'}" />
<ww:param name="source" value="%{'${connector.sourceRepoId}'}" />
</ww:url>
<ww:url id="deleteProxyConnectorUrl" action="deleteProxyConnector" method="confirm">
<ww:param name="source" value="%{'${connector.sourceRepoId}'}" />
<ww:param name="target" value="%{'${connector.targetRepoId}'}" />
</ww:url>
<ww:a href="%{editProxyConnectorUrl}" cssClass="edit" title="Edit Proxy Connector">
<img src="<c:url value="/images/icons/edit.png" />" />
</ww:a>
<ww:a href="%{deleteProxyConnectorUrl}" cssClass="delete" title="Delete Proxy Connector">
<img src="<c:url value="/images/icons/delete.gif" />" />
</ww:a>
</pss:ifAnyAuthorized>
</div>
<h4>Proxy Connector</h4>
<table>
<tr>
<th nowrap="nowrap">Network Proxy:</th>
<td>
<c:choose>
<c:when test="${empty(connector.proxyId)}">
<i>(Direct Connection)</i>
</c:when>
<c:otherwise>
${connector.proxyId}
</c:otherwise>
</c:choose>
</td>
</tr>
<tr>
<th>Policies:</th>
<td nowrap="nowrap">
<c:forEach items="${connector.policies}" var="policies">
<p><em>${policies.key}</em>: ${policies.value}</p>
</c:forEach>
</td>
</tr>
<c:if test="${not(empty(connector.whiteListPatterns))}">
<tr>
<th nowrap="nowrap">White List:</th>
<td nowrap="nowrap">
<c:forEach items="${connector.whiteListPatterns}" var="pattern">
<p><code>"${pattern}"</code></p>
</c:forEach>
</td>
</tr>
</c:if>
<c:if test="${not(empty(connector.blackListPatterns))}">
<tr>
<th nowrap="nowrap">Black List:</th>
<td>
<c:forEach items="${connector.blackListPatterns}" var="pattern">
<p><code>"${pattern}"</code></p>
</c:forEach>
</td>
</tr>
</c:if>
<c:if test="${not(empty(connector.properties))}">
<tr>
<th>Properties:</th>
<td>
<c:forEach items="${connector.properties}" var="prop">
<p><em>${prop.key}</em>: ${prop.value}</p>
</c:forEach>
</td>
</tr>
</c:if>
</table>
</div>
</td>
<td class="remoteRepo">
<div>
<img src="<c:url value="/images/archiva-world.png"/>" />
<p class="id">${connector.targetRepoId}</p>
<p class="name">${repoMap[connector.targetRepoId].name}</p>
<p class="url">${repoMap[connector.targetRepoId].url}</p>
</div>
</td>
</tr>
</c:forEach>
</c:forEach>
</table>
</c:otherwise>
</c:choose>
</div>
</body>
</html>

View File

@ -42,23 +42,25 @@
<%-- TODO replace with icons --%>
<pss:ifAuthorized permission="archiva-manage-configuration">
<ww:url id="addRepositoryUrl" action="addRepository"/>
<ww:a href="%{addRepositoryUrl}">Add Repository</ww:a>
<ww:a href="%{addRepositoryUrl}">
<img src="<c:url value="/images/icons/create.png" />" />
Add Repository</ww:a>
</pss:ifAuthorized>
</div>
<h2>Managed Repositories</h2>
<h2>Local Repositories</h2>
</div>
<c:choose>
<c:when test="${empty(model.managedRepositories)}">
<%-- No Managed Repositories. --%>
<strong>There are no managed repositories configured yet.</strong>
<c:when test="${empty(managedRepositories)}">
<%-- No Local Repositories. --%>
<strong>There are no local repositories configured yet.</strong>
</c:when>
<c:otherwise>
<%-- Display the repositories. --%>
<c:forEach items="${model.managedRepositories}" var="repository" varStatus="i">
<c:forEach items="${managedRepositories}" var="repository" varStatus="i">
<div>
<div class="repository">
<div style="float: right">
<%-- TODO: make some icons --%>
@ -69,12 +71,20 @@
<ww:url id="deleteRepositoryUrl" action="deleteRepository" method="confirm">
<ww:param name="repoid" value="%{'${repository.id}'}" />
</ww:url>
<ww:a href="%{editRepositoryUrl}">Edit Repository</ww:a>
<ww:a href="%{deleteRepositoryUrl}">Delete Repository</ww:a>
<ww:a href="%{editRepositoryUrl}">
<img src="<c:url value="/images/icons/edit.png" />" />
Edit Repository</ww:a>
<ww:a href="%{deleteRepositoryUrl}">
<img src="<c:url value="/images/icons/delete.gif" />" />
Delete Repository</ww:a>
</pss:ifAnyAuthorized>
</div>
<h3>${repository.name}</h3>
<div style="float: left">
<img src="<c:url value="/images/archiva-splat-32.gif"/>" />
</div>
<h3 class="repository">${repository.name}</h3>
<table class="infoTable">
<tr>
@ -93,7 +103,7 @@
</tr>
<tr>
<th>WebDAV URL</th>
<td><a href="${model.baseUrl}/${repository.id}/">${model.baseUrl}/${repository.id}/</a></td>
<td><a href="${baseUrl}/${repository.id}/">${baseUrl}/${repository.id}/</a></td>
</tr>
<tr>
<th>Type</th>
@ -179,6 +189,83 @@
</c:otherwise>
</c:choose>
<h2>Remote Repositories</h2>
<c:choose>
<c:when test="${empty(remoteRepositories)}">
<%-- No Remote Repositories. --%>
<strong>There are no remote repositories configured yet.</strong>
</c:when>
<c:otherwise>
<%-- Display the repositories. --%>
<c:forEach items="${remoteRepositories}" var="repository" varStatus="i">
<div class="repository">
<div style="float: right">
<%-- TODO: make some icons --%>
<pss:ifAnyAuthorized permissions="archiva-manage-configuration">
<ww:url id="editRepositoryUrl" action="editRepository">
<ww:param name="repoid" value="%{'${repository.id}'}" />
</ww:url>
<ww:url id="deleteRepositoryUrl" action="deleteRepository" method="confirm">
<ww:param name="repoid" value="%{'${repository.id}'}" />
</ww:url>
<ww:a href="%{editRepositoryUrl}">
<img src="<c:url value="/images/icons/edit.png" />" />
Edit Repository</ww:a>
<ww:a href="%{deleteRepositoryUrl}">
<img src="<c:url value="/images/icons/delete.gif" />" />
Delete Repository</ww:a>
</pss:ifAnyAuthorized>
</div>
<div style="float: left">
<img src="<c:url value="/images/archiva-world.png"/>" />
</div>
<h3 class="repository">${repository.name}</h3>
<table class="infoTable">
<tr>
<th>Identifier</th>
<td>
<code>${repository.id}</code>
</td>
</tr>
<tr>
<th>URL</th>
<td>${repository.url}</td>
</tr>
<tr>
<th>Type</th>
<%-- TODO: can probably just use layout appended to a key prefix in i18n to simplify this --%>
<td>
<c:choose>
<c:when test="${repository.layout == 'default'}">
Maven 2.x Repository
</c:when>
<c:otherwise>
Maven 1.x Repository
</c:otherwise>
</c:choose>
</td>
</tr>
<tr>
<th>Releases Included</th>
<td class="${repository.releases ? 'donemark' : 'errormark'} booleanIcon"> ${repository.releases}</td>
</tr>
<tr>
<th>Snapshots Included</th>
<td class="${repository.snapshots ? 'donemark' : 'errormark'} booleanIcon"> ${repository.snapshots}</td>
</tr>
</table>
</div>
</c:forEach>
</c:otherwise>
</c:choose>
</div>
</body>

View File

@ -116,28 +116,34 @@
<my:currentWWUrl action="configureAppearance" namespace="/admin">Appearance</my:currentWWUrl>
</li>
</pss:ifAuthorized>
<%-- TODO: future options here.
* Repository Statistics.
* Web Services Statistics.
--%>
</ul>
</pss:ifAnyAuthorized>
<pss:ifAuthorized permission="archiva-manage-configuration">
<h5>Administration</h5>
<ul>
<li class="none">
<my:currentWWUrl action="index" namespace="/admin">Settings</my:currentWWUrl>
</li>
<li class="none">
<my:currentWWUrl action="repositories" namespace="/admin">Repositories</my:currentWWUrl>
</li>
<%--
<li class="none">
<my:currentWWUrl action="proxiedRepositories" namespace="/admin">Proxied Repositories</my:currentWWUrl>
<my:currentWWUrl action="proxyConnectors" namespace="/admin">Proxy Connectors</my:currentWWUrl>
</li>
--%>
<%-- TODO: add back after synced repos are implemented
<li class="none">
<my:currentWWUrl action="syncedRepositories" namespace="/admin">Synced Repositories</my:currentWWUrl>
<my:currentWWUrl action="networkProxies" namespace="/admin">Network Proxies</my:currentWWUrl>
</li>
<li class="none">
<my:currentWWUrl action="repositoryScanning" namespace="/admin">Repository Scanning</my:currentWWUrl>
</li>
<li class="none">
<my:currentWWUrl action="database" namespace="/admin">Database</my:currentWWUrl>
</li>
<%-- TODO: future options here.
* Repository Syncing Connectors. (rsync, ftp, scp, etc...)
* Web Services (enable / disable), role based?
--%>
</ul>
</pss:ifAuthorized>

View File

@ -84,7 +84,6 @@ div.clear hr {
}
#leftColumn {
height: 315px;
width: 170px;
float: left;
overflow: auto;

View File

@ -211,3 +211,77 @@ ul.dependencyTree span.artifact-link {
background-color: #F3B455 !important;
}
div.repository h3 {
border-bottom: 0px !important;
padding-left: 15px !important;
}
div.repository {
border-bottom: 1px solid #DFDEDE;
}
tr.proxyConnector {
border-bottom: 1px solid #DFDEDE;
}
tr.proxyConnector td.managedRepo div,
tr.proxyConnector td.remoteRepo div {
border: 1px dotted gray;
padding: 5px;
background-color: white;
}
tr.proxyConnector td.managedRepo img,
tr.proxyConnector td.remoteRepo img {
float: left;
border: 0px;
}
tr.proxyConnector td.managedRepo div p,
tr.proxyConnector td.remoteRepo div p {
margin: 0px;
margin-left: 40px;
padding: 0px;
}
tr.proxyConnector td.managedRepo div p.id,
tr.proxyConnector td.remoteRepo div p.id {
font-family: monospace;
}
tr.proxyConnector td.connector {
padding-left: 10px;
padding-right: 10px;
}
tr.proxyConnector td.connector div.wrap {
margin-left: 10px;
margin-right: 10px;
padding: 5px;
border: 1px solid gray;
background-color: #eeeeee;
}
tr.proxyConnector td.connector div.controls {
float: right;
}
tr.proxyConnector td.connector div h4 {
font-size: 1.0em;
margin: 0px;
}
tr.proxyConnector td.connector table {
border: 0px;
background-color: transparent;
font-size: 0.8em;
}
tr.proxyConnector td.connector table p {
margin: 0px;
padding: 0px;
}
tr.seperator td {
border-top: 1px dashed #dddddd !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B