mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-12-24 09:19:51 +01:00
Merge with develop
This commit is contained in:
@@ -189,6 +189,14 @@ public class ScmConfiguration implements Configuration {
|
||||
@XmlElement(name = "xsrf-protection")
|
||||
private boolean enabledXsrfProtection = true;
|
||||
|
||||
/**
|
||||
* Enables user converter.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*/
|
||||
@XmlElement(name = "user-converter")
|
||||
private boolean enabledUserConverter = false;
|
||||
|
||||
@XmlElement(name = "namespace-strategy")
|
||||
private String namespaceStrategy = "UsernameNamespaceStrategy";
|
||||
|
||||
@@ -238,6 +246,7 @@ public class ScmConfiguration implements Configuration {
|
||||
this.loginInfoUrl = other.loginInfoUrl;
|
||||
this.releaseFeedUrl = other.releaseFeedUrl;
|
||||
this.mailDomainName = other.mailDomainName;
|
||||
this.enabledUserConverter = other.enabledUserConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,6 +396,17 @@ public class ScmConfiguration implements Configuration {
|
||||
return enabledXsrfProtection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the user converter is enabled.
|
||||
*
|
||||
* @return {@code true} if the user converter is enabled
|
||||
* The user converter automatically converts an internal user to external on their first login using an external system like ldap
|
||||
* @since 2.9.0
|
||||
*/
|
||||
public boolean isEnabledUserConverter() {
|
||||
return enabledUserConverter;
|
||||
}
|
||||
|
||||
public boolean isEnableProxy() {
|
||||
return enableProxy;
|
||||
}
|
||||
@@ -554,6 +574,16 @@ public class ScmConfiguration implements Configuration {
|
||||
this.enabledXsrfProtection = enabledXsrfProtection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set {@code true} to enable user converter.
|
||||
*
|
||||
* @param enabledUserConverter {@code true} to enable user converter
|
||||
* @since 2.9.0
|
||||
*/
|
||||
public void setEnabledUserConverter(boolean enabledUserConverter) {
|
||||
this.enabledUserConverter = enabledUserConverter;
|
||||
}
|
||||
|
||||
public void setNamespaceStrategy(String namespaceStrategy) {
|
||||
this.namespaceStrategy = namespaceStrategy;
|
||||
}
|
||||
|
||||
@@ -21,18 +21,20 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Objects;
|
||||
import sonia.scm.Validateable;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.io.Serializable;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
@@ -44,9 +46,14 @@ import java.io.Serializable;
|
||||
*/
|
||||
@XmlRootElement(name = "branch")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public final class Branch implements Serializable
|
||||
public final class Branch implements Serializable, Validateable
|
||||
{
|
||||
|
||||
private static final String VALID_CHARACTERS_AT_START_AND_END = "\\w-,;\\]{}@&+=$#`|<>";
|
||||
private static final String VALID_CHARACTERS = VALID_CHARACTERS_AT_START_AND_END + "/.";
|
||||
public static final String VALID_BRANCH_NAMES = "[" + VALID_CHARACTERS_AT_START_AND_END + "]([" + VALID_CHARACTERS + "]*[" + VALID_CHARACTERS_AT_START_AND_END + "])?";
|
||||
public static final Pattern VALID_BRANCH_NAME_PATTERN = Pattern.compile(VALID_BRANCH_NAMES);
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -4602244691711222413L;
|
||||
|
||||
@@ -83,6 +90,11 @@ public final class Branch implements Serializable
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return VALID_BRANCH_NAME_PATTERN.matcher(name).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
||||
@@ -34,6 +34,7 @@ import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.spi.RepositoryServiceProvider;
|
||||
import sonia.scm.repository.work.WorkdirProvider;
|
||||
import sonia.scm.security.Authentications;
|
||||
import sonia.scm.user.EMail;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -453,7 +454,8 @@ public final class RepositoryService implements Closeable {
|
||||
public Stream<ScmProtocol> getSupportedProtocols() {
|
||||
return protocolProviders.stream()
|
||||
.filter(protocolProvider -> protocolProvider.getType().equals(getRepository().getType()))
|
||||
.map(this::createProviderInstanceForRepository);
|
||||
.map(this::createProviderInstanceForRepository)
|
||||
.filter(protocol -> !Authentications.isAuthenticatedSubjectAnonymous() || protocol.isAnonymousEnabled());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "java:S3740"})
|
||||
|
||||
@@ -40,4 +40,11 @@ public interface ScmProtocol {
|
||||
* The URL to access the repository providing this protocol.
|
||||
*/
|
||||
String getUrl();
|
||||
|
||||
/**
|
||||
* Whether the protocol can be used as an anonymous user.
|
||||
*/
|
||||
default boolean isAnonymousEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,11 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.security;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
||||
import org.apache.shiro.subject.SimplePrincipalCollection;
|
||||
@@ -33,10 +34,14 @@ import sonia.scm.NotFoundException;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.plugin.Extension;
|
||||
import sonia.scm.user.ExternalUserConverter;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
import sonia.scm.web.security.AdministrationContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Helper class for syncing realms. The class should simplify the creation of realms, which are syncing authenticated
|
||||
* users with the local database.
|
||||
@@ -44,34 +49,49 @@ import sonia.scm.web.security.AdministrationContext;
|
||||
* @author Sebastian Sdorra
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Extension
|
||||
public final class SyncingRealmHelper {
|
||||
|
||||
private final AdministrationContext ctx;
|
||||
private final UserManager userManager;
|
||||
private final GroupManager groupManager;
|
||||
private final Set<ExternalUserConverter> externalUserConverters;
|
||||
|
||||
/**
|
||||
* Constructs a new SyncingRealmHelper.
|
||||
*
|
||||
* @param ctx administration context
|
||||
* @param userManager user manager
|
||||
* @param groupManager group manager
|
||||
* @param ctx administration context
|
||||
* @param userManager user manager
|
||||
* @param groupManager group manager
|
||||
* @param externalUserConverters global scm configuration
|
||||
*/
|
||||
@Inject
|
||||
public SyncingRealmHelper(AdministrationContext ctx, UserManager userManager, GroupManager groupManager) {
|
||||
public SyncingRealmHelper(AdministrationContext ctx, UserManager userManager, GroupManager groupManager, Set<ExternalUserConverter> externalUserConverters) {
|
||||
this.ctx = ctx;
|
||||
this.userManager = userManager;
|
||||
this.groupManager = groupManager;
|
||||
this.externalUserConverters = externalUserConverters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new SyncingRealmHelper.
|
||||
*
|
||||
* @param ctx administration context
|
||||
* @param userManager user manager
|
||||
* @param groupManager group manager
|
||||
* @deprecated Use {@link #SyncingRealmHelper(AdministrationContext, UserManager, GroupManager, Set)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public SyncingRealmHelper(AdministrationContext ctx, UserManager userManager, GroupManager groupManager) {
|
||||
this(ctx, userManager, groupManager, Collections.emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create {@link AuthenticationInfo} from user and groups.
|
||||
*
|
||||
*
|
||||
* @param realm name of the realm
|
||||
* @param user authenticated user
|
||||
*
|
||||
* @param user authenticated user
|
||||
* @return authentication info
|
||||
*/
|
||||
public AuthenticationInfo createAuthenticationInfo(String realm, User user) {
|
||||
@@ -91,17 +111,9 @@ public final class SyncingRealmHelper {
|
||||
public void store(final Group group) {
|
||||
ctx.runAsAdmin(() -> {
|
||||
if (groupManager.get(group.getId()) != null) {
|
||||
try {
|
||||
groupManager.modify(group);
|
||||
} catch (NotFoundException e) {
|
||||
throw new IllegalStateException("got NotFoundException though group " + group.getName() + " could be loaded", e);
|
||||
}
|
||||
modifyGroup(group);
|
||||
} else {
|
||||
try {
|
||||
groupManager.create(group);
|
||||
} catch (AlreadyExistsException e) {
|
||||
throw new IllegalStateException("got AlreadyExistsException though group " + group.getName() + " could not be loaded", e);
|
||||
}
|
||||
createNewGroup(group);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -114,19 +126,54 @@ public final class SyncingRealmHelper {
|
||||
public void store(final User user) {
|
||||
ctx.runAsAdmin(() -> {
|
||||
if (userManager.contains(user.getName())) {
|
||||
try {
|
||||
userManager.modify(user);
|
||||
} catch (NotFoundException e) {
|
||||
throw new IllegalStateException("got NotFoundException though user " + user.getName() + " could be loaded", e);
|
||||
}
|
||||
modifyUser(user);
|
||||
} else {
|
||||
try {
|
||||
userManager.create(user);
|
||||
} catch (AlreadyExistsException e) {
|
||||
throw new IllegalStateException("got AlreadyExistsException though user " + user.getName() + " could not be loaded", e);
|
||||
|
||||
}
|
||||
createNewUser(user);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createNewUser(User user) {
|
||||
try {
|
||||
User clone = user.clone();
|
||||
// New user created by syncing realm helper is always external
|
||||
clone.setExternal(true);
|
||||
userManager.create(clone);
|
||||
} catch (AlreadyExistsException e) {
|
||||
throw new IllegalStateException("got AlreadyExistsException though user " + user.getName() + " could not be loaded", e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void modifyUser(User user) {
|
||||
User clone = user.clone();
|
||||
if (!externalUserConverters.isEmpty()) {
|
||||
log.debug("execute available user converters");
|
||||
for (ExternalUserConverter converter : externalUserConverters) {
|
||||
clone = converter.convert(clone);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
userManager.modify(clone);
|
||||
} catch (NotFoundException e) {
|
||||
throw new IllegalStateException("got NotFoundException though user " + clone.getName() + " could be loaded", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void createNewGroup(Group group) {
|
||||
try {
|
||||
groupManager.create(group);
|
||||
} catch (AlreadyExistsException e) {
|
||||
throw new IllegalStateException("got AlreadyExistsException though group " + group.getName() + " could not be loaded", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void modifyGroup(Group group) {
|
||||
try {
|
||||
groupManager.modify(group);
|
||||
} catch (NotFoundException e) {
|
||||
throw new IllegalStateException("got NotFoundException though group " + group.getName() + " could be loaded", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package sonia.scm.user;
|
||||
|
||||
import sonia.scm.plugin.ExtensionPoint;
|
||||
|
||||
/**
|
||||
* The external user converter can be used to modify users
|
||||
* which are provided by external systems before creation in SCM-Manager.
|
||||
* The implementations will be called in the {@link sonia.scm.security.SyncingRealmHelper}
|
||||
* @since 2.9.0
|
||||
*/
|
||||
@ExtensionPoint
|
||||
public interface ExternalUserConverter {
|
||||
|
||||
/**
|
||||
* Returns the converted user.
|
||||
* @return converted user
|
||||
*/
|
||||
User convert(User user);
|
||||
}
|
||||
@@ -24,12 +24,14 @@
|
||||
|
||||
package sonia.scm.user;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.github.sdorra.ssp.PermissionObject;
|
||||
import com.github.sdorra.ssp.StaticPermissions;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Objects;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import sonia.scm.BasicPropertiesAware;
|
||||
import sonia.scm.ModelObject;
|
||||
import sonia.scm.ReducedModelObject;
|
||||
@@ -41,12 +43,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.security.Principal;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@StaticPermissions(
|
||||
value = "user",
|
||||
globalPermissions = {"create", "list", "autocomplete"},
|
||||
@@ -55,57 +51,42 @@ import java.security.Principal;
|
||||
)
|
||||
@XmlRootElement(name = "users")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class User extends BasicPropertiesAware implements Principal, ModelObject, PermissionObject, ReducedModelObject
|
||||
{
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class User extends BasicPropertiesAware implements Principal, ModelObject, PermissionObject, ReducedModelObject {
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -3089541936726329663L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
private boolean active = true;
|
||||
private boolean external;
|
||||
private Long creationDate;
|
||||
private String displayName;
|
||||
private Long lastModified;
|
||||
private String mail;
|
||||
private String name;
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
* The user type is replaced by {@link #external} flag
|
||||
* @deprecated Use {@link #external} instead.
|
||||
*/
|
||||
public User() {}
|
||||
@Deprecated
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public User(String name)
|
||||
{
|
||||
public User(String name) {
|
||||
this.name = name;
|
||||
this.displayName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
* @param displayName
|
||||
* @param mail
|
||||
*/
|
||||
public User(String name, String displayName, String mail)
|
||||
{
|
||||
public User(String name, String displayName, String mail) {
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.mail = mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
* @param displayName
|
||||
* @param mail
|
||||
*/
|
||||
public User(String name, String displayName, String mail, String password, String type, boolean active)
|
||||
{
|
||||
public User(String name, String displayName, String mail, String password, String type, boolean active) {
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.mail = mail;
|
||||
@@ -114,90 +95,57 @@ public class User extends BasicPropertiesAware implements Principal, ModelObject
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public User clone()
|
||||
{
|
||||
User user = null;
|
||||
public User clone() {
|
||||
User user;
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
user = (User) super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException ex)
|
||||
{
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param user
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean copyProperties(User user)
|
||||
{
|
||||
public boolean copyProperties(User user) {
|
||||
return copyProperties(user, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param user
|
||||
* @param copyPassword
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean copyProperties(User user, boolean copyPassword)
|
||||
{
|
||||
public boolean copyProperties(User user, boolean copyPassword) {
|
||||
boolean result = false;
|
||||
|
||||
if (user.isActive() != active)
|
||||
{
|
||||
if (user.isActive() != active) {
|
||||
result = true;
|
||||
user.setActive(active);
|
||||
}
|
||||
|
||||
if (Util.isNotEquals(user.getDisplayName(), displayName))
|
||||
{
|
||||
if (user.isExternal() != external) {
|
||||
result = true;
|
||||
user.setExternal(external);
|
||||
}
|
||||
|
||||
if (Util.isNotEquals(user.getDisplayName(), displayName)) {
|
||||
result = true;
|
||||
user.setDisplayName(displayName);
|
||||
}
|
||||
|
||||
if (Util.isNotEquals(user.getMail(), mail))
|
||||
{
|
||||
if (Util.isNotEquals(user.getMail(), mail)) {
|
||||
result = true;
|
||||
user.setMail(mail);
|
||||
}
|
||||
|
||||
if (Util.isNotEquals(user.getName(), name))
|
||||
{
|
||||
if (Util.isNotEquals(user.getName(), name)) {
|
||||
result = true;
|
||||
user.setName(name);
|
||||
}
|
||||
|
||||
if (copyPassword && Util.isNotEquals(user.getPassword(), password))
|
||||
{
|
||||
if (copyPassword && Util.isNotEquals(user.getPassword(), password)) {
|
||||
result = true;
|
||||
user.setPassword(password);
|
||||
}
|
||||
|
||||
if (Util.isNotEquals(user.getType(), type))
|
||||
{
|
||||
if (Util.isNotEquals(user.getType(), type)) {
|
||||
result = true;
|
||||
user.setType(type);
|
||||
}
|
||||
@@ -205,316 +153,65 @@ public class User extends BasicPropertiesAware implements Principal, ModelObject
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final User other = (User) obj;
|
||||
|
||||
return Objects.equal(name, other.name)
|
||||
&& Objects.equal(displayName, other.displayName)
|
||||
&& Objects.equal(mail, other.mail)
|
||||
&& Objects.equal(type, other.type)
|
||||
&& Objects.equal(active, other.active)
|
||||
&& Objects.equal(password, other.password)
|
||||
&& Objects.equal(creationDate, other.creationDate)
|
||||
&& Objects.equal(lastModified, other.lastModified)
|
||||
&& Objects.equal(properties, other.properties);
|
||||
&& Objects.equal(displayName, other.displayName)
|
||||
&& Objects.equal(mail, other.mail)
|
||||
&& Objects.equal(external, other.external)
|
||||
&& Objects.equal(active, other.active)
|
||||
&& Objects.equal(password, other.password)
|
||||
&& Objects.equal(creationDate, other.creationDate)
|
||||
&& Objects.equal(lastModified, other.lastModified)
|
||||
&& Objects.equal(properties, other.properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(name, displayName, mail, type, password,
|
||||
active, creationDate, lastModified, properties);
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(name, displayName, mail, password,
|
||||
active, external, creationDate, lastModified, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
String pwd = (password != null)
|
||||
? "(is set)"
|
||||
: "(not set)";
|
||||
? "(is set)"
|
||||
: "(not set)";
|
||||
|
||||
//J-
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.add("name", name)
|
||||
.add("displayName",displayName)
|
||||
.add("mail", mail)
|
||||
.add("password", pwd)
|
||||
.add("type", type)
|
||||
.add("active", active)
|
||||
.add("creationDate", creationDate)
|
||||
.add("lastModified", lastModified)
|
||||
.add("properties", properties)
|
||||
.toString();
|
||||
.add("name", name)
|
||||
.add("displayName", displayName)
|
||||
.add("mail", mail)
|
||||
.add("password", pwd)
|
||||
.add("type", type)
|
||||
.add("active", active)
|
||||
.add("external", external)
|
||||
.add("creationDate", creationDate)
|
||||
.add("lastModified", lastModified)
|
||||
.add("properties", properties)
|
||||
.toString();
|
||||
//J+
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Long getCreationDate()
|
||||
{
|
||||
return creationDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getDisplayName()
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getId()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Long getLastModified()
|
||||
{
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getMail()
|
||||
{
|
||||
return mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false if the user is deactivated.
|
||||
*
|
||||
*
|
||||
* @return false if the user is deactivated
|
||||
* @since 1.16
|
||||
*/
|
||||
public boolean isActive()
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
public boolean isValid() {
|
||||
return ValidationUtil.isNameValid(name) && Util.isNotEmpty(displayName)
|
||||
&& Util.isNotEmpty(type)
|
||||
&& ((Util.isEmpty(mail)) || ValidationUtil.isMailAddressValid(mail));
|
||||
&& ((Util.isEmpty(mail)) || ValidationUtil.isMailAddressValid(mail));
|
||||
}
|
||||
|
||||
//~--- set methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Activate or deactive this user.
|
||||
*
|
||||
*
|
||||
* @param active false to deactivate the user.
|
||||
* @since 1.6
|
||||
*/
|
||||
public void setActive(boolean active)
|
||||
{
|
||||
this.active = active;
|
||||
@Override
|
||||
public String getId() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param creationDate
|
||||
*/
|
||||
public void setCreationDate(Long creationDate)
|
||||
{
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param displayName
|
||||
*/
|
||||
public void setDisplayName(String displayName)
|
||||
{
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param lastModified
|
||||
*/
|
||||
public void setLastModified(Long lastModified)
|
||||
{
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param mail
|
||||
*/
|
||||
public void setMail(String mail)
|
||||
{
|
||||
this.mail = mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param password
|
||||
*/
|
||||
public void setPassword(String password)
|
||||
{
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
public void setType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private boolean active = true;
|
||||
|
||||
/** Field description */
|
||||
private Long creationDate;
|
||||
|
||||
/** Field description */
|
||||
private String displayName;
|
||||
|
||||
/** Field description */
|
||||
private Long lastModified;
|
||||
|
||||
/** Field description */
|
||||
private String mail;
|
||||
|
||||
/** Field description */
|
||||
private String name;
|
||||
|
||||
/** Field description */
|
||||
private String password;
|
||||
|
||||
/** Field description */
|
||||
private String type;
|
||||
}
|
||||
|
||||
@@ -21,23 +21,19 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.web;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The software agent that is acting on behalf of a user. The user agent
|
||||
* The software agent that is acting on behalf of a user. The user agent
|
||||
* represents a browser or one of the repository client (svn, git or hg).
|
||||
*
|
||||
* @author Sebastian Sdorra <s.sdorra@gmail.com>
|
||||
@@ -49,17 +45,16 @@ public final class UserAgent
|
||||
/**
|
||||
* Constructs a new user agent
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
* @param browser
|
||||
* @param name
|
||||
* @param basicAuthenticationCharset
|
||||
* @param browser
|
||||
*/
|
||||
private UserAgent(String name, boolean browser,
|
||||
Charset basicAuthenticationCharset)
|
||||
private UserAgent(String name, Charset basicAuthenticationCharset, boolean browser, boolean scmClient)
|
||||
{
|
||||
this.name = checkNotNull(name);
|
||||
this.browser = browser;
|
||||
this.basicAuthenticationCharset = checkNotNull(basicAuthenticationCharset);
|
||||
this.browser = browser;
|
||||
this.scmClient = scmClient;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
@@ -71,8 +66,30 @@ public final class UserAgent
|
||||
* @param name name of the UserAgent
|
||||
*
|
||||
* @return builder for UserAgent
|
||||
*
|
||||
* @deprecated Use {@link #browser(String)}, {@link #scmClient(String)} or {@link #other(String)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static Builder builder(String name)
|
||||
{
|
||||
return other(name);
|
||||
}
|
||||
|
||||
public static Builder browser(String name)
|
||||
{
|
||||
final Builder builder = new Builder(name);
|
||||
builder.browser = true;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static Builder scmClient(String name)
|
||||
{
|
||||
final Builder builder = new Builder(name);
|
||||
builder.scmClient = true;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static Builder other(String name)
|
||||
{
|
||||
return new Builder(name);
|
||||
}
|
||||
@@ -97,7 +114,7 @@ public final class UserAgent
|
||||
|
||||
return Objects.equal(name, other.name)
|
||||
&& Objects.equal(browser, other.browser)
|
||||
&& Objects.equal(basicAuthenticationCharset, basicAuthenticationCharset);
|
||||
&& Objects.equal(basicAuthenticationCharset, other.basicAuthenticationCharset);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,7 +144,7 @@ public final class UserAgent
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the {@link Charset}, which is used to decode the basic
|
||||
* Returns the {@link Charset}, which is used to decode the basic
|
||||
* authentication header.
|
||||
*
|
||||
* @return {@link Charset} for basic authentication
|
||||
@@ -152,13 +169,23 @@ public final class UserAgent
|
||||
* Returns {@code true} if UserAgent is a browser.
|
||||
*
|
||||
*
|
||||
* @return {@code true} if UserAgent is a browser
|
||||
* @return {@code true} if UserAgent is a browser
|
||||
*/
|
||||
public boolean isBrowser()
|
||||
{
|
||||
return browser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if UserAgent is an scm client (e.g. git, svn or hg).
|
||||
*
|
||||
*
|
||||
* @return {@code true} if UserAgent is an scm client
|
||||
*/
|
||||
public boolean isScmClient() {
|
||||
return scmClient;
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -204,7 +231,10 @@ public final class UserAgent
|
||||
* @param browser {@code true} for a browser
|
||||
*
|
||||
* @return {@code this}
|
||||
*
|
||||
* @deprecated Use {@link #browser(String)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder browser(boolean browser)
|
||||
{
|
||||
this.browser = browser;
|
||||
@@ -215,12 +245,11 @@ public final class UserAgent
|
||||
/**
|
||||
* Builds the {@link UserAgent}.
|
||||
*
|
||||
*
|
||||
* @return new {@link UserAgent}
|
||||
*/
|
||||
public UserAgent build()
|
||||
{
|
||||
return new UserAgent(name, browser, basicAuthenticationCharset);
|
||||
return new UserAgent(name, basicAuthenticationCharset, browser, scmClient);
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
@@ -229,10 +258,13 @@ public final class UserAgent
|
||||
private final String name;
|
||||
|
||||
/** indicator for browsers */
|
||||
private boolean browser = true;
|
||||
private boolean browser = false;
|
||||
|
||||
/** indicator for browsers */
|
||||
private boolean scmClient = false;
|
||||
|
||||
/** basic authentication charset */
|
||||
private Charset basicAuthenticationCharset = Charsets.ISO_8859_1;
|
||||
private Charset basicAuthenticationCharset = StandardCharsets.ISO_8859_1;
|
||||
}
|
||||
|
||||
|
||||
@@ -244,6 +276,9 @@ public final class UserAgent
|
||||
/** indicator for browsers */
|
||||
private final boolean browser;
|
||||
|
||||
/** indicator for scm clients (e.g. git, hg, svn) */
|
||||
private final boolean scmClient;
|
||||
|
||||
/** name of UserAgent */
|
||||
private final String name;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public final class UserAgentParser
|
||||
|
||||
/** unknown UserAgent */
|
||||
@VisibleForTesting
|
||||
static final UserAgent UNKNOWN = UserAgent.builder("UNKNOWN").build();
|
||||
static final UserAgent UNKNOWN = UserAgent.other("UNKNOWN").build();
|
||||
|
||||
/** logger */
|
||||
private static final Logger logger =
|
||||
|
||||
@@ -24,7 +24,15 @@
|
||||
|
||||
package sonia.scm.repository.api;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import sonia.scm.SCMContext;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.spi.HttpScmProtocol;
|
||||
@@ -42,16 +50,32 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.assertj.core.util.IterableUtil.sizeOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class RepositoryServiceTest {
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class RepositoryServiceTest {
|
||||
|
||||
private final RepositoryServiceProvider provider = mock(RepositoryServiceProvider.class);
|
||||
private final Repository repository = new Repository("", "git", "space", "repo");
|
||||
|
||||
private final EMail eMail = new EMail(new ScmConfiguration());
|
||||
|
||||
@Mock
|
||||
private Subject subject;
|
||||
|
||||
@BeforeEach
|
||||
void bindSubject() {
|
||||
ThreadContext.bind(subject);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void unbindSubject() {
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnMatchingProtocolsFromProvider() {
|
||||
void shouldReturnMatchingProtocolsFromProvider() {
|
||||
when(subject.getPrincipal()).thenReturn("Hitchhiker");
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
Stream<ScmProtocol> supportedProtocols = repositoryService.getSupportedProtocols();
|
||||
|
||||
@@ -59,7 +83,17 @@ public class RepositoryServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindKnownProtocol() {
|
||||
void shouldFilterOutNonAnonymousEnabledProtocolsForAnonymousUser() {
|
||||
when(subject.getPrincipal()).thenReturn(SCMContext.USER_ANONYMOUS);
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Stream.of(new DummyScmProtocolProvider(), new DummyScmProtocolProvider(false)).collect(Collectors.toSet()), null, eMail);
|
||||
Stream<ScmProtocol> supportedProtocols = repositoryService.getSupportedProtocols();
|
||||
|
||||
assertThat(sizeOf(supportedProtocols.collect(Collectors.toList()))).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFindKnownProtocol() {
|
||||
when(subject.getPrincipal()).thenReturn("Hitchhiker");
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
|
||||
HttpScmProtocol protocol = repositoryService.getProtocol(HttpScmProtocol.class);
|
||||
@@ -68,23 +102,44 @@ public class RepositoryServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailForUnknownProtocol() {
|
||||
void shouldFailForUnknownProtocol() {
|
||||
when(subject.getPrincipal()).thenReturn("Hitchhiker");
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> repositoryService.getProtocol(UnknownScmProtocol.class));
|
||||
}
|
||||
|
||||
private static class DummyHttpProtocol extends HttpScmProtocol {
|
||||
public DummyHttpProtocol(Repository repository) {
|
||||
|
||||
private final boolean anonymousEnabled;
|
||||
|
||||
public DummyHttpProtocol(Repository repository, boolean anonymousEnabled) {
|
||||
super(repository, "");
|
||||
this.anonymousEnabled = anonymousEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serve(HttpServletRequest request, HttpServletResponse response, Repository repository, ServletConfig config) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnonymousEnabled() {
|
||||
return anonymousEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
private static class DummyScmProtocolProvider implements ScmProtocolProvider {
|
||||
|
||||
private final boolean anonymousEnabled;
|
||||
|
||||
public DummyScmProtocolProvider() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public DummyScmProtocolProvider(boolean anonymousEnabled) {
|
||||
this.anonymousEnabled = anonymousEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "git";
|
||||
@@ -92,9 +147,10 @@ public class RepositoryServiceTest {
|
||||
|
||||
@Override
|
||||
public ScmProtocol get(Repository repository) {
|
||||
return new DummyHttpProtocol(repository);
|
||||
return new DummyHttpProtocol(repository, anonymousEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
private interface UnknownScmProtocol extends ScmProtocol {}
|
||||
private interface UnknownScmProtocol extends ScmProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,15 +27,18 @@ package sonia.scm.security;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.AlreadyExistsException;
|
||||
import sonia.scm.group.Group;
|
||||
import sonia.scm.group.GroupManager;
|
||||
import sonia.scm.user.ExternalUserConverter;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
import sonia.scm.web.security.AdministrationContext;
|
||||
@@ -46,7 +49,9 @@ import java.io.IOException;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -68,8 +73,13 @@ public class SyncingRealmHelperTest {
|
||||
@Mock
|
||||
private UserManager userManager;
|
||||
|
||||
@Mock
|
||||
private ExternalUserConverter converter;
|
||||
|
||||
private SyncingRealmHelper helper;
|
||||
|
||||
private SyncingRealmHelper helperWithConverters;
|
||||
|
||||
/**
|
||||
* Mock {@link AdministrationContext} and create object under test.
|
||||
*/
|
||||
@@ -94,6 +104,7 @@ public class SyncingRealmHelperTest {
|
||||
};
|
||||
|
||||
helper = new SyncingRealmHelper(ctx, userManager, groupManager);
|
||||
helperWithConverters = new SyncingRealmHelper(ctx, userManager, groupManager, ImmutableSet.of(converter));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,10 +151,15 @@ public class SyncingRealmHelperTest {
|
||||
*/
|
||||
@Test
|
||||
public void testStoreUserCreate() {
|
||||
ArgumentCaptor<User> userArgumentCaptor = ArgumentCaptor.forClass(User.class);
|
||||
User user = new User("tricia");
|
||||
|
||||
helper.store(user);
|
||||
verify(userManager, times(1)).create(user);
|
||||
verify(userManager, times(1)).create(userArgumentCaptor.capture());
|
||||
|
||||
User value = userArgumentCaptor.getValue();
|
||||
assertEquals(user.getDisplayName(), value.getDisplayName());
|
||||
assertEquals(user.getName(), value.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,9 +167,10 @@ public class SyncingRealmHelperTest {
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testStoreUserFailure() {
|
||||
ArgumentCaptor<User> userArgumentCaptor = ArgumentCaptor.forClass(User.class);
|
||||
User user = new User("tricia");
|
||||
|
||||
doThrow(AlreadyExistsException.class).when(userManager).create(user);
|
||||
doThrow(AlreadyExistsException.class).when(userManager).create(userArgumentCaptor.capture());
|
||||
helper.store(user);
|
||||
}
|
||||
|
||||
@@ -170,6 +187,23 @@ public class SyncingRealmHelperTest {
|
||||
verify(userManager, times(1)).modify(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests {@link SyncingRealmHelper#store(User)} with an existing user.
|
||||
*/
|
||||
@Test
|
||||
public void testConvertUser(){
|
||||
User zaphod = new User("zaphod");
|
||||
when(converter.convert(any())).thenReturn(zaphod);
|
||||
when(userManager.contains("tricia")).thenReturn(Boolean.TRUE);
|
||||
|
||||
User user = new User("tricia");
|
||||
|
||||
helperWithConverters.store(user);
|
||||
|
||||
verify(converter).convert(user);
|
||||
verify(userManager, times(1)).modify(zaphod);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void builderShouldSetValues() {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.web;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
@@ -89,7 +89,7 @@ public class UserAgentParserTest
|
||||
UserAgent ua = parser.parse(UA_1);
|
||||
|
||||
assertEquals(Charsets.ISO_8859_1, ua.getBasicAuthenticationCharset());
|
||||
assertTrue(ua.isBrowser());
|
||||
assertFalse(ua.isBrowser());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,11 +99,11 @@ public class UserAgentParserTest
|
||||
@Test
|
||||
public void testParse()
|
||||
{
|
||||
UserAgent ua = UserAgent.builder("UA1").build();
|
||||
UserAgent ua = UserAgent.other("UA1").build();
|
||||
|
||||
when(provider1.parseUserAgent(UA_1)).thenReturn(ua);
|
||||
|
||||
UserAgent ua2 = UserAgent.builder("UA2").build();
|
||||
UserAgent ua2 = UserAgent.other("UA2").build();
|
||||
|
||||
when(provider2.parseUserAgent(UA_2)).thenReturn(ua2);
|
||||
|
||||
@@ -120,7 +120,7 @@ public class UserAgentParserTest
|
||||
{
|
||||
when(request.getHeader(HttpUtil.HEADER_USERAGENT)).thenReturn(UA_2);
|
||||
|
||||
UserAgent ua = UserAgent.builder("UA2").build();
|
||||
UserAgent ua = UserAgent.other("UA2").build();
|
||||
|
||||
when(provider1.parseUserAgent(UA_2)).thenReturn(ua);
|
||||
assertEquals(ua, parser.parse(request));
|
||||
@@ -144,7 +144,7 @@ public class UserAgentParserTest
|
||||
@Test
|
||||
public void testParseWithCache()
|
||||
{
|
||||
UserAgent ua = UserAgent.builder("UA").build();
|
||||
UserAgent ua = UserAgent.other("UA").build();
|
||||
|
||||
when(cache.get(UA_1)).thenReturn(ua);
|
||||
assertEquals(ua, parser.parse(UA_1));
|
||||
|
||||
@@ -69,8 +69,8 @@ class HttpProtocolServletAuthenticationFilterBaseTest {
|
||||
@Mock
|
||||
private FilterChain filterChain;
|
||||
|
||||
private UserAgent nonBrowser = UserAgent.builder("i'm not a browser").browser(false).build();
|
||||
private UserAgent browser = UserAgent.builder("i am a browser").browser(true).build();
|
||||
private UserAgent nonBrowser = UserAgent.other("i'm not a browser").build();
|
||||
private UserAgent browser = UserAgent.browser("i am a browser").build();
|
||||
|
||||
@BeforeEach
|
||||
void setUpObjectUnderTest() {
|
||||
|
||||
Reference in New Issue
Block a user