mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 09:25:43 +01:00
merge with brach issue-42
This commit is contained in:
@@ -33,6 +33,10 @@
|
|||||||
|
|
||||||
package sonia.scm;
|
package sonia.scm;
|
||||||
|
|
||||||
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration object for a SCM-Manager
|
* Configuration object for a SCM-Manager
|
||||||
* client (WebInterface, RestClient, ...).
|
* client (WebInterface, RestClient, ...).
|
||||||
@@ -48,6 +52,20 @@ public class ScmClientConfig
|
|||||||
*/
|
*/
|
||||||
public ScmClientConfig() {}
|
public ScmClientConfig() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs {@link ScmClientConfig} object
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param configuration SCM-Manager main configuration
|
||||||
|
* @since 1.14
|
||||||
|
*/
|
||||||
|
public ScmClientConfig(ScmConfiguration configuration)
|
||||||
|
{
|
||||||
|
this.dateFormat = configuration.getDateFormat();
|
||||||
|
this.disableGroupingGrid = configuration.isDisableGroupingGrid();
|
||||||
|
this.enableRepositoryArchive = configuration.isEnableRepositoryArchive();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs {@link ScmClientConfig} object
|
* Constructs {@link ScmClientConfig} object
|
||||||
*
|
*
|
||||||
@@ -100,6 +118,18 @@ public class ScmClientConfig
|
|||||||
return disableGroupingGrid;
|
return disableGroupingGrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the repository archive is disabled.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return true if the repository archive is disabled
|
||||||
|
* @since 1.14
|
||||||
|
*/
|
||||||
|
public boolean isEnableRepositoryArchive()
|
||||||
|
{
|
||||||
|
return enableRepositoryArchive;
|
||||||
|
}
|
||||||
|
|
||||||
//~--- set methods ----------------------------------------------------------
|
//~--- set methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,11 +157,26 @@ public class ScmClientConfig
|
|||||||
this.disableGroupingGrid = disableGroupingGrid;
|
this.disableGroupingGrid = disableGroupingGrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the repository archive. Default is disabled.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param enableRepositoryArchive true to disable the repository archive
|
||||||
|
* @since 1.14
|
||||||
|
*/
|
||||||
|
public void setEnableRepositoryArchive(boolean enableRepositoryArchive)
|
||||||
|
{
|
||||||
|
this.enableRepositoryArchive = enableRepositoryArchive;
|
||||||
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private String dateFormat;
|
private String dateFormat;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private boolean enableRepositoryArchive = true;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private boolean disableGroupingGrid = true;
|
private boolean disableGroupingGrid = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ public class ScmConfiguration
|
|||||||
this.forceBaseUrl = other.forceBaseUrl;
|
this.forceBaseUrl = other.forceBaseUrl;
|
||||||
this.baseUrl = other.baseUrl;
|
this.baseUrl = other.baseUrl;
|
||||||
this.disableGroupingGrid = other.disableGroupingGrid;
|
this.disableGroupingGrid = other.disableGroupingGrid;
|
||||||
|
this.enableRepositoryArchive = other.enableRepositoryArchive;
|
||||||
|
|
||||||
// deprecated fields
|
// deprecated fields
|
||||||
this.sslPort = other.sslPort;
|
this.sslPort = other.sslPort;
|
||||||
@@ -381,6 +382,18 @@ public class ScmConfiguration
|
|||||||
return enableProxy;
|
return enableProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the repository archive is enabled.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return true if the repository archive is enabled
|
||||||
|
* @since 1.14
|
||||||
|
*/
|
||||||
|
public boolean isEnableRepositoryArchive()
|
||||||
|
{
|
||||||
|
return enableRepositoryArchive;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if ssl is enabled.
|
* Returns true if ssl is enabled.
|
||||||
*
|
*
|
||||||
@@ -499,6 +512,18 @@ public class ScmConfiguration
|
|||||||
this.enableProxy = enableProxy;
|
this.enableProxy = enableProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the repository archive. Default is disabled.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param enableRepositoryArchive true to disable the repository archive
|
||||||
|
* @since 1.14
|
||||||
|
*/
|
||||||
|
public void setEnableRepositoryArchive(boolean enableRepositoryArchive)
|
||||||
|
{
|
||||||
|
this.enableRepositoryArchive = enableRepositoryArchive;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -682,6 +707,9 @@ public class ScmConfiguration
|
|||||||
private Set<ConfigChangedListener> listeners =
|
private Set<ConfigChangedListener> listeners =
|
||||||
new HashSet<ConfigChangedListener>();
|
new HashSet<ConfigChangedListener>();
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private boolean enableRepositoryArchive = false;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private boolean disableGroupingGrid = false;
|
private boolean disableGroupingGrid = false;
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ package sonia.scm.repository;
|
|||||||
|
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.security.ScmSecurityException;
|
import sonia.scm.security.ScmSecurityException;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
@@ -54,6 +58,14 @@ import java.util.List;
|
|||||||
public class PermissionUtil
|
public class PermissionUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the logger for PermissionUtil
|
||||||
|
*/
|
||||||
|
private static final Logger logger =
|
||||||
|
LoggerFactory.getLogger(PermissionUtil.class);
|
||||||
|
|
||||||
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -151,6 +163,40 @@ public class PermissionUtil
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the repository is writable.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param configuration SCM-Manager main configuration
|
||||||
|
* @param repository repository to check
|
||||||
|
* @param securityContext current user security context
|
||||||
|
*
|
||||||
|
* @return true if the repository is writable
|
||||||
|
* @since 1.14
|
||||||
|
*/
|
||||||
|
public static boolean isWritable(ScmConfiguration configuration,
|
||||||
|
Repository repository,
|
||||||
|
WebSecurityContext securityContext)
|
||||||
|
{
|
||||||
|
boolean permitted = false;
|
||||||
|
|
||||||
|
if (configuration.isEnableRepositoryArchive() && repository.isArchived())
|
||||||
|
{
|
||||||
|
if (logger.isWarnEnabled())
|
||||||
|
{
|
||||||
|
logger.warn("{} is archived and is not writeable",
|
||||||
|
repository.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
permitted = PermissionUtil.hasPermission(repository, securityContext,
|
||||||
|
PermissionType.WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return permitted;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -345,6 +345,18 @@ public class Repository extends BasicPropertiesAware implements ModelObject
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the repository is archived.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return true if the repository is archived
|
||||||
|
* @since 1.14
|
||||||
|
*/
|
||||||
|
public boolean isArchived()
|
||||||
|
{
|
||||||
|
return archived;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the {@link Repository} is public readable.
|
* Returns true if the {@link Repository} is public readable.
|
||||||
*
|
*
|
||||||
@@ -377,6 +389,18 @@ public class Repository extends BasicPropertiesAware implements ModelObject
|
|||||||
|
|
||||||
//~--- set methods ----------------------------------------------------------
|
//~--- set methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Archive or un archive this repository.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param archived true to enable archive
|
||||||
|
* @since 1.14
|
||||||
|
*/
|
||||||
|
public void setArchived(boolean archived)
|
||||||
|
{
|
||||||
|
this.archived = archived;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the contact of the {@link Repository}. The contact address should be
|
* Sets the contact of the {@link Repository}. The contact address should be
|
||||||
* a email address of a person who is responsible for the {@link Repository}.
|
* a email address of a person who is responsible for the {@link Repository}.
|
||||||
@@ -516,6 +540,9 @@ public class Repository extends BasicPropertiesAware implements ModelObject
|
|||||||
@XmlElement(name = "public")
|
@XmlElement(name = "public")
|
||||||
private boolean publicReadable = false;
|
private boolean publicReadable = false;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private boolean archived = false;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.SCMContext;
|
import sonia.scm.SCMContext;
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.repository.PermissionType;
|
import sonia.scm.repository.PermissionType;
|
||||||
import sonia.scm.repository.PermissionUtil;
|
import sonia.scm.repository.PermissionUtil;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
@@ -76,10 +77,14 @@ public abstract class PermissionFilter extends HttpFilter
|
|||||||
* Constructs ...
|
* Constructs ...
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
* @param securityContextProvider
|
* @param securityContextProvider
|
||||||
*/
|
*/
|
||||||
public PermissionFilter(Provider<WebSecurityContext> securityContextProvider)
|
public PermissionFilter(ScmConfiguration configuration,
|
||||||
|
Provider<WebSecurityContext> securityContextProvider)
|
||||||
{
|
{
|
||||||
|
this.configuration = configuration;
|
||||||
this.securityContextProvider = securityContextProvider;
|
this.securityContextProvider = securityContextProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,10 +144,7 @@ public abstract class PermissionFilter extends HttpFilter
|
|||||||
{
|
{
|
||||||
boolean writeRequest = isWriteRequest(request);
|
boolean writeRequest = isWriteRequest(request);
|
||||||
|
|
||||||
if (PermissionUtil.hasPermission(repository, securityContext,
|
if (hasPermission(repository, securityContext, writeRequest))
|
||||||
writeRequest
|
|
||||||
? PermissionType.WRITE
|
|
||||||
: PermissionType.READ))
|
|
||||||
{
|
{
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
@@ -213,8 +215,43 @@ public abstract class PermissionFilter extends HttpFilter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param repository
|
||||||
|
* @param securityContext
|
||||||
|
* @param writeRequest
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean hasPermission(Repository repository,
|
||||||
|
WebSecurityContext securityContext,
|
||||||
|
boolean writeRequest)
|
||||||
|
{
|
||||||
|
boolean permitted = false;
|
||||||
|
|
||||||
|
if (writeRequest)
|
||||||
|
{
|
||||||
|
permitted = PermissionUtil.isWritable(configuration, repository,
|
||||||
|
securityContext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
permitted = PermissionUtil.hasPermission(repository, securityContext,
|
||||||
|
PermissionType.READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
return permitted;
|
||||||
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
protected Provider<WebSecurityContext> securityContextProvider;
|
protected Provider<WebSecurityContext> securityContextProvider;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private ScmConfiguration configuration;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import sonia.scm.web.security.WebSecurityContext;
|
|||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -61,10 +62,11 @@ public abstract class ProviderPermissionFilter extends PermissionFilter
|
|||||||
* @param repositoryProvider
|
* @param repositoryProvider
|
||||||
*/
|
*/
|
||||||
public ProviderPermissionFilter(
|
public ProviderPermissionFilter(
|
||||||
|
ScmConfiguration configuration,
|
||||||
Provider<WebSecurityContext> securityContextProvider,
|
Provider<WebSecurityContext> securityContextProvider,
|
||||||
RepositoryProvider repositoryProvider)
|
RepositoryProvider repositoryProvider)
|
||||||
{
|
{
|
||||||
super(securityContextProvider);
|
super(configuration, securityContextProvider);
|
||||||
this.repositoryProvider = repositoryProvider;
|
this.repositoryProvider = repositoryProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ package sonia.scm.web.filter;
|
|||||||
|
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.repository.RepositoryManager;
|
import sonia.scm.repository.RepositoryManager;
|
||||||
import sonia.scm.web.security.WebSecurityContext;
|
import sonia.scm.web.security.WebSecurityContext;
|
||||||
@@ -65,14 +66,17 @@ public abstract class RegexPermissionFilter extends PermissionFilter
|
|||||||
* Constructs ...
|
* Constructs ...
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
* @param securityContextProvider
|
* @param securityContextProvider
|
||||||
* @param repositoryManager
|
* @param repositoryManager
|
||||||
*/
|
*/
|
||||||
public RegexPermissionFilter(
|
public RegexPermissionFilter(
|
||||||
|
ScmConfiguration configuration,
|
||||||
Provider<WebSecurityContext> securityContextProvider,
|
Provider<WebSecurityContext> securityContextProvider,
|
||||||
RepositoryManager repositoryManager)
|
RepositoryManager repositoryManager)
|
||||||
{
|
{
|
||||||
super(securityContextProvider);
|
super(configuration, securityContextProvider);
|
||||||
this.repositoryManager = repositoryManager;
|
this.repositoryManager = repositoryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,10 @@ package sonia.scm.repository;
|
|||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.security.ScmSecurityException;
|
import sonia.scm.security.ScmSecurityException;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
import sonia.scm.web.security.WebSecurityContext;
|
import sonia.scm.web.security.WebSecurityContext;
|
||||||
@@ -65,17 +67,7 @@ public class PermissionUtilTest
|
|||||||
*/
|
*/
|
||||||
public PermissionUtilTest()
|
public PermissionUtilTest()
|
||||||
{
|
{
|
||||||
repository = new Repository();
|
|
||||||
admams.getUser().setAdmin(true);
|
admams.getUser().setAdmin(true);
|
||||||
|
|
||||||
Permission[] permissions = new Permission[] {
|
|
||||||
new Permission("dent", PermissionType.READ),
|
|
||||||
new Permission("perfect",
|
|
||||||
PermissionType.WRITE),
|
|
||||||
new Permission("marvin",
|
|
||||||
PermissionType.OWNER) };
|
|
||||||
|
|
||||||
repository.setPermissions(Arrays.asList(permissions));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -108,6 +100,25 @@ public class PermissionUtilTest
|
|||||||
PermissionUtil.assertPermission(repository, admams, PermissionType.OWNER);
|
PermissionUtil.assertPermission(repository, admams, PermissionType.OWNER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
public void before()
|
||||||
|
{
|
||||||
|
repository = new Repository();
|
||||||
|
|
||||||
|
Permission[] permissions = new Permission[] {
|
||||||
|
new Permission("dent", PermissionType.READ),
|
||||||
|
new Permission("perfect",
|
||||||
|
PermissionType.WRITE),
|
||||||
|
new Permission("marvin",
|
||||||
|
PermissionType.OWNER) };
|
||||||
|
|
||||||
|
repository.setPermissions(Arrays.asList(permissions));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -161,6 +172,31 @@ public class PermissionUtilTest
|
|||||||
PermissionType.OWNER));
|
PermissionType.OWNER));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testIsWritable()
|
||||||
|
{
|
||||||
|
ScmConfiguration configuration = new ScmConfiguration();
|
||||||
|
|
||||||
|
configuration.setEnableRepositoryArchive(true);
|
||||||
|
assertTrue(PermissionUtil.isWritable(configuration, repository, perfect));
|
||||||
|
repository.setArchived(true);
|
||||||
|
assertFalse(PermissionUtil.isWritable(configuration, repository, perfect));
|
||||||
|
assertFalse(PermissionUtil.isWritable(configuration, repository, admams));
|
||||||
|
configuration.setEnableRepositoryArchive(false);
|
||||||
|
assertTrue(PermissionUtil.isWritable(configuration, repository, perfect));
|
||||||
|
assertTrue(PermissionUtil.isWritable(configuration, repository, admams));
|
||||||
|
assertFalse(PermissionUtil.isWritable(configuration, repository, dent));
|
||||||
|
configuration.setEnableRepositoryArchive(true);
|
||||||
|
repository.setArchived(false);
|
||||||
|
assertTrue(PermissionUtil.isWritable(configuration, repository, perfect));
|
||||||
|
assertTrue(PermissionUtil.isWritable(configuration, repository, admams));
|
||||||
|
assertFalse(PermissionUtil.isWritable(configuration, repository, dent));
|
||||||
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import sonia.scm.web.security.WebSecurityContext;
|
|||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -79,10 +80,11 @@ public class GitPermissionFilter extends ProviderPermissionFilter
|
|||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public GitPermissionFilter(
|
public GitPermissionFilter(
|
||||||
|
ScmConfiguration configuration,
|
||||||
Provider<WebSecurityContext> securityContextProvider,
|
Provider<WebSecurityContext> securityContextProvider,
|
||||||
RepositoryProvider repositoryProvider)
|
RepositoryProvider repositoryProvider)
|
||||||
{
|
{
|
||||||
super(securityContextProvider, repositoryProvider);
|
super(configuration, securityContextProvider, repositoryProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import sonia.scm.web.security.WebSecurityContext;
|
|||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -64,10 +65,11 @@ public class HgPermissionFilter extends ProviderPermissionFilter
|
|||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public HgPermissionFilter(
|
public HgPermissionFilter(
|
||||||
|
ScmConfiguration configuration,
|
||||||
Provider<WebSecurityContext> securityContextProvider,
|
Provider<WebSecurityContext> securityContextProvider,
|
||||||
RepositoryProvider repositoryProvider)
|
RepositoryProvider repositoryProvider)
|
||||||
{
|
{
|
||||||
super(securityContextProvider, repositoryProvider);
|
super(configuration, securityContextProvider, repositoryProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.repository.RepositoryProvider;
|
import sonia.scm.repository.RepositoryProvider;
|
||||||
import sonia.scm.web.filter.ProviderPermissionFilter;
|
import sonia.scm.web.filter.ProviderPermissionFilter;
|
||||||
import sonia.scm.web.security.WebSecurityContext;
|
import sonia.scm.web.security.WebSecurityContext;
|
||||||
@@ -72,15 +73,18 @@ public class SvnPermissionFilter extends ProviderPermissionFilter
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
* @param securityContextProvider
|
* @param securityContextProvider
|
||||||
* @param repository
|
* @param repository
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public SvnPermissionFilter(
|
public SvnPermissionFilter(
|
||||||
|
ScmConfiguration configuration,
|
||||||
Provider<WebSecurityContext> securityContextProvider,
|
Provider<WebSecurityContext> securityContextProvider,
|
||||||
RepositoryProvider repository)
|
RepositoryProvider repository)
|
||||||
{
|
{
|
||||||
super(securityContextProvider, repository);
|
super(configuration, securityContextProvider, repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|||||||
@@ -251,8 +251,7 @@ public class AuthenticationResource
|
|||||||
return new ScmState(contextProvider, securityContext,
|
return new ScmState(contextProvider, securityContext,
|
||||||
repositoryManger.getConfiguredTypes(),
|
repositoryManger.getConfiguredTypes(),
|
||||||
userManager.getDefaultType(),
|
userManager.getDefaultType(),
|
||||||
new ScmClientConfig(configuration.getDateFormat(),
|
new ScmClientConfig(configuration));
|
||||||
configuration.isDisableGroupingGrid()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|||||||
@@ -46,6 +46,25 @@ import sonia.scm.ConfigurationException;
|
|||||||
import sonia.scm.HandlerEvent;
|
import sonia.scm.HandlerEvent;
|
||||||
import sonia.scm.SCMContextProvider;
|
import sonia.scm.SCMContextProvider;
|
||||||
import sonia.scm.Type;
|
import sonia.scm.Type;
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
import sonia.scm.repository.AbstractRepositoryManager;
|
||||||
|
import sonia.scm.repository.BlameViewer;
|
||||||
|
import sonia.scm.repository.ChangesetViewer;
|
||||||
|
import sonia.scm.repository.DiffViewer;
|
||||||
|
import sonia.scm.repository.PermissionType;
|
||||||
|
import sonia.scm.repository.PermissionUtil;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.RepositoryAllreadyExistExeption;
|
||||||
|
import sonia.scm.repository.RepositoryBrowser;
|
||||||
|
import sonia.scm.repository.RepositoryException;
|
||||||
|
import sonia.scm.repository.RepositoryHandler;
|
||||||
|
import sonia.scm.repository.RepositoryHandlerNotFoundException;
|
||||||
|
import sonia.scm.repository.RepositoryHook;
|
||||||
|
import sonia.scm.repository.RepositoryHookEvent;
|
||||||
|
import sonia.scm.repository.RepositoryListener;
|
||||||
|
import sonia.scm.repository.RepositoryNotFoundException;
|
||||||
|
|
||||||
import sonia.scm.security.ScmSecurityException;
|
import sonia.scm.security.ScmSecurityException;
|
||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.util.CollectionAppender;
|
import sonia.scm.util.CollectionAppender;
|
||||||
@@ -92,6 +111,8 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @param configuration
|
||||||
* @param contextProvider
|
* @param contextProvider
|
||||||
* @param securityContextProvider
|
* @param securityContextProvider
|
||||||
* @param repositoryDAO
|
* @param repositoryDAO
|
||||||
@@ -101,12 +122,13 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
|
|||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
public DefaultRepositoryManager(
|
public DefaultRepositoryManager(
|
||||||
SCMContextProvider contextProvider,
|
ScmConfiguration configuration, SCMContextProvider contextProvider,
|
||||||
Provider<WebSecurityContext> securityContextProvider,
|
Provider<WebSecurityContext> securityContextProvider,
|
||||||
RepositoryDAO repositoryDAO, Set<RepositoryHandler> handlerSet,
|
RepositoryDAO repositoryDAO, Set<RepositoryHandler> handlerSet,
|
||||||
Provider<Set<RepositoryListener>> repositoryListenersProvider,
|
Provider<Set<RepositoryListener>> repositoryListenersProvider,
|
||||||
Provider<Set<RepositoryHook>> repositoryHooksProvider)
|
Provider<Set<RepositoryHook>> repositoryHooksProvider)
|
||||||
{
|
{
|
||||||
|
this.configuration = configuration;
|
||||||
this.securityContextProvider = securityContextProvider;
|
this.securityContextProvider = securityContextProvider;
|
||||||
this.repositoryDAO = repositoryDAO;
|
this.repositoryDAO = repositoryDAO;
|
||||||
this.repositoryListenersProvider = repositoryListenersProvider;
|
this.repositoryListenersProvider = repositoryListenersProvider;
|
||||||
@@ -213,6 +235,12 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
|
|||||||
|
|
||||||
assertIsOwner(repository);
|
assertIsOwner(repository);
|
||||||
|
|
||||||
|
if (configuration.isEnableRepositoryArchive() &&!repository.isArchived())
|
||||||
|
{
|
||||||
|
throw new RepositoryException(
|
||||||
|
"Repository could not deleted, because it is not archived.");
|
||||||
|
}
|
||||||
|
|
||||||
if (repositoryDAO.contains(repository))
|
if (repositoryDAO.contains(repository))
|
||||||
{
|
{
|
||||||
getHandler(repository).delete(repository);
|
getHandler(repository).delete(repository);
|
||||||
@@ -932,6 +960,9 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager
|
|||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
private ScmConfiguration configuration;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private Map<String, RepositoryHandler> handlerMap;
|
private Map<String, RepositoryHandler> handlerMap;
|
||||||
|
|
||||||
|
|||||||
BIN
scm-webapp/src/main/webapp/resources/images/archive.png
Executable file
BIN
scm-webapp/src/main/webapp/resources/images/archive.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 555 B |
@@ -57,6 +57,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{
|
|||||||
baseUrlText: 'Base Url',
|
baseUrlText: 'Base Url',
|
||||||
forceBaseUrlText: 'Force Base Url',
|
forceBaseUrlText: 'Force Base Url',
|
||||||
disableGroupingGridText: 'Disable repository Groups',
|
disableGroupingGridText: 'Disable repository Groups',
|
||||||
|
enableRepositoryArchiveText: 'Enable repository archive',
|
||||||
|
|
||||||
|
|
||||||
// help
|
// help
|
||||||
@@ -81,7 +82,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{
|
|||||||
baseUrlHelpText: 'The url of the application (with context path) i.e. http://localhost:8080/scm',
|
baseUrlHelpText: 'The url of the application (with context path) i.e. http://localhost:8080/scm',
|
||||||
forceBaseUrlHelpText: 'Redirects to the base url if the request comes from a other url',
|
forceBaseUrlHelpText: 'Redirects to the base url if the request comes from a other url',
|
||||||
disableGroupingGridHelpText: 'Disable repository Groups. A complete page reload is required after a change of this value.',
|
disableGroupingGridHelpText: 'Disable repository Groups. A complete page reload is required after a change of this value.',
|
||||||
|
enableRepositoryArchiveHelpText: 'Enable repository archives. A complete page reload is required after a change of this value.',
|
||||||
|
|
||||||
initComponent: function(){
|
initComponent: function(){
|
||||||
|
|
||||||
@@ -108,6 +109,12 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{
|
|||||||
name: 'disableGroupingGrid',
|
name: 'disableGroupingGrid',
|
||||||
inputValue: 'true',
|
inputValue: 'true',
|
||||||
helpText: this.disableGroupingGridHelpText
|
helpText: this.disableGroupingGridHelpText
|
||||||
|
},{
|
||||||
|
xtype: 'checkbox',
|
||||||
|
fieldLabel: this.enableRepositoryArchiveText,
|
||||||
|
name: 'enableRepositoryArchive',
|
||||||
|
inputValue: 'true',
|
||||||
|
helpText: this.enableRepositoryArchiveHelpText
|
||||||
},{
|
},{
|
||||||
xtype: 'textfield',
|
xtype: 'textfield',
|
||||||
fieldLabel: this.dateFormatText,
|
fieldLabel: this.dateFormatText,
|
||||||
|
|||||||
@@ -36,11 +36,23 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
colDescriptionText: 'Description',
|
colDescriptionText: 'Description',
|
||||||
colCreationDateText: 'Creation date',
|
colCreationDateText: 'Creation date',
|
||||||
colUrlText: 'Url',
|
colUrlText: 'Url',
|
||||||
|
colArchiveText: 'Archive',
|
||||||
emptyText: 'No repository is configured',
|
emptyText: 'No repository is configured',
|
||||||
formTitleText: 'Repository Form',
|
formTitleText: 'Repository Form',
|
||||||
unknownType: 'Unknown',
|
unknownType: 'Unknown',
|
||||||
|
|
||||||
|
archiveIcon: 'resources/images/archive.png',
|
||||||
|
|
||||||
|
filterRequest: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use filterRequest
|
||||||
|
*/
|
||||||
searchValue: null,
|
searchValue: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use filterRequest
|
||||||
|
*/
|
||||||
typeFilter: null,
|
typeFilter: null,
|
||||||
|
|
||||||
// TODO find better text
|
// TODO find better text
|
||||||
@@ -82,6 +94,8 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
name:'permissions'
|
name:'permissions'
|
||||||
},{
|
},{
|
||||||
name: 'properties'
|
name: 'properties'
|
||||||
|
},{
|
||||||
|
name: 'archived'
|
||||||
}]
|
}]
|
||||||
}),
|
}),
|
||||||
sortInfo: {
|
sortInfo: {
|
||||||
@@ -139,6 +153,14 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
dataIndex: 'url',
|
dataIndex: 'url',
|
||||||
renderer: this.renderUrl,
|
renderer: this.renderUrl,
|
||||||
width: 250
|
width: 250
|
||||||
|
},{
|
||||||
|
id: 'Archive',
|
||||||
|
header: this.colArchiveText,
|
||||||
|
dataIndex: 'archived',
|
||||||
|
width: 40,
|
||||||
|
hidden: ! state.clientConfig.enableRepositoryArchive,
|
||||||
|
renderer: this.renderArchive,
|
||||||
|
scope: this
|
||||||
},{
|
},{
|
||||||
id: 'group',
|
id: 'group',
|
||||||
dataIndex: 'group',
|
dataIndex: 'group',
|
||||||
@@ -159,6 +181,13 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
console.debug( msg );
|
console.debug( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( state.clientConfig.enableRepositoryArchive ){
|
||||||
|
if ( !this.filterRequest ){
|
||||||
|
this.filterRequest = {};
|
||||||
|
}
|
||||||
|
this.filterRequest.archived = false;
|
||||||
|
}
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
autoExpandColumn: 'description',
|
autoExpandColumn: 'description',
|
||||||
store: repositoryStore,
|
store: repositoryStore,
|
||||||
@@ -180,6 +209,8 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.addEvents('repositorySelected');
|
||||||
|
|
||||||
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
Ext.apply(this, Ext.apply(this.initialConfig, config));
|
||||||
Sonia.repository.Grid.superclass.initComponent.apply(this, arguments);
|
Sonia.repository.Grid.superclass.initComponent.apply(this, arguments);
|
||||||
|
|
||||||
@@ -188,6 +219,10 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderArchive: function(v){
|
||||||
|
return v ? '<img src=' + this.archiveIcon + ' alt=' + v + '>' : '';
|
||||||
|
},
|
||||||
|
|
||||||
convertToGroup: function(v, data){
|
convertToGroup: function(v, data){
|
||||||
var name = data.name;
|
var name = data.name;
|
||||||
var i = name.lastIndexOf('/');
|
var i = name.lastIndexOf('/');
|
||||||
@@ -220,6 +255,9 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
this.filterStore();
|
this.filterStore();
|
||||||
}
|
}
|
||||||
this.ready = true;
|
this.ready = true;
|
||||||
|
if (this.filterRequest){
|
||||||
|
this.filterByRequest();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onFallBelowMinHeight: function(height, minHeight){
|
onFallBelowMinHeight: function(height, minHeight){
|
||||||
@@ -233,23 +271,63 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
this.ownerCt.doLayout();
|
this.ownerCt.doLayout();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getFilterRequest: function(){
|
||||||
|
if ( ! this.filterRequest ){
|
||||||
|
this.filterRequest = {};
|
||||||
|
}
|
||||||
|
return this.filterRequest;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use filterByRequest
|
||||||
|
*/
|
||||||
search: function(value){
|
search: function(value){
|
||||||
this.searchValue = value;
|
this.searchValue = value;
|
||||||
this.filterStore();
|
this.filterStore();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use filterByRequest
|
||||||
|
*/
|
||||||
filter: function(type){
|
filter: function(type){
|
||||||
this.typeFilter = type;
|
this.typeFilter = type;
|
||||||
this.filterStore();
|
this.filterStore();
|
||||||
},
|
},
|
||||||
|
|
||||||
clearStoreFilter: function(){
|
clearStoreFilter: function(){
|
||||||
|
this.filterRequest = null;
|
||||||
this.searchValue = null;
|
this.searchValue = null;
|
||||||
this.typeFilter = null;
|
this.typeFilter = null;
|
||||||
this.getStore().clearFilter();
|
this.getStore().clearFilter();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
filterByRequest: function(){
|
||||||
|
if (debug){
|
||||||
|
console.debug('filter repository store by request:');
|
||||||
|
console.debug(this.filterRequest);
|
||||||
|
}
|
||||||
|
var store = this.getStore();
|
||||||
|
if ( ! this.filterRequest ){
|
||||||
|
store.clearFilter();
|
||||||
|
} else {
|
||||||
|
var query = this.filterRequest.query;
|
||||||
|
if ( query ){
|
||||||
|
query = query.toLowerCase();
|
||||||
|
}
|
||||||
|
var archived = ! state.clientConfig.enableRepositoryArchive || this.filterRequest.archived;
|
||||||
|
store.filterBy(function(rec){
|
||||||
|
var desc = rec.get('description');
|
||||||
|
return (! query || rec.get('name').toLowerCase().indexOf(query) >= 0 ||
|
||||||
|
(desc && desc.toLowerCase().indexOf(query) >= 0)) &&
|
||||||
|
(! this.filterRequest.type || rec.get('type') == this.filterRequest.type) &&
|
||||||
|
(archived || ! rec.get('archived'));
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use filterByRequest
|
||||||
|
*/
|
||||||
filterStore: function(){
|
filterStore: function(){
|
||||||
var store = this.getStore();
|
var store = this.getStore();
|
||||||
if ( ! this.searchValue && ! this.typeFilter ){
|
if ( ! this.searchValue && ! this.typeFilter ){
|
||||||
@@ -268,6 +346,9 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO move to panel
|
||||||
|
*/
|
||||||
selectItem: function(item){
|
selectItem: function(item){
|
||||||
if ( debug ){
|
if ( debug ){
|
||||||
console.debug( item.name + ' selected' );
|
console.debug( item.name + ' selected' );
|
||||||
@@ -277,13 +358,16 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
|
|||||||
this.parentPanel.updateHistory(item);
|
this.parentPanel.updateHistory(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var owner = Sonia.repository.isOwner(item);
|
||||||
|
|
||||||
|
this.fireEvent('repositorySelected', item, owner);
|
||||||
|
|
||||||
var infoPanel = main.getInfoPanel(item.type);
|
var infoPanel = main.getInfoPanel(item.type);
|
||||||
infoPanel.item = item;
|
infoPanel.item = item;
|
||||||
|
|
||||||
var panels = [infoPanel];
|
var panels = [infoPanel];
|
||||||
|
|
||||||
if ( Sonia.repository.isOwner(item) ){
|
if ( owner ){
|
||||||
Ext.getCmp('repoRmButton').setDisabled(false);
|
|
||||||
panels.push({
|
panels.push({
|
||||||
item: item,
|
item: item,
|
||||||
xtype: 'repositorySettingsForm',
|
xtype: 'repositorySettingsForm',
|
||||||
|
|||||||
@@ -34,11 +34,21 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, {
|
|||||||
|
|
||||||
titleText: 'Repository Form',
|
titleText: 'Repository Form',
|
||||||
emptyText: 'Add or select an Repository',
|
emptyText: 'Add or select an Repository',
|
||||||
|
|
||||||
|
// TODO i18n
|
||||||
|
archiveText: 'Archive',
|
||||||
|
unarchiveText: 'Unarchive',
|
||||||
|
archiveTitleText: 'Archive Repository',
|
||||||
|
archiveMsgText: 'Archive Repository "{0}"?',
|
||||||
|
errorArchiveMsgText: 'Repository archival failed',
|
||||||
|
|
||||||
removeTitleText: 'Remove Repository',
|
removeTitleText: 'Remove Repository',
|
||||||
removeMsgText: 'Remove Repository "{0}"?',
|
removeMsgText: 'Remove Repository "{0}"?',
|
||||||
errorTitleText: 'Error',
|
errorTitleText: 'Error',
|
||||||
errorMsgText: 'Repository deletion failed',
|
errorMsgText: 'Repository deletion failed',
|
||||||
|
|
||||||
|
archiveIcon: 'resources/images/archive.png',
|
||||||
|
|
||||||
repositoryGrid: null,
|
repositoryGrid: null,
|
||||||
|
|
||||||
initComponent: function(){
|
initComponent: function(){
|
||||||
@@ -70,6 +80,20 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, {
|
|||||||
handler: this.showAddForm
|
handler: this.showAddForm
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// repository archive
|
||||||
|
if (state.clientConfig.enableRepositoryArchive){
|
||||||
|
toolbar.push({
|
||||||
|
xtype: 'tbbutton',
|
||||||
|
id: 'repoArchiveButton',
|
||||||
|
disabled: true,
|
||||||
|
text: this.archiveText,
|
||||||
|
icon: this.archiveIcon,
|
||||||
|
scope: this,
|
||||||
|
handler: this.toggleArchive
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
toolbar.push({
|
toolbar.push({
|
||||||
xtype: 'tbbutton',
|
xtype: 'tbbutton',
|
||||||
id: 'repoRmButton',
|
id: 'repoRmButton',
|
||||||
@@ -127,13 +151,37 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// repository archive
|
||||||
|
if (state.clientConfig.enableRepositoryArchive){
|
||||||
|
toolbar.push(' ',{
|
||||||
|
id: 'displayArchived',
|
||||||
|
xtype: 'checkbox',
|
||||||
|
listeners: {
|
||||||
|
check: {
|
||||||
|
fn: this.filterByArchived,
|
||||||
|
scope: this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
xtype: 'label',
|
||||||
|
text: 'Archive',
|
||||||
|
cls: 'ytb-text'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
tbar: toolbar,
|
tbar: toolbar,
|
||||||
items: [{
|
items: [{
|
||||||
id: 'repositoryGrid',
|
id: 'repositoryGrid',
|
||||||
xtype: 'repositoryGrid',
|
xtype: 'repositoryGrid',
|
||||||
region: 'center',
|
region: 'center',
|
||||||
parentPanel: this
|
parentPanel: this,
|
||||||
|
listeners: {
|
||||||
|
repositorySelected: {
|
||||||
|
fn: this.onRepositorySelection,
|
||||||
|
scope: this
|
||||||
|
}
|
||||||
|
}
|
||||||
},{
|
},{
|
||||||
id: 'repositoryEditPanel',
|
id: 'repositoryEditPanel',
|
||||||
xtype: 'tabpanel',
|
xtype: 'tabpanel',
|
||||||
@@ -170,57 +218,144 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, {
|
|||||||
Sonia.History.add(token);
|
Sonia.History.add(token);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
filterByArchived: function(checkbox, checked){
|
||||||
|
var grid = this.getGrid();
|
||||||
|
grid.getFilterRequest().archived = checked;
|
||||||
|
grid.filterByRequest();
|
||||||
|
},
|
||||||
|
|
||||||
filterByType: function(combo, rec){
|
filterByType: function(combo, rec){
|
||||||
this.getGrid().filter(rec.get('name'));
|
var grid = this.getGrid();
|
||||||
|
grid.getFilterRequest().type = rec.get('name');
|
||||||
|
grid.filterByRequest();
|
||||||
},
|
},
|
||||||
|
|
||||||
search: function(field){
|
search: function(field){
|
||||||
this.getGrid().search(field.getValue());
|
var grid = this.getGrid();
|
||||||
|
grid.getFilterRequest().query = field.getValue();
|
||||||
|
grid.filterByRequest();
|
||||||
},
|
},
|
||||||
|
|
||||||
removeRepository: function(){
|
getSelectedRepository: function(){
|
||||||
|
var repository = null;
|
||||||
var grid = this.getGrid();
|
var grid = this.getGrid();
|
||||||
var selected = grid.getSelectionModel().getSelected();
|
var selected = grid.getSelectionModel().getSelected();
|
||||||
if ( selected ){
|
if ( selected ){
|
||||||
var item = selected.data;
|
repository = selected.data;
|
||||||
var url = restUrl + 'repositories/' + item.id + '.json';
|
} else if (debug) {
|
||||||
|
console.debug( 'no repository selected' );
|
||||||
|
}
|
||||||
|
return repository;
|
||||||
|
},
|
||||||
|
|
||||||
|
executeRemoteCall: function(title, message, method, url, data, failureCallback){
|
||||||
Ext.MessageBox.show({
|
Ext.MessageBox.show({
|
||||||
title: this.removeTitleText,
|
title: title,
|
||||||
msg: String.format(this.removeMsgText, item.name),
|
msg: message,
|
||||||
buttons: Ext.MessageBox.OKCANCEL,
|
buttons: Ext.MessageBox.OKCANCEL,
|
||||||
icon: Ext.MessageBox.QUESTION,
|
icon: Ext.MessageBox.QUESTION,
|
||||||
fn: function(result){
|
fn: function(result){
|
||||||
if ( result == 'ok' ){
|
if ( result == 'ok' ){
|
||||||
|
|
||||||
if ( debug ){
|
if ( debug ){
|
||||||
console.debug( 'remove repository ' + item.name );
|
console.debug('call repository repository action '+ method + ' on ' + url );
|
||||||
|
}
|
||||||
|
|
||||||
|
var el = this.el;
|
||||||
|
var tid = setTimeout( function(){el.mask('Loading ...');}, 100);
|
||||||
|
|
||||||
|
if (data && data.group){
|
||||||
|
delete data.group;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ext.Ajax.request({
|
Ext.Ajax.request({
|
||||||
url: url,
|
url: url,
|
||||||
method: 'DELETE',
|
method: method,
|
||||||
|
jsonData: data,
|
||||||
scope: this,
|
scope: this,
|
||||||
success: function(){
|
success: function(){
|
||||||
this.reload();
|
this.reload();
|
||||||
this.resetPanel();
|
this.resetPanel();
|
||||||
|
clearTimeout(tid);
|
||||||
|
el.unmask();
|
||||||
},
|
},
|
||||||
failure: function(result){
|
failure: function(result){
|
||||||
main.handleRestFailure(
|
clearTimeout(tid);
|
||||||
result,
|
el.unmask();
|
||||||
|
failureCallback.call(this, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} // canceled
|
||||||
|
},
|
||||||
|
scope: this
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleArchive: function(){
|
||||||
|
var item = this.getSelectedRepository();
|
||||||
|
if ( item ){
|
||||||
|
console.debug(item);
|
||||||
|
|
||||||
|
item.archived = ! item.archived;
|
||||||
|
if (debug){
|
||||||
|
console.debug('toggle repository ' + item.name + ' archive to ' + item.archived);
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = restUrl + 'repositories/' + item.id + '.json';
|
||||||
|
this.executeRemoteCall(this.archiveTitleText,
|
||||||
|
String.format(this.archiveMsgText, item.name),
|
||||||
|
'PUT', url, item, function(result){
|
||||||
|
main.handleFailure(
|
||||||
|
result.status,
|
||||||
|
this.errorTitleText,
|
||||||
|
this.errorArchiveMsgText
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
removeRepository: function(){
|
||||||
|
var item = this.getSelectedRepository();
|
||||||
|
if ( item ){
|
||||||
|
if ( debug ){
|
||||||
|
console.debug( 'remove repository ' + item.name );
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = restUrl + 'repositories/' + item.id + '.json';
|
||||||
|
this.executeRemoteCall(this.archiveTitleText,
|
||||||
|
String.format(this.archiveMsgText, item.name),
|
||||||
|
'DELETE', url, null, function(result){
|
||||||
|
main.handleFailure(
|
||||||
|
result.status,
|
||||||
this.errorTitleText,
|
this.errorTitleText,
|
||||||
this.errorMsgText
|
this.errorMsgText
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
scope: this
|
|
||||||
});
|
|
||||||
|
|
||||||
} else if ( debug ){
|
onRepositorySelection: function(item, owner){
|
||||||
console.debug( 'no repository selected' );
|
if ( owner ){
|
||||||
|
if (state.clientConfig.enableRepositoryArchive){
|
||||||
|
var archiveBt = Ext.getCmp('repoArchiveButton');
|
||||||
|
if ( item.archived ){
|
||||||
|
archiveBt.setText(this.unarchiveText);
|
||||||
|
Ext.getCmp('repoRmButton').setDisabled(false);
|
||||||
|
} else {
|
||||||
|
archiveBt.setText(this.archiveText);
|
||||||
|
Ext.getCmp('repoRmButton').setDisabled(true);
|
||||||
|
}
|
||||||
|
archiveBt.setDisabled(false);
|
||||||
|
} else {
|
||||||
|
Ext.getCmp('repoRmButton').setDisabled(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ext.getCmp('repoRmButton').setDisabled(false);
|
||||||
|
if (state.clientConfig.enableRepositoryArchive){
|
||||||
|
Ext.getCmp('repoArchiveButton').setDisabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -271,6 +406,10 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, {
|
|||||||
|
|
||||||
reload: function(){
|
reload: function(){
|
||||||
this.getGrid().reload();
|
this.getGrid().reload();
|
||||||
|
var repo = this.getSelectedRepository();
|
||||||
|
if ( repo ){
|
||||||
|
this.onRepositorySelection(repo, Sonia.repository.isOwner(repo));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import sonia.scm.Type;
|
import sonia.scm.Type;
|
||||||
import sonia.scm.repository.xml.XmlRepositoryDAO;
|
import sonia.scm.repository.xml.XmlRepositoryDAO;
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.store.JAXBStoreFactory;
|
import sonia.scm.store.JAXBStoreFactory;
|
||||||
import sonia.scm.store.StoreFactory;
|
import sonia.scm.store.StoreFactory;
|
||||||
import sonia.scm.util.MockUtil;
|
import sonia.scm.util.MockUtil;
|
||||||
@@ -134,7 +135,9 @@ public class DefaultRepositoryManagerTest extends RepositoryManagerTestBase
|
|||||||
|
|
||||||
XmlRepositoryDAO repositoryDAO = new XmlRepositoryDAO(factory);
|
XmlRepositoryDAO repositoryDAO = new XmlRepositoryDAO(factory);
|
||||||
|
|
||||||
return new DefaultRepositoryManager(contextProvider,
|
ScmConfiguration configuration = new ScmConfiguration();
|
||||||
|
|
||||||
|
return new DefaultRepositoryManager(configuration, contextProvider,
|
||||||
MockUtil.getAdminSecurityContextProvider(), repositoryDAO,
|
MockUtil.getAdminSecurityContextProvider(), repositoryDAO,
|
||||||
handlerSet, listenerProvider, hookProvider);
|
handlerSet, listenerProvider, hookProvider);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user