Browse Source

working on configuration

drop_old_mail
Stephan Richter 2 years ago
parent
commit
26df2e5654
  1. 2
      .gitignore
  2. 5
      config/config.template.json
  3. 8
      pom.xml
  4. 19
      src/main/java/de/srsoftware/widerhall/Application.java
  5. 114
      src/main/java/de/srsoftware/widerhall/Configuration.java
  6. 6
      src/main/java/de/srsoftware/widerhall/Constants.java
  7. 4
      src/main/java/de/srsoftware/widerhall/data/Database.java
  8. 24
      src/main/java/de/srsoftware/widerhall/web/Web.java
  9. 23
      static/templates/css.st
  10. 11
      static/templates/index.st
  11. 0
      static/templates/js.st
  12. 56
      static/templates/login.st

2
.gitignore vendored

@ -1,2 +1,4 @@ @@ -1,2 +1,4 @@
.idea
target
config/config.json
*.sqlite3

5
config/config.template.json

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
{
"port" : 80,
"base_dir" : "/home/srichter/workspace/Widerhall/static",
"base_url" : "http://localhost",
}

8
pom.xml

@ -84,10 +84,8 @@ @@ -84,10 +84,8 @@
<dependency>
<groupId>org.antlr</groupId>
<artifactId>stringtemplate</artifactId>
<version>4.0.2</version>
<artifactId>ST4</artifactId>
<version>4.3.3</version>
</dependency>
</dependencies>
</project>
</project>

19
src/main/java/de/srsoftware/widerhall/Application.java

