Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.util.Optional;
import java.util.Set;

import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xwiki.component.annotation.Component;
Expand Down Expand Up @@ -85,7 +84,7 @@ public Map<String, String> activateAccount(String activationCode)
.filter(not(User::isSuspended));
LOGGER.debug("activateAccount: user = {}", user);
if (user.isPresent()) {
String password = RandomStringUtils.randomAlphanumeric(24);
String password = SecureRandomUtils.randomAlphanumeric(24);
enableUser(user.get(), password, true);
Map<String, String> userAccount = new HashMap<>();
userAccount.put("username", modelUtils.serializeRefLocal(user.get().getDocRef()));
Expand Down Expand Up @@ -148,7 +147,7 @@ public String getUniqueValidationKey() throws QueryException {
Query.XWQL).<String>execute());
String validkey;
do {
validkey = RandomStringUtils.randomAlphanumeric(24);
validkey = SecureRandomUtils.randomAlphanumeric(24);
} while (existingKeys.contains(validkey));
return validkey;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.celements.auth;

import static com.google.common.base.Preconditions.*;
import static com.xpn.xwiki.XWikiConstant.*;
import static java.util.function.Predicate.*;

import java.util.Optional;

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.context.annotation.Configuration;
import org.xwiki.configuration.ConfigurationSource;
import org.xwiki.model.reference.DocumentReference;

import com.celements.model.util.ModelUtils;
import com.celements.servlet.NodeConfig.NodeIdentity;
import com.xpn.xwiki.user.api.XWikiUser;

