working on legacy api:

Teile des Codes aus funktionierendem Projekt kpiert und angepasst, aber noch nicht getestet
This commit is contained in:
2025-07-04 00:26:01 +02:00
parent c96e7d73ba
commit e48ddfdb2c
12 changed files with 239 additions and 35 deletions

5
legacy/Readme.md Normal file
View File

@@ -0,0 +1,5 @@
# Legacy
This module aims to provide an API for legacy modules to communicate with.
As soon as all "old" PHP modules are replaced, this should no longer be required.

View File

@@ -0,0 +1,126 @@
package de.srsoftware.umbrella.legacy;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.configuration.Configuration;
import de.srsoftware.tools.Path;
import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.Token;
import de.srsoftware.umbrella.core.UmbrellaException;
import de.srsoftware.umbrella.user.sqlite.SqliteDB;
import static de.srsoftware.tools.MimeType.MIME_FORM_URL;
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_SERVER_ERROR;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Constants.KEY;
import static de.srsoftware.umbrella.core.Paths.LOGOUT;
import static de.srsoftware.umbrella.core.Paths.SEARCH;
import static de.srsoftware.umbrella.core.Util.request;
import static java.net.HttpURLConnection.*;
import static java.time.temporal.ChronoUnit.DAYS;
import java.io.IOException;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;
public class LegacyApi extends BaseHandler {
private final SqliteDB users;
private final Configuration config;
public LegacyApi(SqliteDB userDb, Configuration config) {
users = userDb;
this.config = config.subset("umbrella.modules").orElseThrow(() -> new RuntimeException("Missing configuration: umbrella.modules"));
}
@Override
public boolean doGet(Path path, HttpExchange ex) throws IOException {
var head = path.pop();
return switch (head){
case null -> sendRedirect(ex, url(ex).replaceAll("/api/.*",""));
case "common_templates" -> {
allowOrigin(ex, "*"); // add CORS header
yield load(path,ex);
}
case LOGIN -> getLegacyLogin(ex);
case LOGOUT-> logout(ex);
case SEARCH -> {
try {
yield legacySearch(ex);
} catch (UmbrellaException e){
yield send(ex,e);
}
}
default -> super.doGet(path,ex);
};
}
private boolean legacySearch(HttpExchange ex) throws IOException, UmbrellaException {
var optToken = SessionToken.from(ex).map(Token::of);
if (optToken.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED,ex);
var token = optToken.get();
var params = queryParam(ex);
var key = params.get(KEY) instanceof String s ? s : null;
if (key == null) throw new UmbrellaException(HTTP_BAD_REQUEST,"Missing search key");
var fulltext = key.contains("+") || "on".equals(params.get("fulltext"));
StringBuilder searchResult = new StringBuilder();
if (fulltext){
for (var module : config.keys()){
var baseUrl = config.get(module + ".baseUrl");
if (baseUrl.isEmpty()) continue;
var res = request(baseUrl.get()+"/search",token.asMap().plus(KEY,key),MIME_FORM_URL,token.asBearer());
if (!(res instanceof String content) || content.isBlank()) continue;
searchResult.append("<fieldset><label>").append(module).append("</label>");
searchResult.append(content).append("</fieldset>\n");
}
} else {
var bookmark = config.get("bookmark.baseUrl");
if (bookmark.isEmpty()) throw new UmbrellaException(500,"Tag search not available: Bookmark module not configured!");
var res = request(bookmark.get()+"/search",token.asMap().plus(KEY,key),MIME_FORM_URL,null);
if (!(res instanceof String content)) throw new UmbrellaException(500,"Search did not return html content!");
searchResult.append(content);
}
return sendContent(ex,searchResult.toString());
};
private boolean logout(HttpExchange ex) throws IOException {
var returnTo = queryParam(ex).get("returnTo");
var optToken = SessionToken.from(ex).map(Token::of);
if (optToken.isPresent()) try{
var token = optToken.get();
users.dropSession(token);
var expiredToken = new SessionToken(token.toString(),"/", Instant.now().minus(1, DAYS),true);
expiredToken.addTo(ex);
if (returnTo instanceof String location) return sendRedirect(ex,location);
return sendContent(ex, Map.of(REDIRECT,"home"));
} catch (UmbrellaException e) {
return send(ex,e);
}
if (returnTo instanceof String location) return sendRedirect(ex,location);
return sendContent(ex,Map.of(REDIRECT,"home"));
}
private boolean getLegacyLogin(HttpExchange ex) throws IOException {
var returnTo = queryParam(ex).get("returnTo");
if (returnTo instanceof String url) {
var token = SessionToken.from(ex).map(SessionToken::sessionId)
.or(() -> getBearer(ex))
.map(Token::of);
if (token.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED,ex);
return sendRedirect(ex, url + (url.contains("?") ? "&" : "?") + "token=" + token.get());
}
var location = url(ex);
location = location.replaceAll("/api/.*","/login");
if (returnTo != null) location += "?returnTo="+returnTo;
return sendRedirect(ex,location);
}
@Override
public boolean doPost(Path path, HttpExchange ex) throws IOException {
return super.doPost(path, ex);
}
}