Skip to content

Commit cba4107

Browse files
authored
Merge pull request #55 from jumpserver/dev
v4.3.0
2 parents 24a6ffb + 74777b9 commit cba4107

File tree

12 files changed

+1424
-240
lines changed

12 files changed

+1424
-240
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM jumpserver/chen-base:20240913_102042 AS stage-build
1+
FROM jumpserver/chen-base:20241009_104417 AS stage-build
22
ENV LANG=en_US.UTF-8
33

44
WORKDIR /opt/chen/

Dockerfile-base

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ RUN set -ex \
2929
&& chmod 755 /usr/local/bin/check \
3030
&& rm -f check-${CHECK_VERSION}-linux-${TARGETARCH}.tar.gz
3131

32-
ARG WISP_VERSION=v0.2.1
32+
ARG WISP_VERSION=v0.2.2
3333
RUN set -ex \
3434
&& wget https://github.com/jumpserver/wisp/releases/download/${WISP_VERSION}/wisp-${WISP_VERSION}-linux-${TARGETARCH}.tar.gz \
3535
&& tar -xf wisp-${WISP_VERSION}-linux-${TARGETARCH}.tar.gz -C /usr/local/bin/ --strip-components=1 \

backend/framework/src/main/java/org/jumpserver/chen/framework/console/dataview/DataView.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.jumpserver.chen.framework.session.SessionManager;
1515
import org.jumpserver.chen.framework.ws.io.PacketIO;
1616

17+
import java.io.BufferedWriter;
1718
import java.io.IOException;
1819
import java.nio.file.Files;
1920
import java.sql.SQLException;
@@ -125,6 +126,15 @@ private void fullData(SQLQueryResult result) {
125126
}
126127
}
127128

