Further progress on Exec Identity Store

This commit is contained in:
Max Dor
2018-10-29 07:00:07 +01:00
parent b881f73798
commit 026a2e82d9
14 changed files with 534 additions and 65 deletions

View File

@@ -28,7 +28,9 @@ import io.kamax.mxisd.UserID;
import io.kamax.mxisd.UserIdType;
import io.kamax.mxisd.auth.provider.AuthenticatorProvider;
import io.kamax.mxisd.config.ExecConfig;
import io.kamax.mxisd.exception.ConfigurationException;
import io.kamax.mxisd.exception.InternalServerError;
import io.kamax.mxisd.util.TriFunction;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -42,6 +44,8 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeoutException;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@Component
@@ -49,11 +53,74 @@ public class ExecAuthStore extends ExecStore implements AuthenticatorProvider {
private final transient Logger log = LoggerFactory.getLogger(ExecAuthStore.class);
private Map<String, Supplier<String>> inputTemplates;
private Map<String, BiConsumer<String, ExecAuthResult>> outputMapper;
private TriFunction<String, _MatrixID, String, String> inputMapper;
private ExecConfig.Auth cfg;
@Autowired
public ExecAuthStore(ExecConfig cfg) {
this.cfg = Objects.requireNonNull(cfg.getAuth());
inputTemplates = new HashMap<>();
inputTemplates.put(JsonType, () -> {
JsonObject json = new JsonObject();
json.addProperty("localpart", cfg.getToken().getLocalpart());
json.addProperty("domain", cfg.getToken().getDomain());
json.addProperty("mxid", cfg.getToken().getMxid());
json.addProperty("password", cfg.getToken().getPassword());
return GsonUtil.get().toJson(json);
});
inputTemplates.put(MultilinesType, () -> cfg.getToken().getLocalpart() + System.lineSeparator() +
cfg.getToken().getDomain() + System.lineSeparator() +
cfg.getToken().getMxid() + System.lineSeparator() +
cfg.getToken().getPassword() + System.lineSeparator()
);
inputMapper = (input, uId, password) -> input.replace(cfg.getToken().getLocalpart(), uId.getLocalPart())
.replace(cfg.getToken().getDomain(), uId.getDomain())
.replace(cfg.getToken().getMxid(), uId.getId())
.replace(cfg.getToken().getPassword(), password);
outputMapper = new HashMap<>();
outputMapper.put(JsonType, (output, result) -> {
JsonObject data = GsonUtil.getObj(GsonUtil.parseObj(output), "auth");
GsonUtil.findPrimitive(data, "success")
.map(JsonPrimitive::getAsBoolean)
.ifPresent(result::setSuccess);
GsonUtil.findObj(data, "profile")
.flatMap(p -> GsonUtil.findString(p, "display_name"))
.ifPresent(v -> result.getProfile().setDisplayName(v));
});
outputMapper.put(MultilinesType, (output, result) -> {
String[] lines = output.split("\\R");
if (lines.length > 2) {
throw new InternalServerError("Exec auth command returned more than 2 lines (" + lines.length + ")");
}
result.setSuccess(Optional.ofNullable(StringUtils.isEmpty(lines[0]) ? null : lines[0])
.map(v -> StringUtils.equalsAnyIgnoreCase(v, "true", "1"))
.orElse(result.isSuccess()));
if (lines.length == 2) {
Optional.ofNullable(StringUtils.isEmpty(lines[1]) ? null : lines[1])
.ifPresent(v -> result.getProfile().setDisplayName(v));
}
});
validateConfig();
}
private void validateConfig() {
if (StringUtils.isNotEmpty(cfg.getInput().getType()) && !inputTemplates.containsKey(cfg.getInput().getType())) {
throw new ConfigurationException("Exec Auth input type is not valid: " + cfg.getInput().getType());
}
if (StringUtils.isNotEmpty(cfg.getOutput().getType()) && !outputMapper.containsKey(cfg.getOutput().getType())) {
throw new ConfigurationException("Exec Auth output type is not valid: " + cfg.getInput().getType());
}
}
@Override
@@ -75,31 +142,17 @@ public class ExecAuthStore extends ExecStore implements AuthenticatorProvider {
List<String> args = new ArrayList<>();
args.add(cfg.getCommand());
args.addAll(cfg.getArgs().stream().map(arg -> arg
.replace(cfg.getToken().getLocalpart(), uId.getLocalPart())
.replace(cfg.getToken().getDomain(), uId.getDomain())
.replace(cfg.getToken().getMxid(), uId.getId())
.replace(cfg.getToken().getPassword(), password)
).collect(Collectors.toList()));
args.addAll(cfg.getArgs().stream().map(arg -> inputMapper.apply(arg, uId, password)).collect(Collectors.toList()));
psExec.command(args);
psExec.environment(new HashMap<>(cfg.getEnv()).entrySet().stream().peek(e -> {
e.setValue(e.getValue().replace(cfg.getToken().getLocalpart(), uId.getLocalPart()));
e.setValue(e.getValue().replace(cfg.getToken().getDomain(), uId.getDomain()));
e.setValue(e.getValue().replace(cfg.getToken().getMxid(), uId.getId()));
e.setValue(e.getValue().replace(cfg.getToken().getPassword(), password));
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
psExec.environment(new HashMap<>(cfg.getEnv()).entrySet().stream()
.peek(e -> e.setValue(inputMapper.apply(e.getValue(), uId, password)))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
if (StringUtils.isNotBlank(cfg.getInput())) {
if (StringUtils.equals("json", cfg.getInput())) {
JsonObject input = new JsonObject();
input.addProperty("localpart", uId.getLocalPart());
input.addProperty("mxid", uId.getId());
input.addProperty("password", password);
psExec.redirectInput(IOUtils.toInputStream(GsonUtil.get().toJson(input), StandardCharsets.UTF_8));
} else {
throw new InternalServerError(cfg.getInput() + " is not a valid executable input format");
}
if (StringUtils.isNotBlank(cfg.getInput().getType())) {
String template = cfg.getInput().getTemplate().orElseGet(inputTemplates.get(cfg.getInput().getType()));
String input = inputMapper.apply(template, uId, password);
psExec.redirectInput(IOUtils.toInputStream(input, StandardCharsets.UTF_8));
}
try {
@@ -107,28 +160,23 @@ public class ExecAuthStore extends ExecStore implements AuthenticatorProvider {
ProcessResult psResult = psExec.execute();
result.setExitStatus(psResult.getExitValue());
String output = psResult.outputUTF8();
log.debug("Command output:{}{}", System.lineSeparator(), output);
log.info("Exit status: {}", result.getExitStatus());
if (cfg.getExit().getSuccess().contains(result.getExitStatus())) {
result.setSuccess(true);
if (result.isSuccess()) {
if (StringUtils.equals("json", cfg.getOutput())) {
JsonObject data = GsonUtil.parseObj(output);
GsonUtil.findPrimitive(data, "success")
.map(JsonPrimitive::getAsBoolean)
.ifPresent(result::setSuccess);
GsonUtil.findObj(data, "profile")
.flatMap(p -> GsonUtil.findString(p, "display_name"))
.ifPresent(v -> result.getProfile().setDisplayName(v));
} else {
log.debug("Command output:{}{}", "\n", output);
if (result.isSuccess() && StringUtils.isNotEmpty(output)) {
outputMapper.get(cfg.getOutput().getType()).accept(output, result);
} else {
if (StringUtils.isNotEmpty(output)) {
log.info("Exec auth failed with output:{}{}", System.lineSeparator(), output);
}
}
} else if (cfg.getExit().getFailure().contains(result.getExitStatus())) {
log.debug("{} stdout:{}{}", cfg.getCommand(), "\n", output);
log.debug("{} stdout:{}{}", cfg.getCommand(), System.lineSeparator(), output);
result.setSuccess(false);
} else {
log.error("{} stdout:{}{}", cfg.getCommand(), "\n", output);
log.error("{} stdout:{}{}", cfg.getCommand(), System.lineSeparator(), output);
throw new InternalServerError("Exec auth command returned with unexpected exit status");
}

View File

@@ -20,17 +20,26 @@
package io.kamax.mxisd.backend.exec;
import io.kamax.mxisd.config.ExecConfig;
import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult;
import io.kamax.mxisd.directory.IDirectoryProvider;
import io.kamax.mxisd.exception.NotImplementedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ExecDirectoryStore extends ExecStore implements IDirectoryProvider {
private ExecConfig.Directory cfg;
@Autowired
public ExecDirectoryStore(ExecConfig cfg) {
this.cfg = cfg.getDirectory();
}
@Override
public boolean isEnabled() {
return false;
return cfg.isEnabled();
}
@Override

View File

@@ -20,22 +20,129 @@
package io.kamax.mxisd.backend.exec;
import com.google.gson.JsonObject;
import io.kamax.matrix.MatrixID;
import io.kamax.matrix._MatrixID;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.mxisd.config.ExecConfig;
import io.kamax.mxisd.config.MatrixConfig;
import io.kamax.mxisd.exception.ConfigurationException;
import io.kamax.mxisd.exception.InternalServerError;
import io.kamax.mxisd.exception.NotImplementedException;
import io.kamax.mxisd.lookup.SingleLookupReply;
import io.kamax.mxisd.lookup.SingleLookupRequest;
import io.kamax.mxisd.lookup.ThreePidMapping;
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zeroturnaround.exec.ProcessExecutor;
import org.zeroturnaround.exec.ProcessResult;
import java.util.List;
import java.util.Optional;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeoutException;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@Component
public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
private final Logger log = LoggerFactory.getLogger(ExecIdentityStore.class);
private final ExecConfig.Identity cfg;
private final MatrixConfig mxCfg;
private BiFunction<String, SingleLookupRequest, String> singleInputMap;
private Map<String, Supplier<String>> singleInputTemplates;
private Map<String, Function<String, Optional<_MatrixID>>> singleOutputMap;
@Autowired
public ExecIdentityStore(ExecConfig cfg, MatrixConfig mxCfg) {
this.cfg = cfg.getIdentity();
this.mxCfg = mxCfg;
singleInputMap = (v, request) -> v.replace(cfg.getToken().getMedium(), request.getType())
.replace(cfg.getToken().getAddress(), request.getThreePid());
singleInputTemplates = new HashMap<>();
singleInputTemplates.put(JsonType, () -> {
JsonObject json = new JsonObject();
json.addProperty("medium", cfg.getToken().getMedium());
json.addProperty("address", cfg.getToken().getAddress());
return GsonUtil.get().toJson(json);
});
singleInputTemplates.put(MultilinesType, () -> cfg.getToken().getMedium()
+ System.lineSeparator()
+ cfg.getToken().getAddress()
);
singleOutputMap = new HashMap<>();
singleOutputMap.put(JsonType, output -> {
if (StringUtils.isBlank(output)) {
return Optional.empty();
}
return GsonUtil.findObj(GsonUtil.parseObj(output), "lookup").map(lookup -> {
String type = GsonUtil.getStringOrThrow(lookup, "type");
String value = GsonUtil.getStringOrThrow(lookup, "value");
if (StringUtils.equals(type, "uid")) {
return MatrixID.asAcceptable(value, mxCfg.getDomain());
}
if (StringUtils.equals(type, "mxid")) {
return MatrixID.asAcceptable(value);
}
throw new InternalServerError("Invalid user type: " + type);
});
});
singleOutputMap.put(MultilinesType, output -> {
String[] lines = output.split("\\R");
if (lines.length > 2) {
throw new InternalServerError("Exec auth command returned more than 2 lines (" + lines.length + ")");
}
if (lines.length == 1 && StringUtils.isBlank(lines[0])) {
return Optional.empty();
}
String type = StringUtils.trimToEmpty(lines.length == 1 ? "uid" : lines[0]);
String value = StringUtils.trimToEmpty(lines.length == 2 ? lines[1] : lines[0]);
if (StringUtils.equals(type, "uid")) {
return Optional.of(MatrixID.asAcceptable(value, mxCfg.getDomain()));
}
if (StringUtils.equals(type, "mxid")) {
return Optional.of(MatrixID.asAcceptable(value));
}
throw new InternalServerError("Invalid user type: " + type);
});
validateConfig();
}
private void validateConfig() {
if (StringUtils.isNotEmpty(cfg.getInput().getType()) && !singleInputTemplates.containsKey(cfg.getInput().getType())) {
throw new ConfigurationException("Exec Identity Single Lookup: input type is not valid: " + cfg.getInput().getType());
}
if (StringUtils.isNotEmpty(cfg.getOutput().getType()) && !singleOutputMap.containsKey(cfg.getOutput().getType())) {
throw new ConfigurationException("Exec Auth output type is not valid: " + cfg.getInput().getType());
}
}
@Override
public boolean isEnabled() {
return false;
return cfg.isEnabled();
}
@Override
@@ -45,12 +152,53 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
@Override
public int getPriority() {
return 0;
return cfg.getPriority();
}
@Override
public Optional<SingleLookupReply> find(SingleLookupRequest request) {
throw new NotImplementedException(this.getClass().getName());
ProcessExecutor psExec = new ProcessExecutor().readOutput(true);
List<String> args = new ArrayList<>();
args.add(cfg.getCommand());
args.addAll(cfg.getArgs().stream().map(arg -> singleInputMap.apply(arg, request)).collect(Collectors.toList()));
psExec.command(args);
psExec.environment(new HashMap<>(cfg.getEnv()).entrySet().stream()
.peek(e -> e.setValue(singleInputMap.apply(e.getValue(), request)))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
if (StringUtils.isNotBlank(cfg.getInput().getType())) {
String template = cfg.getInput().getTemplate().orElseGet(singleInputTemplates.get(cfg.getInput().getType()));
String input = singleInputMap.apply(template, request);
psExec.redirectInput(IOUtils.toInputStream(input, StandardCharsets.UTF_8));
}
try {
log.info("Executing {}", cfg.getCommand());
ProcessResult psResult = psExec.execute();
String output = psResult.outputUTF8();
log.debug("Command output:{}{}", System.lineSeparator(), output);
log.info("Exit status: {}", psResult.getExitValue());
if (cfg.getExit().getSuccess().contains(psResult.getExitValue())) {
if (StringUtils.isBlank(output)) {
return Optional.empty();
}
return singleOutputMap.get(cfg.getOutput().getType())
.apply(output)
.map(mxId -> new SingleLookupReply(request, mxId));
} else if (cfg.getExit().getFailure().contains(psResult.getExitValue())) {
log.debug("{} stdout:{}{}", cfg.getCommand(), System.lineSeparator(), output);
return Optional.empty();
} else {
log.error("{} stdout:{}{}", cfg.getCommand(), System.lineSeparator(), output);
throw new InternalServerError("Exec auth command returned with unexpected exit status");
}
} catch (IOException | InterruptedException | TimeoutException e) {
throw new InternalServerError(e);
}
}
@Override

View File

@@ -22,8 +22,10 @@ package io.kamax.mxisd.backend.exec;
import io.kamax.matrix._MatrixID;
import io.kamax.matrix._ThreePid;
import io.kamax.mxisd.config.ExecConfig;
import io.kamax.mxisd.exception.NotImplementedException;
import io.kamax.mxisd.profile.ProfileProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@@ -32,9 +34,16 @@ import java.util.Optional;
@Component
public class ExecProfileStore extends ExecStore implements ProfileProvider {
private ExecConfig.Profile cfg;
@Autowired
public ExecProfileStore(ExecConfig cfg) {
this.cfg = cfg.getProfile();
}
@Override
public boolean isEnabled() {
return false;
return cfg.isEnabled();
}
@Override

View File

@@ -22,6 +22,7 @@ package io.kamax.mxisd.backend.exec;
public abstract class ExecStore {
// no-op
public static final String JsonType = "json";
public static final String MultilinesType = "multilines";
}

View File

@@ -31,6 +31,29 @@ import java.util.*;
@ConfigurationProperties("exec")
public class ExecConfig {
public class IO {
private String type;
private String template;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Optional<String> getTemplate() {
return Optional.ofNullable(template);
}
public void setTemplate(String template) {
this.template = template;
}
}
public class Exit {
private List<Integer> success = Collections.singletonList(0);
@@ -101,6 +124,8 @@ public class ExecConfig {
private String domain = "{domain}";
private String mxid = "{mxid}";
private String password = "{password}";
private String medium = "{medium}";
private String address = "{address}";
public String getLocalpart() {
return localpart;
@@ -134,6 +159,22 @@ public class ExecConfig {
this.password = password;
}
public String getMedium() {
return medium;
}
public void setMedium(String medium) {
this.medium = medium;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public class Process {
@@ -143,10 +184,10 @@ public class ExecConfig {
private List<String> args = new ArrayList<>();
private Map<String, String> env = new HashMap<>();
private String input;
private IO input = new IO();
private Exit exit = new Exit();
private String output;
private IO output = new IO();
public TokenOverride getToken() {
return token;
@@ -184,11 +225,11 @@ public class ExecConfig {
this.env.put(key, value);
}
public String getInput() {
public IO getInput() {
return input;
}
public void setInput(String input) {
public void setInput(IO input) {
this.input = input;
}
@@ -200,11 +241,11 @@ public class ExecConfig {
this.exit = exit;
}
public String getOutput() {
public IO getOutput() {
return output;
}
public void setOutput(String output) {
public void setOutput(IO output) {
this.output = output;
}
@@ -224,9 +265,33 @@ public class ExecConfig {
}
public class Directory extends Process {
public class Directory {
public class Search {
private Process byName = new Process();
private Process byThreepid = new Process();
public Process getByName() {
return byName;
}
public void setByName(Process byName) {
this.byName = byName;
}
public Process getByThreepid() {
return byThreepid;
}
public void setByThreepid(Process byThreepid) {
this.byThreepid = byThreepid;
}
}
private Boolean enabled;
private Search search = new Search();
public Boolean isEnabled() {
return enabled;
@@ -236,11 +301,20 @@ public class ExecConfig {
this.enabled = enabled;
}
public Search getSearch() {
return search;
}
public void setSearch(Search search) {
this.search = search;
}
}
public class Identity extends Process {
private Boolean enabled;
private int priority;
public Boolean isEnabled() {
return enabled;
@@ -250,6 +324,14 @@ public class ExecConfig {
this.enabled = enabled;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
}
public class Profile extends Process {

View File

@@ -0,0 +1,28 @@
/*
* mxisd - Matrix Identity Server Daemon
* Copyright (C) 2018 Kamax Sarl
*
* https://www.kamax.io/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.util;
@FunctionalInterface
public interface TriFunction<T, U, V, R> {
R apply(T t, U u, V v);
}

View File

@@ -18,15 +18,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.backend.exec;
package io.kamax.mxisd.backend.exec.input;
import java.util.Arrays;
public class ExecAuthStoreArgsTest extends ExecAuthStoreTest {
public class ArgsTest extends InputTest {
@Override
protected void setValidCommand() {
cfg.getAuth().setCommand("src/test/resources/store/exec/authArgsTest.sh");
cfg.getAuth().setCommand("src/test/resources/store/exec/input/argsTest.sh");
}
@Override

View File

@@ -18,9 +18,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.backend.exec;
package io.kamax.mxisd.backend.exec.input;
public class ExecAuthStoreEnvTest extends ExecAuthStoreTest {
import java.util.HashMap;
public class EnvTest extends InputTest {
private final String LocalpartEnv = "LOCALPART";
private final String DomainEnv = "DOMAIN";
@@ -28,11 +30,12 @@ public class ExecAuthStoreEnvTest extends ExecAuthStoreTest {
@Override
protected void setValidCommand() {
cfg.getAuth().setCommand("src/test/resources/store/exec/authEnvTest.sh");
cfg.getAuth().setCommand("src/test/resources/store/exec/input/envTest.sh");
}
@Override
protected void setValidEnv() {
cfg.getAuth().setEnv(new HashMap<>());
cfg.getAuth().addEnv(LocalpartEnv, LocalpartToken);
cfg.getAuth().addEnv(DomainEnv, DomainToken);
cfg.getAuth().addEnv(MxidEnv, MxidToken);

View File

@@ -18,13 +18,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.backend.exec;
package io.kamax.mxisd.backend.exec.input;
import io.kamax.matrix.MatrixID;
import io.kamax.matrix._MatrixID;
import io.kamax.mxisd.UserIdType;
import io.kamax.mxisd.backend.exec.ExecAuthResult;
import io.kamax.mxisd.backend.exec.ExecAuthStore;
import io.kamax.mxisd.config.ExecConfig;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
@@ -32,7 +35,7 @@ import java.util.Collections;
import static org.junit.Assert.assertEquals;
public abstract class ExecAuthStoreTest {
public abstract class InputTest {
protected final ExecConfig cfg;
protected final ExecAuthStore p;
@@ -61,20 +64,23 @@ public abstract class ExecAuthStoreTest {
// no-op
}
protected void setValidInput() {
// no-op
}
protected void setValidExit() {
cfg.getAuth().getExit().setSuccess(Collections.singletonList(0));
cfg.getAuth().getExit().setFailure(Arrays.asList(1, 10, 11, 12, 20, 21, 22));
}
protected void setValidConfig() {
@Before
public void setValidConfig() {
setValidCommand();
setValidEnv();
setValidArgs();
setValidInput();
setValidExit();
}
public ExecAuthStoreTest() {
cfg = new ExecConfig();
cfg.getAuth().addEnv("WITH_LOCALPART", "1");
cfg.getAuth().addEnv("REQ_LOCALPART", uId.getLocalPart());
cfg.getAuth().addEnv("WITH_DOMAIN", "1");
@@ -82,9 +88,10 @@ public abstract class ExecAuthStoreTest {
cfg.getAuth().addEnv("WITH_MXID", "1");
cfg.getAuth().addEnv("REQ_MXID", uId.getId());
cfg.getAuth().addEnv("REQ_PASS", requiredPass);
}
setValidConfig();
public InputTest() {
cfg = new ExecConfig();
p = new ExecAuthStore(cfg);
}
@@ -119,7 +126,7 @@ public abstract class ExecAuthStoreTest {
protected abstract void setEmptyLocalpartConfig();
@Test
public void doEmptyLocalpartConfig() {
public void emptyLocalpartConfig() {
setEmptyLocalpartConfig();
ExecAuthResult res = p.authenticate(uId, requiredPass);

View File

@@ -0,0 +1,92 @@
/*
* mxisd - Matrix Identity Server Daemon
* Copyright (C) 2018 Kamax Sarl
*
* https://www.kamax.io/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.kamax.mxisd.backend.exec.input;
import io.kamax.mxisd.backend.exec.ExecStore;
public class MultilinesTest extends InputTest {
@Override
protected void setValidCommand() {
cfg.getAuth().setCommand("src/test/resources/store/exec/input/multilinesTest.sh");
}
@Override
protected void setValidInput() {
cfg.getAuth().getInput().setType(ExecStore.MultilinesType);
cfg.getAuth().getInput().setTemplate(null);
}
@Override
protected void setEmptyLocalpartConfig() {
cfg.getAuth().getInput().setTemplate("" + System.lineSeparator()
+ DomainToken + System.lineSeparator()
+ MxidToken + System.lineSeparator()
+ PassToken + System.lineSeparator()
);
}
@Override
public void setWrongLocalpartConfig() {
cfg.getAuth().getInput().setTemplate(LocalpartInvalid + System.lineSeparator()
+ DomainToken + System.lineSeparator()
+ MxidToken + System.lineSeparator()
+ PassToken + System.lineSeparator()
);
}
@Override
protected void setEmptyDomainConfig() {
cfg.getAuth().getInput().setTemplate(LocalpartToken + System.lineSeparator()
+ "" + System.lineSeparator()
+ MxidToken + System.lineSeparator()
+ PassToken + System.lineSeparator()
);
}
@Override
public void setWrongDomainConfig() {
cfg.getAuth().getInput().setTemplate(LocalpartToken + System.lineSeparator()
+ DomainInvalid + System.lineSeparator()
+ MxidToken + System.lineSeparator()
+ PassToken + System.lineSeparator()
);
}
@Override
protected void setEmptyMxidConfig() {
cfg.getAuth().getInput().setTemplate(LocalpartToken + System.lineSeparator()
+ DomainToken + System.lineSeparator()
+ "" + System.lineSeparator()
+ PassToken + System.lineSeparator()
);
}
@Override
public void setWrongMxidConfig() {
cfg.getAuth().getInput().setTemplate(LocalpartToken + System.lineSeparator()
+ DomainToken + System.lineSeparator()
+ MxidInvalid + System.lineSeparator()
+ PassToken + System.lineSeparator()
);
}
}

View File

@@ -0,0 +1,42 @@
#!/bin/bash
#
# mxisd - Matrix Identity Server Daemon
# Copyright (C) 2018 Kamax Sarl
#
# https://www.kamax.io/
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
if [ -n "$WITH_LOCALPART" ]; then
read LOCALPART
[ -n "$LOCALPART" ] || exit 10
[ "$LOCALPART" = "$REQ_LOCALPART" ] || exit 20
fi
if [ -n "$WITH_DOMAIN" ]; then
read DOMAIN
[ -n "$DOMAIN" ] || exit 11
[ "$DOMAIN" = "$REQ_DOMAIN" ] || exit 21
fi
if [ -n "$WITH_MXID" ]; then
read MXID
[ -n "$MXID" ] || exit 12
[ "$MXID" = "$REQ_MXID" ] || exit 22
fi
read PASS
[ "$PASS" = "$REQ_PASS" ] || exit 1
exit 0