Add support for all features for Exec Identity Store
This commit is contained in:
@@ -42,7 +42,7 @@ import java.util.Optional;
|
||||
@Component
|
||||
public class ExecAuthStore extends ExecStore implements AuthenticatorProvider {
|
||||
|
||||
private final transient Logger log = LoggerFactory.getLogger(ExecAuthStore.class);
|
||||
private final Logger log = LoggerFactory.getLogger(ExecAuthStore.class);
|
||||
|
||||
private ExecConfig.Auth cfg;
|
||||
|
||||
@@ -66,43 +66,43 @@ public class ExecAuthStore extends ExecStore implements AuthenticatorProvider {
|
||||
ExecAuthResult result = new ExecAuthResult();
|
||||
result.setId(new UserID(UserIdType.Localpart, uId.getLocalPart()));
|
||||
|
||||
Processor<ExecAuthResult> process = new Processor<>();
|
||||
process.withConfig(cfg);
|
||||
process.addTokenMapper(cfg.getToken().getLocalpart(), uId::getLocalPart);
|
||||
process.addTokenMapper(cfg.getToken().getDomain(), uId::getDomain);
|
||||
process.addTokenMapper(cfg.getToken().getMxid(), uId::getId);
|
||||
process.addTokenMapper(cfg.getToken().getPassword(), () -> password);
|
||||
Processor<ExecAuthResult> p = new Processor<>(cfg);
|
||||
|
||||
process.addInputTemplate(JsonType, tokens -> {
|
||||
p.addTokenMapper(cfg.getToken().getLocalpart(), uId::getLocalPart);
|
||||
p.addTokenMapper(cfg.getToken().getDomain(), uId::getDomain);
|
||||
p.addTokenMapper(cfg.getToken().getMxid(), uId::getId);
|
||||
p.addTokenMapper(cfg.getToken().getPassword(), () -> password);
|
||||
|
||||
p.addJsonInputTemplate(tokens -> {
|
||||
RestAuthRequestJson json = new RestAuthRequestJson();
|
||||
json.setLocalpart(tokens.getLocalpart());
|
||||
json.setDomain(tokens.getDomain());
|
||||
json.setMxid(tokens.getMxid());
|
||||
json.setPassword(tokens.getPassword());
|
||||
return GsonUtil.get().toJson(json);
|
||||
return json;
|
||||
});
|
||||
process.addInputTemplate(MultilinesType, tokens -> tokens.getLocalpart() + System.lineSeparator() +
|
||||
p.addInputTemplate(MultilinesType, tokens -> tokens.getLocalpart() + System.lineSeparator() +
|
||||
tokens.getDomain() + System.lineSeparator() +
|
||||
tokens.getMxid() + System.lineSeparator() +
|
||||
tokens.getPassword() + System.lineSeparator()
|
||||
);
|
||||
|
||||
process.withExitHandler(pr -> result.setExitStatus(pr.getExitValue()));
|
||||
p.withExitHandler(pr -> result.setExitStatus(pr.getExitValue()));
|
||||
|
||||
process.withSuccessHandler(pr -> result.setSuccess(true));
|
||||
process.withSuccessDefault(o -> result);
|
||||
process.addSuccessMapper(JsonType, output -> {
|
||||
p.withSuccessHandler(pr -> result.setSuccess(true));
|
||||
p.withSuccessDefault(o -> result);
|
||||
p.addSuccessMapper(JsonType, output -> {
|
||||
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"))
|
||||
.flatMap(profile -> GsonUtil.findString(profile, "display_name"))
|
||||
.ifPresent(v -> result.getProfile().setDisplayName(v));
|
||||
|
||||
return result;
|
||||
});
|
||||
process.addSuccessMapper(MultilinesType, output -> {
|
||||
p.addSuccessMapper(MultilinesType, output -> {
|
||||
String[] lines = output.split("\\R");
|
||||
if (lines.length > 2) {
|
||||
throw new InternalServerError("Exec auth command returned more than 2 lines (" + lines.length + ")");
|
||||
@@ -120,10 +120,10 @@ public class ExecAuthStore extends ExecStore implements AuthenticatorProvider {
|
||||
return result;
|
||||
});
|
||||
|
||||
process.withFailureHandler(pr -> result.setSuccess(false));
|
||||
process.withFailureDefault(o -> result);
|
||||
p.withFailureHandler(pr -> result.setSuccess(false));
|
||||
p.withFailureDefault(o -> result);
|
||||
|
||||
return process.execute();
|
||||
return p.execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ import io.kamax.mxisd.config.MatrixConfig;
|
||||
import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchRequest;
|
||||
import io.kamax.mxisd.controller.directory.v1.io.UserDirectorySearchResult;
|
||||
import io.kamax.mxisd.directory.IDirectoryProvider;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -38,7 +39,11 @@ public class ExecDirectoryStore extends ExecStore implements IDirectoryProvider
|
||||
|
||||
@Autowired
|
||||
public ExecDirectoryStore(ExecConfig cfg, MatrixConfig mxCfg) {
|
||||
this.cfg = cfg.getDirectory();
|
||||
this(cfg.getDirectory(), mxCfg);
|
||||
}
|
||||
|
||||
public ExecDirectoryStore(ExecConfig.Directory cfg, MatrixConfig mxCfg) {
|
||||
this.cfg = cfg;
|
||||
this.mxCfg = mxCfg;
|
||||
}
|
||||
|
||||
@@ -48,24 +53,32 @@ public class ExecDirectoryStore extends ExecStore implements IDirectoryProvider
|
||||
}
|
||||
|
||||
private UserDirectorySearchResult search(ExecConfig.Process cfg, UserDirectorySearchRequest request) {
|
||||
Processor<UserDirectorySearchResult> processor = new Processor<>();
|
||||
processor.withConfig(cfg);
|
||||
processor.addInputTemplate(JsonType, tokens -> GsonUtil.get().toJson(new UserDirectorySearchRequest(tokens.getType(), tokens.getQuery())));
|
||||
processor.addInputTemplate(MultilinesType, tokens -> tokens.getType() + System.lineSeparator() + tokens.getQuery());
|
||||
if (StringUtils.isEmpty(cfg.getCommand())) {
|
||||
return UserDirectorySearchResult.empty();
|
||||
}
|
||||
|
||||
processor.addTokenMapper(cfg.getToken().getType(), request::getBy);
|
||||
processor.addTokenMapper(cfg.getToken().getQuery(), request::getSearchTerm);
|
||||
Processor<UserDirectorySearchResult> p = new Processor<>(cfg);
|
||||
|
||||
p.addJsonInputTemplate(tokens -> new UserDirectorySearchRequest(tokens.getType(), tokens.getQuery()));
|
||||
p.addInputTemplate(MultilinesType, tokens -> tokens.getType() + System.lineSeparator() + tokens.getQuery());
|
||||
|
||||
p.addTokenMapper(cfg.getToken().getType(), request::getBy);
|
||||
p.addTokenMapper(cfg.getToken().getQuery(), request::getSearchTerm);
|
||||
|
||||
p.addSuccessMapper(JsonType, output -> {
|
||||
if (StringUtils.isBlank(output)) {
|
||||
return UserDirectorySearchResult.empty();
|
||||
}
|
||||
|
||||
processor.addSuccessMapper(JsonType, output -> {
|
||||
UserDirectorySearchResult response = GsonUtil.get().fromJson(output, UserDirectorySearchResult.class);
|
||||
for (UserDirectorySearchResult.Result result : response.getResults()) {
|
||||
result.setUserId(MatrixID.asAcceptable(result.getUserId(), mxCfg.getDomain()).getId());
|
||||
}
|
||||
return response;
|
||||
});
|
||||
processor.withFailureDefault(output -> new UserDirectorySearchResult());
|
||||
p.withFailureDefault(output -> new UserDirectorySearchResult());
|
||||
|
||||
return processor.execute();
|
||||
return p.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -21,12 +21,15 @@
|
||||
package io.kamax.mxisd.backend.exec;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import io.kamax.matrix.MatrixID;
|
||||
import io.kamax.matrix.ThreePid;
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
import io.kamax.mxisd.UserID;
|
||||
import io.kamax.mxisd.UserIdType;
|
||||
import io.kamax.mxisd.backend.rest.LookupBulkResponseJson;
|
||||
import io.kamax.mxisd.backend.rest.LookupSingleResponseJson;
|
||||
import io.kamax.mxisd.config.ExecConfig;
|
||||
import io.kamax.mxisd.config.MatrixConfig;
|
||||
import io.kamax.mxisd.exception.InternalServerError;
|
||||
@@ -42,6 +45,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -55,7 +59,11 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
|
||||
|
||||
@Autowired
|
||||
public ExecIdentityStore(ExecConfig cfg, MatrixConfig mxCfg) {
|
||||
this.cfg = cfg.getIdentity();
|
||||
this(cfg.getIdentity(), mxCfg);
|
||||
}
|
||||
|
||||
public ExecIdentityStore(ExecConfig.Identity cfg, MatrixConfig mxCfg) {
|
||||
this.cfg = cfg;
|
||||
this.mxCfg = mxCfg;
|
||||
}
|
||||
|
||||
@@ -78,46 +86,49 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
|
||||
return cfg.getLookup().getSingle();
|
||||
}
|
||||
|
||||
private _MatrixID getUserId(UserID id) {
|
||||
if (Objects.isNull(id)) {
|
||||
throw new JsonParseException("User id key is not present");
|
||||
}
|
||||
|
||||
if (UserIdType.Localpart.is(id.getType())) {
|
||||
return MatrixID.asAcceptable(id.getValue(), mxCfg.getDomain());
|
||||
}
|
||||
|
||||
if (UserIdType.MatrixID.is(id.getType())) {
|
||||
return MatrixID.asAcceptable(id.getValue());
|
||||
}
|
||||
|
||||
throw new InternalServerError("Unknown user type: " + id.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SingleLookupReply> find(SingleLookupRequest request) {
|
||||
Processor<Optional<SingleLookupReply>> processor = new Processor<>();
|
||||
processor.withConfig(cfg.getLookup().getSingle());
|
||||
Processor<Optional<SingleLookupReply>> p = new Processor<>();
|
||||
p.withConfig(cfg.getLookup().getSingle());
|
||||
|
||||
processor.addTokenMapper(getSingleCfg().getToken().getMedium(), request::getType);
|
||||
processor.addTokenMapper(getSingleCfg().getToken().getAddress(), request::getThreePid);
|
||||
p.addTokenMapper(getSingleCfg().getToken().getMedium(), request::getType);
|
||||
p.addTokenMapper(getSingleCfg().getToken().getAddress(), request::getThreePid);
|
||||
|
||||
processor.addInputTemplate(JsonType, tokens -> {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("medium", tokens.getMedium());
|
||||
json.addProperty("address", tokens.getAddress());
|
||||
return GsonUtil.get().toJson(json);
|
||||
});
|
||||
processor.addInputTemplate(MultilinesType, tokens -> tokens.getMedium()
|
||||
p.addJsonInputTemplate(tokens -> new ThreePid(tokens.getMedium(), tokens.getAddress()));
|
||||
p.addInputTemplate(MultilinesType, tokens -> tokens.getMedium()
|
||||
+ System.lineSeparator()
|
||||
+ tokens.getAddress()
|
||||
);
|
||||
|
||||
processor.addSuccessMapper(JsonType, output -> {
|
||||
p.addSuccessMapper(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 (UserIdType.Localpart.is(type)) {
|
||||
return MatrixID.asAcceptable(value, mxCfg.getDomain());
|
||||
}
|
||||
|
||||
if (UserIdType.MatrixID.is(type)) {
|
||||
return MatrixID.asAcceptable(value);
|
||||
}
|
||||
|
||||
throw new InternalServerError("Invalid user type: " + type);
|
||||
}).map(mxId -> new SingleLookupReply(request, mxId));
|
||||
return GsonUtil.findObj(GsonUtil.parseObj(output), "lookup")
|
||||
.filter(obj -> !obj.entrySet().isEmpty())
|
||||
.map(json -> GsonUtil.get().fromJson(json, LookupSingleResponseJson.class))
|
||||
.map(lookup -> getUserId(lookup.getId()))
|
||||
.map(mxId -> new SingleLookupReply(request, mxId));
|
||||
});
|
||||
|
||||
processor.addSuccessMapper(MultilinesType, output -> {
|
||||
p.addSuccessMapper(MultilinesType, output -> {
|
||||
String[] lines = output.split("\\R");
|
||||
if (lines.length > 2) {
|
||||
throw new InternalServerError("Exec auth command returned more than 2 lines (" + lines.length + ")");
|
||||
@@ -141,23 +152,23 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
|
||||
throw new InternalServerError("Invalid user type: " + type);
|
||||
});
|
||||
|
||||
processor.withFailureDefault(o -> Optional.empty());
|
||||
p.withFailureDefault(o -> Optional.empty());
|
||||
|
||||
return processor.execute();
|
||||
return p.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ThreePidMapping> populate(List<ThreePidMapping> mappings) {
|
||||
Processor<List<ThreePidMapping>> processor = new Processor<>();
|
||||
processor.withConfig(cfg.getLookup().getBulk());
|
||||
Processor<List<ThreePidMapping>> p = new Processor<>();
|
||||
p.withConfig(cfg.getLookup().getBulk());
|
||||
|
||||
processor.addInput(JsonType, () -> {
|
||||
p.addInput(JsonType, () -> {
|
||||
JsonArray tpids = GsonUtil.asArray(mappings.stream()
|
||||
.map(mapping -> GsonUtil.get().toJsonTree(new ThreePid(mapping.getMedium(), mapping.getValue())))
|
||||
.collect(Collectors.toList()));
|
||||
return GsonUtil.get().toJson(GsonUtil.makeObj("lookup", tpids));
|
||||
});
|
||||
processor.addInput(MultilinesType, () -> {
|
||||
p.addInput(MultilinesType, () -> {
|
||||
StringBuilder input = new StringBuilder();
|
||||
for (ThreePidMapping mapping : mappings) {
|
||||
input.append(mapping.getMedium()).append("\t").append(mapping.getValue()).append(System.lineSeparator());
|
||||
@@ -165,7 +176,7 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
|
||||
return input.toString();
|
||||
});
|
||||
|
||||
processor.addSuccessMapper(JsonType, output -> {
|
||||
p.addSuccessMapper(JsonType, output -> {
|
||||
if (StringUtils.isBlank(output)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -190,9 +201,9 @@ public class ExecIdentityStore extends ExecStore implements IThreePidProvider {
|
||||
}).collect(Collectors.toList());
|
||||
});
|
||||
|
||||
processor.withFailureDefault(output -> Collections.emptyList());
|
||||
p.withFailureDefault(output -> Collections.emptyList());
|
||||
|
||||
return processor.execute();
|
||||
return p.execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -22,12 +22,16 @@ package io.kamax.mxisd.backend.exec;
|
||||
|
||||
import io.kamax.matrix._MatrixID;
|
||||
import io.kamax.matrix._ThreePid;
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
import io.kamax.mxisd.config.ExecConfig;
|
||||
import io.kamax.mxisd.exception.NotImplementedException;
|
||||
import io.kamax.mxisd.profile.JsonProfileRequest;
|
||||
import io.kamax.mxisd.profile.JsonProfileResult;
|
||||
import io.kamax.mxisd.profile.ProfileProvider;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -38,7 +42,11 @@ public class ExecProfileStore extends ExecStore implements ProfileProvider {
|
||||
|
||||
@Autowired
|
||||
public ExecProfileStore(ExecConfig cfg) {
|
||||
this.cfg = cfg.getProfile();
|
||||
this(cfg.getProfile());
|
||||
}
|
||||
|
||||
public ExecProfileStore(ExecConfig.Profile cfg) {
|
||||
this.cfg = cfg;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,19 +54,50 @@ public class ExecProfileStore extends ExecStore implements ProfileProvider {
|
||||
return cfg.isEnabled();
|
||||
}
|
||||
|
||||
private Optional<JsonProfileResult> getFull(_MatrixID userId, ExecConfig.Process cfg) {
|
||||
Processor<Optional<JsonProfileResult>> p = new Processor<>(cfg);
|
||||
|
||||
p.addJsonInputTemplate(tokens -> new JsonProfileRequest(tokens.getLocalpart(), tokens.getDomain(), tokens.getMxid()));
|
||||
p.addInputTemplate(MultilinesType, tokens -> tokens.getLocalpart() + System.lineSeparator()
|
||||
+ tokens.getDomain() + System.lineSeparator()
|
||||
+ tokens.getMxid() + System.lineSeparator()
|
||||
);
|
||||
|
||||
p.addTokenMapper(cfg.getToken().getLocalpart(), userId::getLocalPart);
|
||||
p.addTokenMapper(cfg.getToken().getDomain(), userId::getDomain);
|
||||
p.addTokenMapper(cfg.getToken().getMxid(), userId::getId);
|
||||
|
||||
p.withFailureDefault(v -> Optional.empty());
|
||||
|
||||
p.addSuccessMapper(JsonType, output -> {
|
||||
if (StringUtils.isBlank(output)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return GsonUtil.findObj(GsonUtil.parseObj(output), "profile")
|
||||
.map(obj -> GsonUtil.get().fromJson(obj, JsonProfileResult.class));
|
||||
});
|
||||
|
||||
return p.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getDisplayName(_MatrixID userId) {
|
||||
throw new NotImplementedException(this.getClass().getName());
|
||||
return getFull(userId, cfg.getDisplayName()).map(JsonProfileResult::getDisplayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<_ThreePid> getThreepids(_MatrixID userId) {
|
||||
throw new NotImplementedException(this.getClass().getName());
|
||||
return getFull(userId, cfg.getThreePid())
|
||||
.map(p -> Collections.<_ThreePid>unmodifiableList(p.getThreepids()))
|
||||
.orElseGet(Collections::emptyList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRoles(_MatrixID userId) {
|
||||
throw new NotImplementedException(this.getClass().getName());
|
||||
return getFull(userId, cfg.getRole())
|
||||
.map(JsonProfileResult::getRoles)
|
||||
.orElseGet(Collections::emptyList);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
package io.kamax.mxisd.backend.exec;
|
||||
|
||||
import io.kamax.matrix.json.GsonUtil;
|
||||
import io.kamax.mxisd.config.ExecConfig;
|
||||
import io.kamax.mxisd.exception.InternalServerError;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
@@ -42,8 +43,18 @@ public class ExecStore {
|
||||
public static final String JsonType = "json";
|
||||
public static final String MultilinesType = "multilines";
|
||||
|
||||
protected static String toJson(Object o) {
|
||||
return GsonUtil.get().toJson(o);
|
||||
}
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(ExecStore.class);
|
||||
|
||||
private Supplier<ProcessExecutor> executorSupplier = () -> new ProcessExecutor().readOutput(true);
|
||||
|
||||
public void setExecutorSupplier(Supplier<ProcessExecutor> supplier) {
|
||||
executorSupplier = supplier;
|
||||
}
|
||||
|
||||
public class Processor<V> {
|
||||
|
||||
private ExecConfig.Process cfg;
|
||||
@@ -55,7 +66,6 @@ public class ExecStore {
|
||||
|
||||
private Map<String, Function<ExecConfig.TokenOverride, String>> inputTypeTemplates;
|
||||
private Supplier<String> inputTypeNoTemplateHandler;
|
||||
private Map<String, Function<ExecConfig.TokenOverride, String>> inputTypeTokenizers;
|
||||
private Map<String, Supplier<String>> tokenMappers;
|
||||
private Function<String, String> tokenHandler;
|
||||
|
||||
@@ -70,17 +80,22 @@ public class ExecStore {
|
||||
private Map<String, Function<String, V>> unknownMappers;
|
||||
private Function<String, V> unknownDefault;
|
||||
|
||||
public Processor(ExecConfig.Process cfg) {
|
||||
this();
|
||||
withConfig(cfg);
|
||||
}
|
||||
|
||||
public Processor() {
|
||||
tokenMappers = new HashMap<>();
|
||||
inputTypeSuppliers = new HashMap<>();
|
||||
inputTypeTemplates = new HashMap<>();
|
||||
|
||||
tokenHandler = input -> {
|
||||
withTokenHandler(tokenHandler = input -> {
|
||||
for (Map.Entry<String, Supplier<String>> entry : tokenMappers.entrySet()) {
|
||||
input = input.replace(entry.getKey(), entry.getValue().get());
|
||||
}
|
||||
return input;
|
||||
};
|
||||
});
|
||||
|
||||
inputTypeNoTemplateHandler = () -> cfg.getInput().getType()
|
||||
.map(type -> inputTypeTemplates.get(type).apply(cfg.getToken()))
|
||||
@@ -98,12 +113,12 @@ public class ExecStore {
|
||||
|
||||
inputSupplier = () -> cfg.getInput().getType().map(type -> inputTypeMapper.apply(type));
|
||||
|
||||
onExitHandler = pr -> {
|
||||
};
|
||||
withExitHandler(pr -> {
|
||||
});
|
||||
|
||||
successMappers = new HashMap<>();
|
||||
successHandler = pr -> {
|
||||
};
|
||||
successMappers = new HashMap<>();
|
||||
successDefault = output -> {
|
||||
log.info("{} stdout: {}{}", cfg.getCommand(), System.lineSeparator(), output);
|
||||
throw new InternalServerError("Exec command has no success handler configured. This is a bug. Please report.");
|
||||
@@ -119,90 +134,80 @@ public class ExecStore {
|
||||
|
||||
unknownHandler = pr -> log.warn("Unexpected exit status: {}", pr.getExitValue());
|
||||
unknownMappers = new HashMap<>();
|
||||
unknownDefault = output -> {
|
||||
withUnknownDefault(output -> {
|
||||
log.error("{} stdout:{}{}", cfg.getCommand(), System.lineSeparator(), output);
|
||||
throw new InternalServerError("Exec command returned with unexpected exit status");
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public Processor<V> withConfig(ExecConfig.Process cfg) {
|
||||
public void withConfig(ExecConfig.Process cfg) {
|
||||
this.cfg = cfg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> addTokenMapper(String token, Supplier<String> data) {
|
||||
public void addTokenMapper(String token, Supplier<String> data) {
|
||||
tokenMappers.put(token, data);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> withTokenHandler(Function<String, String> tokenHandler) {
|
||||
this.tokenHandler = tokenHandler;
|
||||
return this;
|
||||
public void withTokenHandler(Function<String, String> handler) {
|
||||
tokenHandler = handler;
|
||||
}
|
||||
|
||||
public Processor<V> addInput(String type, Supplier<String> handler) {
|
||||
public void addInput(String type, Supplier<String> handler) {
|
||||
inputTypeSuppliers.put(type, handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> addInputTemplate(String type, Function<ExecConfig.TokenOverride, String> template) {
|
||||
protected void addInputTemplate(String type, Function<ExecConfig.TokenOverride, String> template) {
|
||||
inputTypeTemplates.put(type, template);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> withExitHandler(Consumer<ProcessResult> handler) {
|
||||
public void addJsonInputTemplate(Function<ExecConfig.TokenOverride, Object> template) {
|
||||
inputTypeTemplates.put(JsonType, token -> GsonUtil.get().toJson(template.apply(token)));
|
||||
}
|
||||
|
||||
public void withExitHandler(Consumer<ProcessResult> handler) {
|
||||
onExitHandler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> withSuccessHandler(Consumer<ProcessResult> handler) {
|
||||
public void withSuccessHandler(Consumer<ProcessResult> handler) {
|
||||
successHandler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> addSuccessMapper(String type, Function<String, V> mapper) {
|
||||
public void addSuccessMapper(String type, Function<String, V> mapper) {
|
||||
successMappers.put(type, mapper);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> withSuccessDefault(Function<String, V> mapper) {
|
||||
public void withSuccessDefault(Function<String, V> mapper) {
|
||||
successDefault = mapper;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> withFailureHandler(Consumer<ProcessResult> handler) {
|
||||
public void withFailureHandler(Consumer<ProcessResult> handler) {
|
||||
failureHandler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> addFailureMapper(String type, Function<String, V> mapper) {
|
||||
public void addFailureMapper(String type, Function<String, V> mapper) {
|
||||
failureMappers.put(type, mapper);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> withFailureDefault(Function<String, V> mapper) {
|
||||
public void withFailureDefault(Function<String, V> mapper) {
|
||||
failureDefault = mapper;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> addUnknownMapper(String type, Function<String, V> mapper) {
|
||||
public void addUnknownMapper(String type, Function<String, V> mapper) {
|
||||
unknownMappers.put(type, mapper);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Processor<V> withUnknownDefault(Function<String, V> mapper) {
|
||||
public void withUnknownDefault(Function<String, V> mapper) {
|
||||
unknownDefault = mapper;
|
||||
return this;
|
||||
}
|
||||
|
||||
V execute() {
|
||||
public V execute() {
|
||||
log.info("Executing {}", cfg.getCommand());
|
||||
|
||||
try {
|
||||
ProcessExecutor psExec = new ProcessExecutor().readOutput(true);
|
||||
ProcessExecutor psExec = executorSupplier.get();
|
||||
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add(cfg.getCommand());
|
||||
args.add(tokenHandler.apply(cfg.getCommand()));
|
||||
args.addAll(cfg.getArgs().stream().map(arg -> tokenHandler.apply(arg)).collect(Collectors.toList()));
|
||||
psExec.command(args);
|
||||
|
||||
@@ -235,8 +240,9 @@ public class ExecStore {
|
||||
.map(type -> unknownMappers.getOrDefault(type, unknownDefault).apply(output))
|
||||
.orElseGet(() -> unknownDefault.apply(output));
|
||||
}
|
||||
} catch (IOException | InterruptedException | TimeoutException e) {
|
||||
} catch (RuntimeException | IOException | InterruptedException | TimeoutException e) {
|
||||
log.error("Failed to execute {}", cfg.getCommand());
|
||||
log.debug("Internal exception:", e);
|
||||
throw new InternalServerError(e);
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
package io.kamax.mxisd.backend.rest;
|
||||
|
||||
import io.kamax.matrix.ThreePidMedium;
|
||||
import io.kamax.mxisd.UserID;
|
||||
|
||||
public class LookupSingleResponseJson {
|
||||
@@ -32,12 +33,28 @@ public class LookupSingleResponseJson {
|
||||
return medium;
|
||||
}
|
||||
|
||||
public void setMedium(String medium) {
|
||||
this.medium = medium;
|
||||
}
|
||||
|
||||
public void setMedium(ThreePidMedium medium) {
|
||||
setMedium(medium.getId());
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public UserID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UserID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -420,9 +420,12 @@ public class ExecConfig {
|
||||
|
||||
}
|
||||
|
||||
public class Profile extends Process {
|
||||
public class Profile {
|
||||
|
||||
private Boolean enabled;
|
||||
private Process displayName = new Process();
|
||||
private Process threePid = new Process();
|
||||
private Process role = new Process();
|
||||
|
||||
public Boolean isEnabled() {
|
||||
return enabled;
|
||||
@@ -432,6 +435,30 @@ public class ExecConfig {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Process getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(Process displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public Process getThreePid() {
|
||||
return threePid;
|
||||
}
|
||||
|
||||
public void setThreePid(Process threePid) {
|
||||
this.threePid = threePid;
|
||||
}
|
||||
|
||||
public Process getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRoles(Process role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean enabled;
|
||||
@@ -490,7 +517,7 @@ public class ExecConfig {
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void build() {
|
||||
public ExecConfig compute() {
|
||||
if (Objects.isNull(getAuth().isEnabled())) {
|
||||
getAuth().setEnabled(isEnabled());
|
||||
}
|
||||
@@ -506,6 +533,8 @@ public class ExecConfig {
|
||||
if (Objects.isNull(getProfile().isEnabled())) {
|
||||
getProfile().setEnabled(isEnabled());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -25,6 +25,10 @@ import java.util.Set;
|
||||
|
||||
public class UserDirectorySearchResult {
|
||||
|
||||
public static UserDirectorySearchResult empty() {
|
||||
return new UserDirectorySearchResult();
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
|
||||
private String displayName;
|
||||
|
67
src/main/java/io/kamax/mxisd/profile/JsonProfileRequest.java
Normal file
67
src/main/java/io/kamax/mxisd/profile/JsonProfileRequest.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.profile;
|
||||
|
||||
import io.kamax.matrix._MatrixID;
|
||||
|
||||
public class JsonProfileRequest {
|
||||
|
||||
private String localpart;
|
||||
private String domain;
|
||||
private String mxid;
|
||||
|
||||
public JsonProfileRequest(_MatrixID mxId) {
|
||||
this.localpart = mxId.getLocalPart();
|
||||
this.domain = mxId.getDomain();
|
||||
this.mxid = mxId.getId();
|
||||
}
|
||||
|
||||
public JsonProfileRequest(String localpart, String domain, String mxId) {
|
||||
this.localpart = localpart;
|
||||
this.domain = domain;
|
||||
this.mxid = mxId;
|
||||
}
|
||||
|
||||
public String getLocalpart() {
|
||||
return localpart;
|
||||
}
|
||||
|
||||
public void setLocalpart(String localpart) {
|
||||
this.localpart = localpart;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
public String getMxid() {
|
||||
return mxid;
|
||||
}
|
||||
|
||||
public void setMxid(String mxid) {
|
||||
this.mxid = mxid;
|
||||
}
|
||||
|
||||
}
|
69
src/main/java/io/kamax/mxisd/profile/JsonProfileResult.java
Normal file
69
src/main/java/io/kamax/mxisd/profile/JsonProfileResult.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.profile;
|
||||
|
||||
import io.kamax.matrix.ThreePid;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class JsonProfileResult {
|
||||
|
||||
private String displayName;
|
||||
private List<ThreePid> threepids;
|
||||
private List<String> roles;
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public List<ThreePid> getThreepids() {
|
||||
return threepids;
|
||||
}
|
||||
|
||||
public void setThreepids(List<ThreePid> threepids) {
|
||||
this.threepids = threepids;
|
||||
}
|
||||
|
||||
public void addThreepid(ThreePid threepid) {
|
||||
if (Objects.isNull(threepids)) threepids = new ArrayList<>();
|
||||
threepids.add(threepid);
|
||||
}
|
||||
|
||||
public List<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(List<String> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public void addRole(String role) {
|
||||
if (Objects.isNull(roles)) roles = new ArrayList<>();
|
||||
roles.add(role);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user