129+
private static void writeString(BufferedWriter writer, Object object) throws IOException {
130+
var str = object.toString();
131+
132+
if (str.contains(",")) {
133+
str = "\"" + str + "\"";
134+
}
135+
writer.write(str);
136+
}
137+
128138
public void export(String scope) throws SQLException {
129139
var session = SessionManager.getCurrentSession();
130140

@@ -144,7 +154,7 @@ public void export(String scope) throws SQLException {
144154

145155
if (scope.equals("current")) {
146156
for (Field field : this.data.getFields()) {
147-
writer.write(field.getName());
157+
writeString(writer, field.getName());
148158
writer.write(",");
149159
}
150160
writer.newLine();
@@ -155,7 +165,7 @@ public void export(String scope) throws SQLException {
155165
writer.write("NULL");
156166
writer.write(",");
157167
} else {
158-
writer.write(row.get(field.getName()).toString());
168+
writeString(writer, row.get(field.getName()));
159169
writer.write(",");
160170
}
161171
}

backend/framework/src/main/java/org/jumpserver/chen/framework/session/impl/JMSSession.java

+64-13
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.jumpserver.chen.framework.jms.impl.ReplayHandlerImpl;
1818
import org.jumpserver.chen.framework.session.QueryAuditFunction;
1919
import org.jumpserver.chen.framework.session.SessionManager;
20+
import org.jumpserver.chen.framework.session.controller.dialog.Button;
2021
import org.jumpserver.chen.framework.session.controller.dialog.Dialog;
2122
import org.jumpserver.chen.framework.session.controller.message.MessageLevel;
2223
import org.jumpserver.chen.framework.session.exception.SessionException;
@@ -27,8 +28,11 @@
2728

2829
import java.sql.Connection;
2930
import java.sql.SQLException;
30-
import java.text.SimpleDateFormat;
31+
import java.time.Duration;
3132
import java.time.Instant;
33+
import java.time.LocalDateTime;
34+
import java.time.ZoneOffset;
35+
import java.time.format.DateTimeFormatter;
3236
import java.util.List;
3337

3438
@Slf4j
@@ -45,9 +49,15 @@ public class JMSSession extends BaseSession {
4549
private final List<Common.CommandACL> commandACLs;
4650
private final long maxIdleTimeDelta;
4751
private final long expireTime;
48-
private long lastActiveTime;
4952

50-
private int maxSessionTime;
53+
54+
private LocalDateTime lastActiveTime;
55+
56+
private LocalDateTime maxSessionEndTime;
57+
private int maxSessionEndHours;
58+
private LocalDateTime dynamicEndTime;
59+
private String dynamicEndReason;
60+
5161
private Thread waitIdleTimeThread;
5262
@Setter
5363
private String gatewayId;
@@ -86,13 +96,41 @@ public JMSSession(Common.Session session,
8696
this.commandACLs = tokenResp.getData().getFilterRulesList();
8797
this.expireTime = tokenResp.getData().getExpireInfo().getExpireAt();
8898
this.maxIdleTimeDelta = tokenResp.getData().getSetting().getMaxIdleTime();
89-
this.maxSessionTime = tokenResp.getData().getSetting().getMaxSessionTime();
99+
100+
this.maxSessionEndHours = tokenResp.getData().getSetting().getMaxSessionTime();
101+
this.maxSessionEndTime = LocalDateTime.now().plusHours(tokenResp.getData().getSetting().getMaxSessionTime());
102+
this.dynamicEndTime = this.maxSessionEndTime;
103+
90104
this.canUpload = tokenResp.getData().getPermission().getEnableUpload();
91105
this.canDownload = tokenResp.getData().getPermission().getEnableDownload();
92106
this.canCopy = tokenResp.getData().getPermission().getEnableCopy();
93107
this.canPaste = tokenResp.getData().getPermission().getEnablePaste();
94108
}
95109

110+
111+
public void setDynamicEndInfo(String reason) {
112+
113+
SessionManager.setContext(this.getWebToken());
114+
115+
this.dynamicEndReason = reason;
116+
this.dynamicEndTime = LocalDateTime.now().plusMinutes(10);
117+
118+
var dialog = new Dialog(MessageUtils.get("PermissionExpiredDialogTitle"));
119+
120+
dialog.setBody(MessageUtils.get("PermissionExpiredDialogMessage"));
121+
122+
dialog.addButton(new Button(MessageUtils.get("Cancel"), "cancel", () -> this.getController().closeDialog()));
123+
124+
this.getController().showDialog(dialog);
125+
126+
}
127+
128+
public void resetDynamicEndInfo() {
129+
this.dynamicEndReason = "";
130+
this.dynamicEndTime = this.maxSessionEndTime;
131+
}
132+
133+
96134
@Override
97135
public void recordCommand(String command) {
98136
CommandRecord commandRecord = new CommandRecord(command);
@@ -167,27 +205,40 @@ private void recordLifecycle(ServiceOuterClass.SessionLifecycleLogRequest.EventT
167205
}
168206

169207
private void startWaitIdleTime() {
170-
this.lastActiveTime = System.currentTimeMillis();
208+
this.lastActiveTime = LocalDateTime.now();
209+
210+
var token = SessionManager.getContextToken();
211+
171212
this.waitIdleTimeThread = new Thread(() -> {
213+
SessionManager.setContext(token);
214+
172215
while (this.isActive()) {
173216
try {
174217
Thread.sleep(5000);
218+
175219
synchronized (this) {
176-
long now = System.currentTimeMillis();
177-
var expireTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(this.expireTime * 1000);
178-
if (now > this.expireTime * 1000) {
179-
this.close("PermissionsExpiredOn", "permission_expired", expireTime);
220+
var expireTime = LocalDateTime.ofEpochSecond(this.expireTime, 0, ZoneOffset.ofHours(8));
221+
222+
if (LocalDateTime.now().isAfter(expireTime)) {
223+
this.close("PermissionsExpiredOn", "permission_expired", expireTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
180224
return;
181225
}
182-
if (now - this.lastActiveTime > this.maxIdleTimeDelta * 1000 * 60) {
226+
227+
if (Math.abs(Duration.between(LocalDateTime.now(), this.lastActiveTime).toMinutes()) > this.maxIdleTimeDelta) {
183228
this.close("OverMaxIdleTimeError", "idle_disconnect", this.maxIdleTimeDelta);
184229
return;
185230
}
186231

187-
if (now - this.lastActiveTime > (long) this.maxSessionTime * 1000 * 60 * 60) {
188-
this.close("OverMaxSessionTimeError", "max_session_timeout", this.maxSessionTime);
232+
if (LocalDateTime.now().isAfter(this.maxSessionEndTime)) {
233+
this.close("OverMaxSessionTimeError", "max_session_timeout", this.maxSessionEndHours);
189234
return;
190235
}
236+
237+
if (LocalDateTime.now().isAfter(this.dynamicEndTime)) {
238+
this.close("PermissionAlreadyExpired", this.dynamicEndReason);
239+
return;
240+
}
241+
191242
}
192243
} catch (InterruptedException e) {
193244
log.info("JMSSession waitIdleTimeThread interrupted, close it");
@@ -259,7 +310,7 @@ private void closeGateway() {
259310
@Override
260311
public SQLQueryResult withAudit(String command, QueryAuditFunction queryAuditFunction) throws SQLException, CommandRejectException {
261312
synchronized (this) {
262-
this.lastActiveTime = System.currentTimeMillis();
313+
this.lastActiveTime = LocalDateTime.now();
263314
}
264315
if (this.locked) {
265316
throw new CommandRejectException(MessageUtils.get("SessionLockedError"));

backend/modules/src/main/java/org.jumpserver.chen.modules/postgresql/PostgresqlActuator.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ public List<String> getSchemas() throws SQLException {
3333

3434
@Override
3535
public void changeSchema(String schema) throws SQLException {
36-
this.execute(SQL.of("SET SEARCH_PATH TO ?;", schema));
36+
this.execute(SQL.of("SET SEARCH_PATH TO '?';", schema));
3737
}
3838

3939
@Override
4040
public SQLExecutePlan createPlan(String schema, String table, SQLQueryParams sqlQueryParams) throws SQLException {
41-
var sql = SQL.of("select * from ?.?", schema, table);
41+
var sql = SQL.of("select * from \"?\".\"?\"", schema, table);
4242
return this.createPlan(sql, sqlQueryParams);
4343
}
4444
}

backend/web/src/main/java/org/jumpserver/chen/web/hook/RegisterJMSEvent.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,14 @@ public void onNext(ServiceOuterClass.TaskResponse taskResponse) {
7878
if (targetSession != null) {
7979
switch (taskResponse.getTask().getAction()) {
8080
case KillSession ->
81-
targetSession.close("SessionClosedBy","admin_terminate", taskResponse.getTask().getTerminatedBy());
81+
targetSession.close("SessionClosedBy", "admin_terminate", taskResponse.getTask().getTerminatedBy());
8282

8383
case LockSession -> targetSession.lockSession(taskResponse.getTask().getCreatedBy());
8484
case UnlockSession ->
8585
targetSession.unloadSession(taskResponse.getTask().getCreatedBy());
86+
case TokenPermExpired ->
87+
targetSession.setDynamicEndInfo(taskResponse.getTask().getTokenStatus().getDetail());
88+
case TokenPermValid -> targetSession.resetDynamicEndInfo();
8689
}
8790
var req = ServiceOuterClass.FinishedTaskRequest
8891
.newBuilder()

backend/web/src/main/java/org/jumpserver/chen/web/service/impl/JmsSessionService.java

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ private Common.Session createJMSSession(ServiceOuterClass.TokenResponse tokenRes
126126
.setProtocol(tokenResp.getData().getAsset().getProtocols(0).getName())
127127
.setDateStart(System.currentTimeMillis() / 1000)
128128
.setRemoteAddr(remoteAddr)
129+
.setTokenId(tokenResp.getData().getKeyId())
129130
.build();
130131

131132
var sessionResp = this.serviceBlockingStub.createSession(

0 commit comments

Comments
 (0)