组和角色优化,增加角色动态任务,删除resumeTime和suspendTime

This commit is contained in:
MaxKey 2024-09-23 09:52:52 +08:00
parent 0c128ed276
commit 194b8bbe7c
10 changed files with 151 additions and 221 deletions

View File

@ -65,10 +65,6 @@ public class Groups extends JpaEntity implements Serializable {
@Column
String orgIdsList;
@Column
String resumeTime;
@Column
String suspendTime;
@Column
int isdefault;
@ -228,22 +224,6 @@ public class Groups extends JpaEntity implements Serializable {
this.orgIdsList = orgIdsList;
}
public String getResumeTime() {
return resumeTime;
}
public void setResumeTime(String resumeTime) {
this.resumeTime = resumeTime;
}
public String getSuspendTime() {
return suspendTime;
}
public void setSuspendTime(String suspendTime) {
this.suspendTime = suspendTime;
}
public String getInstId() {
return instId;
}
@ -275,10 +255,6 @@ public class Groups extends JpaEntity implements Serializable {
builder.append(filters);
builder.append(", orgIdsList=");
builder.append(orgIdsList);
builder.append(", resumeTime=");
builder.append(resumeTime);
builder.append(", suspendTime=");
builder.append(suspendTime);
builder.append(", isdefault=");
builder.append(isdefault);
builder.append(", description=");

View File

@ -64,10 +64,6 @@ public class Roles extends JpaEntity implements Serializable {
@Column
String orgIdsList;
@Column
String resumeTime;
@Column
String suspendTime;
@Column
int isdefault;
@ -230,22 +226,6 @@ public class Roles extends JpaEntity implements Serializable {
this.orgIdsList = orgIdsList;
}
public String getResumeTime() {
return resumeTime;
}
public void setResumeTime(String resumeTime) {
this.resumeTime = resumeTime;
}
public String getSuspendTime() {
return suspendTime;
}
public void setSuspendTime(String suspendTime) {
this.suspendTime = suspendTime;
}
public String getAppId() {
return appId;
}
@ -285,10 +265,6 @@ public class Roles extends JpaEntity implements Serializable {
builder.append(filters);
builder.append(", orgIdsList=");
builder.append(orgIdsList);
builder.append(", resumeTime=");
builder.append(resumeTime);
builder.append(", suspendTime=");
builder.append(suspendTime);
builder.append(", isdefault=");
builder.append(isdefault);
builder.append(", description=");

View File

@ -18,8 +18,6 @@
package org.dromara.maxkey.persistence.service;
import java.sql.Types;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
@ -35,13 +33,10 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Repository
public class GroupsService extends JpaService<Groups>{
static final Logger _logger = LoggerFactory.getLogger(GroupsService.class);
@JsonIgnore
@Autowired
GroupMemberService groupMemberService;
@ -77,26 +72,6 @@ public class GroupsService extends JpaService<Groups>{
public void refreshDynamicGroups(Groups dynamicGroup){
if(dynamicGroup.getCategory().equals(Roles.Category.DYNAMIC)) {
boolean isDynamicTimeSupport = false;
boolean isBetweenEffectiveTime = false;
if(StringUtils.isNotBlank(dynamicGroup.getResumeTime())
&&StringUtils.isNotBlank(dynamicGroup.getSuspendTime())
&&!dynamicGroup.getSuspendTime().equals("00:00")) {
LocalTime currentTime = LocalDateTime.now().toLocalTime();
LocalTime resumeTime = LocalTime.parse(dynamicGroup.getResumeTime());
LocalTime suspendTime = LocalTime.parse(dynamicGroup.getSuspendTime());
_logger.info("currentTime: {} , resumeTime : {} , suspendTime: {}"
, currentTime
, resumeTime
, suspendTime);
isDynamicTimeSupport = true;
if(resumeTime.isBefore(currentTime) && currentTime.isBefore(suspendTime)) {
isBetweenEffectiveTime = true;
}
}
if(StringUtils.isNotBlank(dynamicGroup.getOrgIdsList())) {
String []orgIds = dynamicGroup.getOrgIdsList().split(",");
@ -120,23 +95,15 @@ public class GroupsService extends JpaService<Groups>{
_logger.info("filters include SQL Injection Attack Risk.");
return;
}
filters = filters.replace("&", " AND ");
filters = filters.replace("|", " OR ");
//replace & with AND, | with OR
filters = filters.replace("&", " AND ").replace("|", " OR ");
dynamicGroup.setFilters(filters);
}
if(isDynamicTimeSupport) {
if(isBetweenEffectiveTime) {
groupMemberService.deleteDynamicMember(dynamicGroup);
groupMemberService.addDynamicMember(dynamicGroup);
}else {
groupMemberService.deleteDynamicMember(dynamicGroup);
}
}else{
groupMemberService.deleteDynamicMember(dynamicGroup);
groupMemberService.addDynamicMember(dynamicGroup);
}
groupMemberService.deleteDynamicMember(dynamicGroup);
groupMemberService.addDynamicMember(dynamicGroup);
}
}

View File

@ -20,8 +20,6 @@
package org.dromara.maxkey.persistence.service;
import java.sql.Types;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
@ -36,13 +34,10 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Repository
public class RolesService extends JpaService<Roles> {
static final Logger _logger = LoggerFactory.getLogger(RolesService.class);
@JsonIgnore
@Autowired
RoleMemberService roleMemberService;
@ -75,24 +70,6 @@ public class RolesService extends JpaService<Roles> {
public void refreshDynamicRoles(Roles dynamicRole){
if(dynamicRole.getCategory().equals(Roles.Category.DYNAMIC)) {
boolean isDynamicTimeSupport = false;
boolean isBetweenEffectiveTime = false;
if(StringUtils.isNotBlank(dynamicRole.getResumeTime())
&&StringUtils.isNotBlank(dynamicRole.getSuspendTime())
&&!dynamicRole.getSuspendTime().equals("00:00")) {
LocalTime currentTime = LocalDateTime.now().toLocalTime();
LocalTime resumeTime = LocalTime.parse(dynamicRole.getResumeTime());
LocalTime suspendTime = LocalTime.parse(dynamicRole.getSuspendTime());
_logger.info("currentTime: {} , resumeTime : {} , suspendTime: {}" ,
currentTime , resumeTime , suspendTime);
isDynamicTimeSupport = true;
if(resumeTime.isBefore(currentTime) && currentTime.isBefore(suspendTime)) {
isBetweenEffectiveTime = true;
}
}
if(StringUtils.isNotBlank(dynamicRole.getOrgIdsList())) {
String []orgIds = dynamicRole.getOrgIdsList().split(",");
@ -117,24 +94,16 @@ public class RolesService extends JpaService<Roles> {
_logger.info("filters include SQL Injection Attack Risk.");
return;
}
filters = filters.replace("&", " AND ");
filters = filters.replaceAll("\\|", " OR ");
//replace & with AND, | with OR
filters = filters.replace("&", " AND ").replace("\\|", " OR ");
_logger.debug("set filters {}" , filters);
dynamicRole.setFilters(filters);
}
if(isDynamicTimeSupport) {
if(isBetweenEffectiveTime) {
roleMemberService.deleteDynamicRoleMember(dynamicRole);
roleMemberService.addDynamicRoleMember(dynamicRole);
}else {
roleMemberService.deleteDynamicRoleMember(dynamicRole);
}
}else{
roleMemberService.deleteDynamicRoleMember(dynamicRole);
roleMemberService.addDynamicRoleMember(dynamicRole);
}
roleMemberService.deleteDynamicRoleMember(dynamicRole);
roleMemberService.addDynamicRoleMember(dynamicRole);
}
}

View File

@ -24,13 +24,8 @@ export class Groups extends BaseEntity {
category!: String;
filters!: String;
orgIdsList!: String;
resumeTime!: String;
suspendTime!: String;
isdefault!: String;
picker_resumeTime: Date = new Date(format(new Date(), 'yyyy-MM-dd 00:00:00'));
picker_suspendTime: Date = new Date(format(new Date(), 'yyyy-MM-dd 00:00:00'));
constructor() {
super();
}
@ -40,13 +35,6 @@ export class Groups extends BaseEntity {
if (this.status == 1) {
this.switch_status = true;
}
if (this.resumeTime != '') {
this.picker_resumeTime = new Date(format(new Date(), `yyyy-MM-dd ${this.resumeTime}:00`));
}
if (this.suspendTime != '') {
this.picker_suspendTime = new Date(format(new Date(), `yyyy-MM-dd ${this.suspendTime}:00`));
}
}
override trans(): void {
if (this.switch_status) {
@ -54,12 +42,5 @@ export class Groups extends BaseEntity {
} else {
this.status = 0;
}
if (this.picker_resumeTime) {
this.resumeTime = format(this.picker_resumeTime, 'HH:mm');
}
if (this.picker_suspendTime) {
this.suspendTime = format(this.picker_suspendTime, 'HH:mm');
}
}
}

View File

@ -1,19 +1,18 @@
/*
* Copyright [2024] [MaxKey of copyright http://www.maxkey.top]
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import format from 'date-fns/format';
@ -27,11 +26,7 @@ export class Roles extends BaseEntity {
category!: String;
filters!: String;
orgIdsList!: String;
resumeTime!: String;
suspendTime!: String;
isdefault!: String;
picker_resumeTime: Date = new Date(format(new Date(), 'yyyy-MM-dd 00:00:00'));
picker_suspendTime: Date = new Date(format(new Date(), 'yyyy-MM-dd 00:00:00'));
constructor() {
super();
@ -45,13 +40,6 @@ export class Roles extends BaseEntity {
} else {
this.switch_status = false;
}
if (this.resumeTime != '') {
this.picker_resumeTime = new Date(format(new Date(), `yyyy-MM-dd ${this.resumeTime}:00`));
}
if (this.suspendTime != '') {
this.picker_suspendTime = new Date(format(new Date(), `yyyy-MM-dd ${this.suspendTime}:00`));
}
}
override trans(): void {
@ -60,11 +48,5 @@ export class Roles extends BaseEntity {
} else {
this.status = 0;
}
if (this.picker_resumeTime) {
this.resumeTime = format(this.picker_resumeTime, 'HH:mm');
}
if (this.picker_suspendTime) {
this.suspendTime = format(this.picker_suspendTime, 'HH:mm');
}
}
}

View File

@ -28,30 +28,6 @@
</nz-radio-group>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="form.model.category == 'dynamic'">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resumeTime">{{ 'mxk.groups.resumeTime' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid port!">
<nz-time-picker
[(ngModel)]="form.model.picker_resumeTime"
[ngModelOptions]="{ standalone: true }"
nzFormat="HH:mm"
name="picker_resumeTime"
id="picker_resumeTime"
></nz-time-picker>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="form.model.category == 'dynamic'">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="suspendTime">{{ 'mxk.groups.suspendTime' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid suspendTime!">
<nz-time-picker
[(ngModel)]="form.model.picker_suspendTime"
[ngModelOptions]="{ standalone: true }"
nzFormat="HH:mm"
name="picker_suspendTime"
id="picker_suspendTime"
></nz-time-picker>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="form.model.category == 'dynamic'">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="orgIdsList">{{ 'mxk.groups.orgIdsList' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid upperCase!">

View File

@ -4,8 +4,7 @@
<nz-form-item class="d-none">
<nz-form-label [nzMd]="6" nzRequired nzFor="id">{{ 'mxk.text.id' | i18n }}</nz-form-label>
<nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
<input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input
name="id" id="id" />
<input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input name="id" id="id" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
@ -19,22 +18,26 @@
<nz-form-item>
<nz-form-label [nzMd]="6" nzRequired nzFor="roleCode">{{ 'mxk.text.id' | i18n }}</nz-form-label>
<nz-form-control [nzMd]="18" nzErrorTip="The input is not valid roleCode!">
<input [(ngModel)]="form.model.roleCode" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }"
nz-input name="roleCode" id="roleCode" />
<input
[(ngModel)]="form.model.roleCode"
disabled="{{ isEdit }}"
[ngModelOptions]="{ standalone: true }"
nz-input
name="roleCode"
id="roleCode"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="name">{{ 'mxk.roles.name' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid minLength!">
<input [(ngModel)]="form.model.roleName" [ngModelOptions]="{ standalone: true }" nz-input name="roleName"
id="roleName" />
<input [(ngModel)]="form.model.roleName" [ngModelOptions]="{ standalone: true }" nz-input name="roleName" id="roleName" />
</nz-form-control>
</nz-form-item>
<nz-form-item style="display: none">
<nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="name">{{ 'mxk.roles.appId' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid minLength!">
<input [(ngModel)]="form.model.appId" [ngModelOptions]="{ standalone: true }" nz-input name="roleName"
id="roleName" />
<input [(ngModel)]="form.model.appId" [ngModelOptions]="{ standalone: true }" nz-input name="roleName" id="roleName" />
</nz-form-control>
</nz-form-item>
@ -48,43 +51,56 @@
</nz-radio-group>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="form.model.category == 'dynamic'">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resumeTime">{{ 'mxk.roles.resumeTime' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid port!">
<nz-time-picker [(ngModel)]="form.model.picker_resumeTime" [ngModelOptions]="{ standalone: true }"
nzFormat="HH:mm" name="picker_resumeTime" id="picker_resumeTime"></nz-time-picker>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="form.model.category == 'dynamic'">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="suspendTime">{{ 'mxk.roles.suspendTime' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid suspendTime!">
<nz-time-picker [(ngModel)]="form.model.picker_suspendTime" [ngModelOptions]="{ standalone: true }"
nzFormat="HH:mm" name="picker_suspendTime" id="picker_suspendTime"></nz-time-picker>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="form.model.category == 'dynamic'">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="orgIdsList">{{ 'mxk.roles.orgIdsList' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid upperCase!">
<input type="hidden" [(ngModel)]="form.model.orgIdsList" [ngModelOptions]="{ standalone: true }" nz-input
name="orgIdsList" id="orgIdsList" />
<nz-tree-select nzVirtualHeight="300px" [nzMaxTagCount]="3" [(ngModel)]="selectValues"
[ngModelOptions]="{ standalone: true }" [nzNodes]="treeNodes.nodes" nzCheckable nzPlaceHolder="Please select"
[nzCheckStrictly]="true">
<input
type="hidden"
[(ngModel)]="form.model.orgIdsList"
[ngModelOptions]="{ standalone: true }"
nz-input
name="orgIdsList"
id="orgIdsList"
/>
<nz-tree-select
nzVirtualHeight="300px"
[nzMaxTagCount]="3"
[(ngModel)]="selectValues"
[ngModelOptions]="{ standalone: true }"
[nzNodes]="treeNodes.nodes"
nzCheckable
nzPlaceHolder="Please select"
[nzCheckStrictly]="true"
>
</nz-tree-select>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="form.model.category == 'dynamic'">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="filters">{{ 'mxk.roles.filters' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid filters!">
<textarea rows="4" nz-input [(ngModel)]="form.model.filters" [ngModelOptions]="{ standalone: true }" nz-input
name="filters" id="filters"></textarea>
<textarea
rows="4"
nz-input
[(ngModel)]="form.model.filters"
[ngModelOptions]="{ standalone: true }"
nz-input
name="filters"
id="filters"
></textarea>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="description">{{ 'mxk.text.description' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid encoding!">
<textarea rows="4" nz-input [(ngModel)]="form.model.description" [ngModelOptions]="{ standalone: true }"
nz-input name="description" id="description"></textarea>
<textarea
rows="4"
nz-input
[(ngModel)]="form.model.description"
[ngModelOptions]="{ standalone: true }"
nz-input
name="description"
id="description"
></textarea>
</nz-form-control>
</nz-form-item>
</form>
@ -93,4 +109,4 @@
<div *nzModalFooter>
<button nz-button nzType="default" (click)="onClose($event)">{{ 'mxk.text.close' | i18n }}</button>
<button nz-button nzType="primary" (click)="onSubmit($event)">{{ 'mxk.text.submit' | i18n }}</button>
</div>
</div>

View File

@ -20,11 +20,13 @@ package org.dromara.maxkey.autoconfigure;
import org.dromara.maxkey.authn.session.SessionManager;
import org.dromara.maxkey.configuration.ApplicationConfig;
import org.dromara.maxkey.listener.DynamicGroupsListenerAdapter;
import org.dromara.maxkey.listener.DynamicRolesListenerAdapter;
import org.dromara.maxkey.listener.ReorgDeptListenerAdapter;
import org.dromara.maxkey.listener.SessionListenerAdapter;
import org.dromara.maxkey.persistence.service.ConnectorsService;
import org.dromara.maxkey.persistence.service.GroupsService;
import org.dromara.maxkey.persistence.service.OrganizationsService;
import org.dromara.maxkey.persistence.service.RolesService;
import org.dromara.maxkey.provision.thread.ProvisioningRunner;
import org.dromara.maxkey.provision.thread.ProvisioningRunnerThread;
import org.dromara.maxkey.schedule.ScheduleAdapterBuilder;
@ -85,6 +87,23 @@ public class MaxKeyMgtListenerConfig {
logger.debug("DynamicGroups ListenerAdapter inited .");
return "dynamicGroupsListenerAdapter";
}
@Bean
String dynamicRolesListenerAdapter(
Scheduler scheduler,
RolesService rolesService,
@Value("${maxkey.job.cron.schedule}") String cronSchedule
) throws SchedulerException {
new ScheduleAdapterBuilder()
.setScheduler(scheduler)
.setCron(cronSchedule)
.setJobClass(DynamicRolesListenerAdapter.class)
.setJobData("rolesService",rolesService)
.build();
logger.debug("Dynamic Roles ListenerAdapter inited .");
return "dynamicRolesListenerAdapter";
}
@Bean
String provisioningRunnerThread(

View File

@ -0,0 +1,68 @@
/*
* Copyright [2024] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dromara.maxkey.listener;
import java.io.Serializable;
import org.dromara.maxkey.persistence.service.RolesService;
import org.dromara.maxkey.schedule.ScheduleAdapter;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DynamicRolesListenerAdapter extends ScheduleAdapter implements Job , Serializable {
/**
*
*/
private static final long serialVersionUID = 7000735366821127880L;
static final Logger logger = LoggerFactory.getLogger(DynamicRolesListenerAdapter.class);
transient RolesService rolesService;
@Override
public void execute(JobExecutionContext context){
if(jobStatus == JOBSTATUS.RUNNING) {return;}
init(context);
logger.debug("running ... " );
jobStatus = JOBSTATUS.RUNNING;
try {
if(rolesService != null) {
rolesService.refreshAllDynamicRoles();
Thread.sleep(10 * 1000);//10 minutes
}
logger.debug("finished " );
jobStatus = JOBSTATUS.FINISHED;
}catch(Exception e) {
jobStatus = JOBSTATUS.ERROR;
logger.error("Exception " ,e);
}
}
@Override
protected void init(JobExecutionContext context){
super.init(context);
if(rolesService == null) {
rolesService = getParameter("rolesService",RolesService.class);
}
}
}