Merge branch 'master' into develop

This commit is contained in:
devezhao-mbp 2020-04-29 21:13:23 +08:00
commit a6e883b706
13 changed files with 123 additions and 84 deletions

48
pom.xml
View file

@ -1,6 +1,4 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rebuild</groupId>
@ -11,12 +9,12 @@
<description>Building your business-systems free!</description>
<url>https://getrebuild.com/</url>
<developers>
<developer>
<name>devezhao</name>
<email>zhaofang123@gmail.com</email>
</developer>
</developers>
<developers>
<developer>
<name>devezhao</name>
<email>zhaofang123@gmail.com</email>
</developer>
</developers>
<licenses>
<license>
@ -158,11 +156,11 @@
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
@ -317,11 +315,11 @@
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
@ -332,10 +330,10 @@
<artifactId>thumbnailator</artifactId>
<version>0.4.11</version>
</dependency>
<dependency>
<groupId>es.moki.ratelimitj</groupId>
<artifactId>ratelimitj-inmemory</artifactId>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>es.moki.ratelimitj</groupId>
<artifactId>ratelimitj-inmemory</artifactId>
<version>0.6.0</version>
</dependency>
</dependencies>
</project>
</project>

View file

@ -18,6 +18,7 @@ import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.rebuild.api.ApiGateway;
import com.rebuild.api.BaseApi;
import com.rebuild.server.helper.AesPreferencesConfigurer;
import com.rebuild.server.helper.ConfigurableItem;
import com.rebuild.server.helper.SysConfiguration;
import com.rebuild.server.helper.cache.CommonCache;
@ -67,7 +68,7 @@ public final class Application {
public static final String VER = "1.10.0-dev";
/** Rebuild Build
*/
public static final int BUILD = 1090;
public static final int BUILD = 1091;
/** Logging for Global
*/
@ -193,7 +194,8 @@ public final class Application {
if (APPLICATION_CTX == null) {
debugMode = true;
LOG.info("Rebuild Booting in DEBUG mode ...");
AesPreferencesConfigurer.initApplicationProperties();
long at = System.currentTimeMillis();
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] { "application-ctx.xml" });
new Application(ctx).init(at);

View file

@ -9,6 +9,7 @@ package com.rebuild.server;
import cn.devezhao.commons.CalendarUtils;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.server.helper.AesPreferencesConfigurer;
import com.rebuild.server.helper.ConfigurableItem;
import com.rebuild.server.helper.License;
import com.rebuild.server.helper.SysConfiguration;
@ -56,6 +57,8 @@ public class ServerListener extends ContextCleanupListener implements InstallSta
event.getServletContext().setAttribute("baseUrl", CONTEXT_PATH);
try {
AesPreferencesConfigurer.initApplicationProperties();
if (!checkInstalled()) {
eventHold = event;
LOG.warn(Application.formatFailure("REBUILD IS WAITING FOR INSTALL ..."));

View file

@ -106,12 +106,11 @@ public final class ServerStatus {
return Status.success(name);
}
AesPreferencesConfigurer configurer = Application.getBean(AesPreferencesConfigurer.class);
try {
Connection c = DriverManager.getConnection(
configurer.getItem("db.url"),
configurer.getItem("db.user"),
configurer.getItem("db.passwd"));
AesPreferencesConfigurer.getItem("db.url"),
AesPreferencesConfigurer.getItem("db.user"),
AesPreferencesConfigurer.getItem("db.passwd"));
SqlHelper.close(c);
} catch (Exception ex) {
return Status.error(name, ThrowableUtils.getRootCause(ex).getLocalizedMessage());

View file

@ -18,17 +18,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
package com.rebuild.server.helper;
import com.rebuild.server.Application;
import com.rebuild.server.helper.setup.InstallState;
import com.rebuild.server.helper.setup.SetupException;
import com.rebuild.utils.AES;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
@ -39,12 +44,18 @@ import java.util.Properties;
*/
public class AesPreferencesConfigurer extends PreferencesPlaceholderConfigurer implements InstallState {
private Properties propsHold = null;
private static final Log LOG = LogFactory.getLog(AesPreferencesConfigurer.class);
private static Properties propsHold = null;
@Override
protected void loadProperties(Properties props) throws IOException {
super.loadProperties(props);
props.putAll(fromInstallFile());
this.afterLoad(props);
LOG.info("Application properties : " + props);
setNullValue(StringUtils.EMPTY);
}
@ -52,8 +63,6 @@ public class AesPreferencesConfigurer extends PreferencesPlaceholderConfigurer i
* @param props
*/
private void afterLoad(Properties props) {
props.putAll(fromInstallFile());
final Object[] keys = props.keySet().toArray(new Object[0]);
for (Object key : keys) {
String cleanKey = key.toString();
@ -87,13 +96,6 @@ public class AesPreferencesConfigurer extends PreferencesPlaceholderConfigurer i
setIfEmpty(props, ConfigurableItem.CachePort, "6379");
propsHold = (Properties) props.clone();
if (propsHold.getProperty("db.url").contains("jdbc:h2:")) {
Application.LOG.warn("Using QuickMode with H2 database!");
}
if (Application.devMode()) {
Application.LOG.info("System properties : " + propsHold);
}
}
/**
@ -125,13 +127,29 @@ public class AesPreferencesConfigurer extends PreferencesPlaceholderConfigurer i
}
}
// --
/**
* @throws IOException
*/
public static void initApplicationProperties() throws IOException {
if (propsHold != null) return;
File file = ResourceUtils.getFile("classpath:application.properties");
try (InputStream is = new FileInputStream(file)) {
Properties props = new Properties();
props.load(is);
new AesPreferencesConfigurer().afterLoad(props);
}
}
/**
* 获取配置项
*
* @param name
* @return
*/
public String getItem(String name) {
public static String getItem(String name) {
Assert.notNull(propsHold, "Rebuild unstarted");
return StringUtils.defaultIfBlank(propsHold.getProperty(name), null);
}
}

View file

@ -21,7 +21,6 @@ package com.rebuild.server.helper;
import cn.devezhao.persist4j.Record;
import cn.devezhao.persist4j.engine.ID;
import com.rebuild.server.Application;
import com.rebuild.server.helper.cache.CommonCache;
import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.service.bizz.UserService;
import org.apache.commons.lang.StringUtils;
@ -88,37 +87,38 @@ public class KVStorage {
* @return
*/
protected static String getValue(final String key, boolean reload, Object defaultValue) {
if (!Application.serversReady()) {
return defaultValue == null ? null : defaultValue.toString();
String value = null;
if (Application.serversReady()) {
value = Application.getCommonCache().get(key);
if (value != null && !reload) {
return value;
}
// 1. 首先从数据库
Object[] fromDb = Application.createQueryNoFilter(
"select value from SystemConfig where item = ?")
.setParameter(1, key)
.unique();
value = fromDb == null ? null : StringUtils.defaultIfBlank((String) fromDb[0], null);
}
String cached = Application.getCommonCache().get(key);
if (cached != null && !reload) {
return cached;
}
// 1. 首先从数据库
Object[] fromDb = Application.createQueryNoFilter(
"select value from SystemConfig where item = ?")
.setParameter(1, key)
.unique();
cached = fromDb == null ? null : StringUtils.defaultIfBlank((String) fromDb[0], null);
// 2. 从配置文件加载
if (cached == null) {
cached = Application.getBean(AesPreferencesConfigurer.class).getItem(key);
// 2. 从配置文件/命令行加载
if (value == null) {
value = AesPreferencesConfigurer.getItem(key);
}
// 3. 默认值
if (cached == null && defaultValue != null) {
cached = defaultValue.toString();
if (value == null && defaultValue != null) {
value = defaultValue.toString();
}
if (cached == null) {
Application.getCommonCache().evict(key);
} else {
Application.getCommonCache().put(key, cached);
if (Application.serversReady()) {
if (value == null) {
Application.getCommonCache().evict(key);
} else {
Application.getCommonCache().put(key, value);
}
}
return cached;
return value;
}
}

View file

@ -42,11 +42,15 @@ public final class License {
SN = SysConfiguration.get(ConfigurableItem.SN, true);
if (SN == null) {
try {
JSONObject result = siteApi("api/authority/new?ver=" + Application.VER, false);
if (result != null) {
SN = result.getString("sn");
String apiUrl = String.format("https://getrebuild.com/api/authority/new?ver=%s&k=%s", Application.VER, OSA_KEY);
String result = CommonsUtils.get(apiUrl);
if (JSONUtils.wellFormat(result)) {
JSONObject o = JSON.parseObject(result);
SN = o.getString("sn");
SysConfiguration.set(ConfigurableItem.SN, SN);
}
} catch (Exception ignored) {
// UNCATCHABLE
}

View file

@ -8,7 +8,6 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.server.helper.setup;
import cn.devezhao.commons.CalendarUtils;
import com.rebuild.server.Application;
import com.rebuild.server.helper.AesPreferencesConfigurer;
import com.rebuild.server.helper.ConfigurableItem;
import com.rebuild.server.helper.SysConfiguration;
@ -41,9 +40,9 @@ public class DatabaseBackup {
* @throws IOException
*/
public File backup() throws IOException {
String url = Application.getBean(AesPreferencesConfigurer.class).getItem("db.url");
String user = Application.getBean(AesPreferencesConfigurer.class).getItem("db.user");
String passwd = Application.getBean(AesPreferencesConfigurer.class).getItem("db.passwd");
String url = AesPreferencesConfigurer.getItem("db.url");
String user = AesPreferencesConfigurer.getItem("db.user");
String passwd = AesPreferencesConfigurer.getItem("db.passwd");
url = url.split("\\?")[0].split("//")[1];
String host = url.split(":")[0];

View file

@ -22,7 +22,7 @@ import java.io.File;
public interface InstallState {
/**
* 状态文件位置 /.rebuild/.rebuild
* 安装文件位置 /.rebuild/.rebuild
*/
String INSTALL_FILE = ".rebuild";

View file

@ -307,7 +307,7 @@ public class Installer implements InstallState {
* @return
*/
public static boolean isUseH2() {
String dbUrl = Application.getBean(AesPreferencesConfigurer.class).getItem("db.url");
String dbUrl = AesPreferencesConfigurer.getItem("db.url");
return dbUrl.startsWith("jdbc:h2:");
}
}

View file

@ -18,10 +18,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
package com.rebuild.utils;
import com.rebuild.server.Application;
import com.rebuild.server.RebuildException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
@ -33,7 +34,9 @@ import javax.crypto.spec.SecretKeySpec;
* @since 2017-1-2
*/
public class AES {
private static final Log LOG = LogFactory.getLog(AES.class);
/**
* @param input
* @return
@ -58,7 +61,7 @@ public class AES {
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes());
} catch (Exception ex) {
throw new RebuildException("Encrypt error : " + input, ex);
throw new RebuildException("Encrypting error : " + input, ex);
}
return new String(Base64.encodeBase64(crypted));
}
@ -103,11 +106,24 @@ public class AES {
cipher.init(Cipher.DECRYPT_MODE, skey);
output = cipher.doFinal(Base64.decodeBase64(input));
} catch (Exception ex) {
throw new RebuildException("Decrypt error : " + input, ex);
throw new RebuildException("Decrypting error : " + input, ex);
}
return new String(output);
}
/**
* @param input
* @return
*/
public static String decryptNothrow(String input) {
try {
return decrypt(input);
} catch (RebuildException ex) {
LOG.warn("Decrypting error (Use blank input) : " + input);
return StringUtils.EMPTY;
}
}
/**
* 通过 `-Drbpass=KEY` 指定 AES 秘钥
*

View file

@ -83,7 +83,7 @@
<td data-id="MarkWatermark" data-options="true:是;false:否">${MarkWatermark ? "是" : "否"}</td>
</tr>
<tr>
<td>数据库自动备份<p>每日0点备份到数据目录,请预留足够磁盘空间</p></td>
<td>数据库自动备份<p>每日 0 点备份到数据目录,请预留足够磁盘空间</p></td>
<td data-id="DBBackupsEnable" data-options="true:是;false:否">${DBBackupsEnable ? "是" : "否"}</td>
</tr>
</tbody>

View file

@ -102,7 +102,7 @@
<button class="btn btn-primary btn-xl" type="submit" data-spinner>${bundle.lang('Login')}</button>
<div class="mt-4 text-center">${bundle.lang('NoAccountYet')}&nbsp;<a href="signup">${bundle.lang('SignupNow')}</a></div>
</div>
<div class="select-lang text-center mb-2">
<div class="select-lang text-center mb-2 dev-show">
<a href="?locale=zh_CN" title="中文"><img src="${baseUrl}/assets/img/flag/zh-CN.png" /></a>
<a href="?locale=en" title="English"><img src="${baseUrl}/assets/img/flag/en-US.png" /></a>
<a href="?locale=ja" title="日本語"><img src="${baseUrl}/assets/img/flag/ja-JP.png" /></a>