@ -3,7 +3,7 @@ package de.srsoftware.widerhall; @@ -3,7 +3,7 @@ package de.srsoftware.widerhall;
import de.srsoftware.widerhall.mail.Forwarder;
import de.srsoftware.widerhall.mail.ImapClient;
import de.srsoftware.widerhall.mail.MessageHandler;
import de.srsoftware.widerhall.web.Static;
import de.srsoftware.widerhall.web.Web;
import de.srsoftware.widerhall.web.Rest;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
@ -11,18 +11,23 @@ import org.eclipse.jetty.server.ServerConnector; @@ -11,18 +11,23 @@ import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.json.simple.JSONObject;
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Application {
private static final Logger LOG = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) throws Exception {
var config = Configuration.setFile(new File("/tmp/config.json"));
var config = Configuration.instance();
// the following construct allows the initial config file to point to another config file, which is then loaded:
while (!config.configFile().equals(config.file())) config.load(config.configFile());
//startMailSystem(json);
startWebserver(config);
startWebserver();
}
private static void startWebserver(Configuration config) throws Exception {
private static void startWebserver() throws Exception {
var config = Configuration.instance();
var server = new Server();
var connector = new ServerConnector(server);
connector.setPort(config.serverPort());
@ -31,7 +36,7 @@ public class Application { @@ -31,7 +36,7 @@ public class Application {
server.setConnectors(new Connector[]{connector});
ServletContextHandler context = new ServletContextHandler(server, "/",sh,null,null,null);
context.addServlet(Rest.class,"/api");
context.addServlet(Static.class,"/static/*");
context.addServlet(Web.class,"/web/*");
server.start();
}

114
src/main/java/de/srsoftware/widerhall/Configuration.java

@ -3,66 +3,93 @@ package de.srsoftware.widerhall; @@ -3,66 +3,93 @@ package de.srsoftware.widerhall;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import static de.srsoftware.widerhall.Constants.*;
public class Configuration {
private static final Logger LOG = LoggerFactory.getLogger(Configuration.class);
private static Configuration singleton = null;
private JSONObject data;
private final File file;
private File file;
public static Configuration instance() {
if (singleton == null) singleton = new Configuration().setDefaults();
return singleton;
}
public Configuration(File configFile) throws IOException, ParseException {
this.file = configFile;
if (!configFile.exists()){
setDefaults();
save();
/**
* Merges configuration from file into current configuration.
* Existing entries will be replaced.
* @param file
* @return
* @throws IOException
* @throws ParseException
*/
public Configuration load(File file) {
this.file = file;
if (file.exists()) try {
var newVals = (JSONObject) new JSONParser().parse(Files.readString(file.toPath()));
data.putAll(newVals);
} catch (ParseException | IOException e){
LOG.warn("Was not able to load configuration from {}:",file,e);
}
var content = Files.readString(configFile.toPath());
data = (JSONObject) new JSONParser().parse(content);
return this;
}
public static Configuration setFile(File file) throws IOException, ParseException {
singleton = new Configuration(file);
return singleton;
public Configuration save(File file) throws IOException {
this.file = file;
return save();
}
public static Configuration instance() {
return singleton;
public Configuration save() throws IOException {
if (file == null) throw new NullPointerException("Cannot save configuration: file is null!");
file.getParentFile().mkdirs();
Files.writeString(file.toPath(),data.toJSONString());
return this;
}
private void setDefaults() throws MalformedURLException {
private Configuration setDefaults() {
if (data == null) data = new JSONObject();
baseDir();
serverPort();
tokenUrl();
loginUrl();
configFile();
dbFile();
baseUrl();
clientId();
clientSecret();
serverPort();
return this;
}
private void save() throws IOException {
Files.writeString(file.toPath(),data.toJSONString());
private JSONObject locations() {
Object o = data.get(LOCATIONS);
if (!(o instanceof JSONObject)) data.put(LOCATIONS,o = new JSONObject());
return (JSONObject) o;
}
public int serverPort() {
if (!data.containsKey(PORT)) data.put(PORT,80L);
var o = data.get(PORT);
return (int) (long) o;
public String baseDir() {
var locations = locations();
if (!locations.containsKey(BASE)) locations.put(BASE,System.getProperty("user.dir"));
return (String) locations.get(BASE);
}
public File configFile() {
var locations = locations();
if (!locations.containsKey(CONFIG)) locations.put(CONFIG, String.join(File.separator,baseDir(),"config","config.json"));
return new File((String) locations.get(CONFIG));
}
public URL tokenUrl() throws MalformedURLException {
if (!data.containsKey(TOKEN_URL)) data.put(TOKEN_URL,"http://localhost:"+serverPort()+"/oauth/token");
return new URL((String) data.get(TOKEN_URL));
public File dbFile() {
var locations = locations();
if (!locations.containsKey(DB)) locations.put(DB, String.join(File.separator,baseDir(),"db","db.sqlite3"));
return new File((String) locations.get(DB));
}
public String loginUrl() {
if (!data.containsKey(LOGIN_URL)) data.put(LOGIN_URL,"http://localhost:"+serverPort()+"/oauth/login");
return (String) data.get(LOGIN_URL);
public int serverPort() {
if (!data.containsKey(PORT)) data.put(PORT,80L);
var o = data.get(PORT);
return (int) (long) o;
}
public String baseUrl() {
@ -70,23 +97,8 @@ public class Configuration { @@ -70,23 +97,8 @@ public class Configuration {
return (String) data.get(BASE_URL);
}
public String clientId() {
if (!data.containsKey(CLIENT_ID)) data.put(CLIENT_ID,"widerhall");
return (String) data.get(CLIENT_ID);
}
public Object clientSecret() {
if (!data.containsKey(CLIENT_SECRET)) data.put(CLIENT_SECRET,"changeme");
return (String) data.get(CLIENT_SECRET);
}
public String dbLocation() {
if (!data.containsKey(DB_FILE)) data.put(DB_FILE,System.getProperty("user.home")+"/.config/widerhall/db.sqlite3");
return (String) data.get(DB_FILE);
}
public String baseDir() {
if (!data.containsKey(Constants.BASE_DIR)) data.put(BASE_DIR,System.getProperty("user.dir")+"/static");
return (String) data.get(BASE_DIR);
public File file() {
return file;
}
}

6
src/main/java/de/srsoftware/widerhall/Constants.java

@ -13,6 +13,8 @@ public class Constants { @@ -13,6 +13,8 @@ public class Constants {
public static final String BASE_URL = "base_url";
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String DB_FILE = "db_file";
public static final String BASE_DIR = "base_dir";
public static final String DB = "database";
public static final String BASE = "base";
public static final String CONFIG = "configuration";
public static final String LOCATIONS = "locations";
}

4
src/main/java/de/srsoftware/widerhall/data/Database.java

@ -127,10 +127,10 @@ public class Database { @@ -127,10 +127,10 @@ public class Database {
public static Database open() {
if (singleton == null){
Configuration config = Configuration.instance();
String dbFile = config.dbLocation();
var dbFile = config.dbFile();
String url = "jdbc:sqlite:"+dbFile;
LOG.debug("Opening {}",url);
new File(dbFile).getParentFile().mkdirs();
dbFile.getParentFile().mkdirs();
try {
singleton = new Database(DriverManager.getConnection(url)).assertTables();
} catch (SQLException sqle) {

24
src/main/java/de/srsoftware/widerhall/web/Static.java → src/main/java/de/srsoftware/widerhall/web/Web.java

@ -6,7 +6,7 @@ import de.srsoftware.widerhall.data.User; @@ -6,7 +6,7 @@ import de.srsoftware.widerhall.data.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupDir;
import org.stringtemplate.v4.STRawGroupDir;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@ -19,17 +19,19 @@ import java.util.Map; @@ -19,17 +19,19 @@ import java.util.Map;
import static de.srsoftware.widerhall.Util.t;
public class Static extends HttpServlet {
public class Web extends HttpServlet {
private static final Logger LOG = LoggerFactory.getLogger(Static.class);
private static final Logger LOG = LoggerFactory.getLogger(Web.class);
private static final String LOGIN = "login";
private final String baseDir;
private final STGroup templates;
private static final String WEB_ROOT = "/web";
public Static(){
public Web(){
var config = Configuration.instance();
baseDir = config.baseDir();
var templateDir = String.join(File.separator,baseDir,"templates");
templates = new STGroupDir(templateDir,'{','}');
var templateDir = String.join(File.separator,baseDir,"static","templates");
templates = new STRawGroupDir(templateDir,'«',');
}
@Override
@ -43,13 +45,11 @@ public class Static extends HttpServlet { @@ -43,13 +45,11 @@ public class Static extends HttpServlet {
path = path == null ? "index" : path.substring(1);
switch (path){
case "css":
return loadFile("style.css",resp);
case "js":
return loadFile("widerhall.js",resp);
case "login":
return loadTemplate(path,null,resp);
case "jquery":
return loadFile("jquery-3.6.0.min.js",resp);
case "login":
return loadTemplate(path, null, resp);
}
var u = req.getSession().getAttribute("user");
@ -77,7 +77,7 @@ public class Static extends HttpServlet { @@ -77,7 +77,7 @@ public class Static extends HttpServlet {
private String loginRedirect(HttpServletResponse resp) {
try {
resp.sendRedirect("/static/login");
resp.sendRedirect(String.join("/",WEB_ROOT,LOGIN));
return null;
} catch (IOException e) {
return t("Was not able to redirect to login page: {}", e.getMessage());
@ -123,7 +123,7 @@ public class Static extends HttpServlet { @@ -123,7 +123,7 @@ public class Static extends HttpServlet {
try {
var user = User.load(email,pass);
req.getSession().setAttribute("user",user);
resp.sendRedirect("/static");
resp.sendRedirect(String.join("/",WEB_ROOT,"index"));
} catch (Exception e) {
try {
LOG.warn("Static.handleLogin failed:",e);

23
static/templates/css.st

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
label {
display: block;
margin: 5px 0;
}
#login form {
width: 450px;
margin: 0 auto;
}
h1 {
text-align: center;
}
.error{
display: block;
text-align: center;
background: orange;
}
.user{
background: lime;
}

11
static/templates/index.st

@ -1,14 +1,13 @@ @@ -1,14 +1,13 @@
index(data) ::= <<
<html>
<head>
<meta charset="utf-8" />
<script src="static/jquery"></script>
<script src="static/js"></script>
<script src="jquery"></script>
<script src="js"></script>
<link rel="stylesheet" href="css" />
</head>
<body>
<span class="user">Logged in as <em>{data.user.name}</em></span>
<span class="user">Logged in as <em>«data.user.name»</em></span>
<h2>Users</h2>
<h2>Lists</h2>
</body>
</html>
>>
</html>

0
static/widerhall.js → static/templates/js.st

56
static/templates/login.st

@ -1,30 +1,28 @@ @@ -1,30 +1,28 @@
login(data) ::= <<
<html>
<head>
<meta charset="utf-8" />
<script src="/static/jquery"></script>
<script src="/static/js"></script>
<link rel="stylesheet" href="/static/css" />
</head>
<body id="login">
<h1>Widerhall login</h1>
{if(data.error)}
<span class="error">{data.error}</span>
{endif}
<form method="POST">
<fieldset>
<legend>Login-Daten</legend>
<label>
<input type="text" name="email" value="" id="email" />
E-Mail-Adresse
</label>
<label>
<input type="password" name="pass" value="" id="password" />
Passwort
</label>
<button type="submit">Einloggen</button>
</fieldset>
</form>
</body>
</html>
>>
<head>
<meta charset="utf-8" />
<script src="jquery"></script>
<script src="js"></script>
<link rel="stylesheet" href="css" />
</head>
<body id="login">
<h1>Widerhall login</h1>
«if(data.error)»
<span class="error">«data.error»</span>
«endif»
<form method="POST">
<fieldset>
<legend>Login-Daten</legend>
<label>
<input type="text" name="email" value="" id="email" />
E-Mail-Adresse
</label>
<label>
<input type="password" name="pass" value="" id="password" />
Passwort
</label>
<button type="submit">Einloggen</button>
</fieldset>
</form>
</body>
</html>
Loading…
Cancel
Save