@Configuration
public class MainAdminConfig {

static final String CFG_KEY_AUTOLOGIN = "main.admin.autologin";
static final String CFG_KEY_PASSWORD = "main.admin.password";

public static final DocumentReference USER_DOC_REF =
new DocumentReference(MAIN_WIKI.getName(), XWIKI_SPACE, "Admin");

private final ConfigurationSource configSource;
private final NodeIdentity nodeIdentity;
private final ModelUtils modelUtils;

@Inject
public MainAdminConfig(
@Named("xwikiproperties") ConfigurationSource configSource,
NodeIdentity nodeIdentity,
ModelUtils modelUtils) {
this.configSource = configSource;
this.nodeIdentity = nodeIdentity;
this.modelUtils = modelUtils;
isAutoLoginEnabled();
}

public DocumentReference getUserDocRef() {
return USER_DOC_REF;
}

public XWikiUser getXWikiUser() {
return new XWikiUser(modelUtils.serializeRef(USER_DOC_REF), true);
}

public Optional<String> getPassword() {
return Optional.ofNullable(configSource.getProperty(CFG_KEY_PASSWORD, ""))
.map(String::trim)
.filter(not(String::isEmpty));
}

public boolean isAutoLoginEnabled() {
var enabled = configSource.getProperty(CFG_KEY_AUTOLOGIN, false);
checkState(!enabled || "local".equals(nodeIdentity.clusterName()),
"Admin auto-login requires CLUSTER_NAME=local");
return enabled;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.celements.auth;

import java.security.SecureRandom;

import org.apache.commons.lang.RandomStringUtils;

public final class SecureRandomUtils {

private static final SecureRandom RANDOM = new SecureRandom();

private SecureRandomUtils() {}

public static String randomAlphanumeric(int length) {
return RandomStringUtils.random(length, 0, 0, true, true, null, RANDOM);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import javax.inject.Named;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -37,6 +36,7 @@
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryManager;

import com.celements.auth.SecureRandomUtils;
import com.celements.init.XWikiProvider;
import com.celements.marshalling.ReferenceMarshaller;
import com.celements.model.access.IModelAccessFacade;
Expand Down Expand Up @@ -217,7 +217,7 @@ void fillInUserData(XWikiDocument userDoc, Map<String, String> userData)
throws DocumentAccessException {
userData.putIfAbsent(XWikiUsersClass.FIELD_ACTIVE.getName(), "0");
userData.putIfAbsent(XWikiUsersClass.FIELD_PASSWORD.getName(),
RandomStringUtils.randomAlphanumeric(24));
SecureRandomUtils.randomAlphanumeric(24));
try {
BaseObject userObject = XWikiObjectEditor.on(userDoc).filter(usersClass).createFirst();
xwiki.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import javax.inject.Inject;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang.RandomStringUtils;
import org.springframework.stereotype.Component;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.observation.event.Event;

import com.celements.auth.SecureRandomUtils;
import com.celements.auth.user.UserPageType;
import com.celements.common.observation.listener.AbstractLocalEventListener;
import com.celements.model.object.xwiki.XWikiObjectEditor;
Expand Down Expand Up @@ -93,7 +93,7 @@ void setDefaultValuesOnNewUser(XWikiDocument userDoc) {
.filter(XWikiUsersClass.CLASS_REF)
.filterAbsent(XWikiUsersClass.FIELD_PASSWORD)
.editField(XWikiUsersClass.FIELD_PASSWORD)
.first(RandomStringUtils.randomAlphanumeric(24));
.first(SecureRandomUtils.randomAlphanumeric(24));
}

private XWikiUser asXWikiUser(DocumentReference userDocRef) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.celements.mandatory;

import static com.celements.common.lambda.LambdaExceptionUtil.*;
import static java.util.function.Predicate.*;
import static com.xpn.xwiki.XWikiConstant.*;

import java.util.List;
import java.util.Optional;

import javax.inject.Inject;

Expand All @@ -15,20 +13,17 @@
import org.xwiki.model.reference.DocumentReference;

import com.celements.auth.AuthenticationService;
import com.celements.auth.MainAdminConfig;
import com.celements.auth.SecureRandomUtils;
import com.celements.auth.user.UserInstantiationException;
import com.celements.auth.user.UserService;
import com.celements.model.access.exception.DocumentSaveException;
import com.celements.model.reference.RefBuilder;
import com.xpn.xwiki.XWikiConstant;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;

@Component("celements.mandatory.MainAdminUser")
public class MainAdminUser extends AbstractMandatoryDocument {

public static final String ADMIN_DOC_NAME = "Admin";
public static final String CFG_KEY_ADMIN_PASSWORD = "main.admin.password";

private static final Logger LOGGER = LoggerFactory.getLogger(MainAdminUser.class);

@Inject
Expand All @@ -37,6 +32,9 @@ public class MainAdminUser extends AbstractMandatoryDocument {
@Inject
private AuthenticationService authService;

@Inject
private MainAdminConfig config;

@Override
public String getName() {
return "MainAdminUser";
Expand All @@ -51,12 +49,12 @@ public List<String> dependsOnMandatoryDocuments() {

@Override
protected DocumentReference getDocRef() {
return getAdminUserDocRef();
return config.getUserDocRef();
}

@Override
protected boolean isEnabledByDefault() {
return getAdminPassword().isPresent();
return config.isAutoLoginEnabled() || config.getPassword().isPresent();
}

@Override
Expand All @@ -72,31 +70,20 @@ protected boolean checkDocuments(XWikiDocument doc) throws XWikiException {
@Override
protected boolean checkDocumentsMain(XWikiDocument doc) throws XWikiException {
try {
var adminUser = userService.getUser(getAdminUserDocRef());
getAdminPassword().ifPresent(rethrowConsumer(password -> authService
.enableUser(adminUser, password, false)));
var adminUser = userService.getUser(config.getUserDocRef());
if (isEnabledByDefault()) {
var password = config.getPassword().orElseGet(() -> SecureRandomUtils.randomAlphanumeric(24));
authService.enableUser(adminUser, password, false);
}
userService.addUserToGroup(adminUser, getAdminGroupRef());
return false; // safe already handled
} catch (UserInstantiationException | DocumentSaveException exc) {
throw new XWikiException(0, 0, "Admin user document not found", exc);
}
}

Optional<String> getAdminPassword() {
String password = xwikiPropConfigSource.getProperty(CFG_KEY_ADMIN_PASSWORD, "");
return Optional.ofNullable(password).map(String::trim).filter(not(String::isEmpty));
}

private DocumentReference getAdminUserDocRef() {
return new RefBuilder()
.with(modelContext.getWikiRef())
.space(XWikiConstant.XWIKI_SPACE)
.doc(ADMIN_DOC_NAME)
.build(DocumentReference.class);
}

private ClassReference getAdminGroupRef() {
return new ClassReference(XWikiConstant.XWIKI_SPACE, "XWikiAdminGroup");
return new ClassReference(XWIKI_SPACE, "XWikiAdminGroup");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,27 @@

import static com.celements.common.lambda.LambdaExceptionUtil.*;
import static com.celements.logging.LogUtils.*;
import static com.celements.spring.context.SpringContextProvider.*;
import static com.google.common.base.Strings.*;
import static com.google.common.collect.ImmutableList.*;
import static com.xpn.xwiki.user.api.XWikiRightService.*;
import static java.util.Arrays.*;

import java.security.Principal;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

import org.securityfilter.realm.SimplePrincipal;
import org.xwiki.model.reference.DocumentReference;

import com.celements.auth.MainAdminConfig;
import com.celements.auth.user.User;
import com.celements.auth.user.UserInstantiationException;
import com.celements.auth.user.UserService;
import com.celements.model.util.ModelUtils;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
Expand All @@ -47,19 +53,44 @@

public class TokenLDAPAuthServiceImpl extends XWikiLDAPAuthServiceImpl {

private final Supplier<MainAdminConfig> mainAdminCfg = Suppliers.memoize(
() -> getSpringContext().getBean(MainAdminConfig.class));

@Override
public XWikiUser checkAuth(XWikiContext context) throws XWikiException {
if ((context.getResponse() != null) && !"".equals(context.getWiki().Param("celements.auth.P3P",
""))) {
context.getResponse().addHeader("P3P", "CP=\"" + context.getWiki().Param("celements.auth.P3P")
+ "\"");
}
return Optional.ofNullable(checkAuthByToken(context)
.orElseGet(rethrowSupplier(() -> super.checkAuth(context))))
return autoLogin()
.or(rethrowSupplier(() -> checkAuthByToken(context)))
.or(rethrowSupplier(() -> Optional.ofNullable(super.checkAuth(context))))
.filter(this::isNotSuspended)
.orElse(null);
}

@Override
public XWikiUser checkAuth(String username, String password, String rememberme,
XWikiContext context) throws XWikiException {
return autoLogin().orElseGet(rethrowSupplier(() -> super
.checkAuth(username, password, rememberme, context)));
}

@Override
public Principal authenticate(String username, String password, XWikiContext context)
throws XWikiException {
return autoLogin()
.<Principal>map(x -> new SimplePrincipal(x.getUser()))
.orElseGet(rethrowSupplier(() -> super.authenticate(username, password, context)));
}

private Optional<XWikiUser> autoLogin() {
return mainAdminCfg.get().isAutoLoginEnabled()
? Optional.of(mainAdminCfg.get().getXWikiUser())
: Optional.empty();
}

private boolean isNotSuspended(XWikiUser xUser) {
try {
if (xUser.getUser().equals(SUPERADMIN_USER_FULLNAME)
Expand Down
Loading