Merge remote-tracking branch 'origin/master'

# Conflicts:
#	eiam-console/src/main/java/cn/topiam/employee/console/service/analysis/impl/AnalysisServiceImpl.java
pull/65/head
xiuchen 2023-10-05 11:26:57 +08:00
commit 9ff1c96f05
12 changed files with 121 additions and 61 deletions

View File

@ -187,7 +187,7 @@ public class UserEntity extends LogicDeleteEntity<Long> {
*/
@Transient
@JsonIgnore
private String plaintext;
private String passwordPlainText;
@Override
public boolean equals(Object o) {

View File

@ -68,7 +68,7 @@ public class UserRepositoryCustomizedImpl implements UserRepositoryCustomized {
@Override
public Page<UserPO> getUserList(UserListQuery query, Pageable pageable) {
//@formatter:off
StringBuilder builder = new StringBuilder("SELECT `user`.id_, `user`.username_,`user`.password_, `user`.email_, `user`.phone_,`user`.phone_area_code, `user`.full_name ,`user`.nick_name, `user`.avatar_ , `user`.status_, `user`.data_origin, `user`.email_verified, `user`.phone_verified, `user`.auth_total, `user`.last_auth_ip, `user`.last_auth_time, `user`.expand_, `user`.external_id , `user`.expire_date,`user`.create_by, `user`.create_time, `user`.update_by , `user`.update_time, `user`.remark_, group_concat( IF(organization_member.primary_ = 1, null, organization_.display_path ) ) AS primary_org_display_path, group_concat( IF(organization_member.primary_ IS NULL, null, organization_.display_path ) ) AS org_display_path FROM `user` INNER JOIN `organization_member` ON (`user`.id_ = organization_member.user_id) INNER JOIN `organization` organization_ ON (organization_.id_ = organization_member.org_id) WHERE `user`.is_deleted = 0");
StringBuilder builder = new StringBuilder("SELECT `user`.id_, `user`.username_, `user`.password_, `user`.email_, `user`.phone_, `user`.phone_area_code, `user`.full_name, `user`.nick_name, `user`.avatar_, `user`.status_, `user`.data_origin, `user`.email_verified, `user`.phone_verified, `user`.auth_total, `user`.last_auth_ip, `user`.last_auth_time, `user`.expand_, `user`.external_id, `user`.expire_date, `user`.create_by, `user`.create_time, `user`.update_by, `user`.update_time, `user`.remark_, group_concat( IF( organization_member.primary_ = TRUE, organization_.display_path, NULL) ) AS primary_org_display_path, group_concat( IF ( organization_member.primary_ IS NULL, organization_.display_path, NULL ) ) AS org_display_path FROM `user` INNER JOIN `organization_member` ON ( `user`.id_ = organization_member.user_id ) INNER JOIN `organization` organization_ ON ( organization_.id_ = organization_member.org_id ) WHERE `user`.is_deleted = 0 AND organization_member.is_deleted = 0 ");
//组织条件
if (StringUtils.isNotBlank(query.getOrganizationId())) {
if (Boolean.TRUE.equals(query.getInclSubOrganization())) {

View File

@ -88,6 +88,10 @@
<constraints nullable="true"/>
</column>
</addColumn>
<addColumn tableName="administrator">
<column name="full_name" remarks="姓名" type="VARCHAR(100)"/>
<column name="nick_name" remarks="昵称" type="VARCHAR(50)"/>
</addColumn>
<!--创建索引-->
<createIndex tableName="app_group_association" indexName="uk_app_group_association" unique="true">
<column name="group_id"/>

View File

@ -39,7 +39,6 @@ import {
Table,
Tooltip,
Typography,
Tag,
Popover,
} from 'antd';
import React, { useRef, useState } from 'react';
@ -184,44 +183,41 @@ export default (props: UserListProps) => {
dataIndex: 'orgDisplayPath',
search: false,
ellipsis: true,
render: (_, record) => [
<Popover
key="pop"
title={
<Tag color={'geekblue'} key={record.orgDisplayPath}>
{record.primaryOrgDisplayPath}
</Tag>
}
content={
<Space direction="vertical" size="small" style={{ display: 'flex' }}>
{record.orgDisplayPath.split(',')?.map((p: string) => {
return (
<Tag color={'green'} key={p}>
{p}
</Tag>
);
})}
</Space>
}
>
<Space key="primary_path">
{
<Tag color={'geekblue'} key={record.primaryOrgDisplayPath}>
{record.primaryOrgDisplayPath}
</Tag>
}
</Space>
<Space key="path" direction="vertical" size="small" style={{ display: 'flex' }}>
{record.orgDisplayPath.split(',')?.map((p: string) => {
return (
<Tag color={'green'} key={p}>
{p}
</Tag>
);
render: (_, record) => {
return (
<Popover
key="pop"
title={intl.formatMessage({
id: 'pages.account.user_list.user.columns.org_display_path',
})}
</Space>
</Popover>,
],
content={
<>
{record.primaryOrgDisplayPath && (
<Space key="primary_path">{record.primaryOrgDisplayPath}</Space>
)}
{record.orgDisplayPath && (
<Space key="path" direction="vertical" size="small" style={{ display: 'flex' }}>
{record.orgDisplayPath?.split(',')?.map((p: string) => {
return p;
})}
</Space>
)}
</>
}
>
{record.primaryOrgDisplayPath && (
<Space key="primary_path">{record.primaryOrgDisplayPath}</Space>
)}
{record.orgDisplayPath && (
<Space key="path" direction="vertical" size="small" style={{ display: 'flex' }}>
{record.orgDisplayPath?.split(',')?.map((p: string) => {
return p;
})}
</Space>
)}
</Popover>
);
},
},
{
title: intl.formatMessage({ id: 'pages.account.user_list.user.columns.status' }),

View File

@ -181,6 +181,7 @@ declare namespace AccountAPI {
dataOrigin: string;
authTotal: string;
lastAuthTime: string;
primaryOrgDisplayPath: string;
orgDisplayPath: string;
remark: string;
custom?: Record<string, any>;

View File

@ -117,11 +117,17 @@ public class UserListResult implements Serializable {
private LocalDateTime lastAuthTime;
/**
*
*
*/
@Parameter(description = "组织机构目录")
@Parameter(description = "组织机构目录")
private String orgDisplayPath;
/**
*
*/
@Parameter(description = "主组织机构目录")
private String primaryOrgDisplayPath;
/**
*
*/

View File

@ -18,8 +18,11 @@
package cn.topiam.employee.console.service.analysis.impl;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.elasticsearch.client.elc.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@ -35,10 +38,18 @@ import cn.topiam.employee.common.repository.authentication.IdentityProviderRepos
import cn.topiam.employee.console.pojo.query.analysis.AnalysisQuery;
import cn.topiam.employee.console.pojo.result.analysis.*;
import cn.topiam.employee.console.service.analysis.AnalysisService;
import cn.topiam.employee.support.autoconfiguration.SupportProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import co.elastic.clients.json.JsonData;
import static cn.topiam.employee.audit.entity.Event.*;
import static cn.topiam.employee.console.converter.authn.IdentityProviderConverter.getIdentityProviderType;
import static cn.topiam.employee.support.constant.EiamConstants.DEFAULT_DATE_TIME_FORMATTER_PATTERN;
/**
* @author TopIAM
@ -49,6 +60,8 @@ import static cn.topiam.employee.console.converter.authn.IdentityProviderConvert
@RequiredArgsConstructor
public class AnalysisServiceImpl implements AnalysisService {
public static final String COUNT = "count";
/**
*
*
@ -100,6 +113,22 @@ public class AnalysisServiceImpl implements AnalysisService {
return applicationVisitList;
}
/**
*
*
* @param params {@link AnalysisQuery}
* @return {@link Query}
*/
private Query getRangeQueryBuilder(AnalysisQuery params) {
String min = params.getStartTime()
.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMATTER_PATTERN));
String max = params.getEndTime()
.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMATTER_PATTERN));
// 查询条件
return QueryBuilders.range(range -> range.field(EVENT_TIME).timeZone(ZONE_ID)
.format(DEFAULT_DATE_TIME_FORMATTER_PATTERN).gt(JsonData.of(min)).lt(JsonData.of(max)));
}
/**
*
* @param params {@link AnalysisQuery}
@ -124,7 +153,7 @@ public class AnalysisServiceImpl implements AnalysisService {
*
*
* @param params {@link AnalysisQuery}
* @return {@link List<AuthnZoneResult>}
* @return {@link AuthnZoneResult}
*/
@Override
public List<AuthnZoneResult> authnZone(AnalysisQuery params) {
@ -150,6 +179,42 @@ public class AnalysisServiceImpl implements AnalysisService {
return app.getName();
}
/**
*
*
* @param query {@link Query}
* @param eventType {@link EventType}
* @return {@link BoolQuery.Builder}
*/
@NotNull
private BoolQuery.Builder getQueryBuilder(Query query, EventType eventType) {
// 查询条件
BoolQuery.Builder queryBuilder = QueryBuilders.bool();
// 事件类型
queryBuilder.must(Queries.termQueryAsQuery(EVENT_TYPE, eventType.getCode()));
// 日期条件
queryBuilder.filter(query);
return queryBuilder;
}
/**
*
*
* @param query {@link Query}
* @param eventType {@link EventType}
* @return {@link Query}
*/
@NotNull
private Query getQuery(Query query, EventType eventType) {
return getQueryBuilder(query, eventType).build()._toQuery();
}
private final String ZONE_ID = ZoneId.systemDefault().getId();
private final SupportProperties supportProperties;
// private final ElasticsearchTemplate elasticsearchTemplate;
private final AuditRepository auditRepository;
private final AppRepository appRepository;

View File

@ -178,7 +178,7 @@ public class AbstractIdentitySourcePostProcessor {
entity.setDataOrigin(dataOrigin);
entity.setIdentitySourceId(identitySource.getId());
entity.setPassword(passwordEncoder.encode(defaultPassword));
entity.setPlaintext(defaultPassword);
entity.setPasswordPlainText(defaultPassword);
//必须字段
entity.setCreateBy(SYSTEM_DEFAULT_USER_NAME);
@ -302,14 +302,14 @@ public class AbstractIdentitySourcePostProcessor {
thirdPartyUser.getEmail(), thirdPartyUser.getPhone());
if (StringUtils.isNotEmpty(thirdPartyUser.getEmail())) {
Map<String, Object> parameter = new HashMap<>(16);
parameter.put(MsgVariable.PASSWORD, thirdPartyUser.getPlaintext());
parameter.put(MsgVariable.PASSWORD, thirdPartyUser.getPasswordPlainText());
mailMsgEventPublish.publish(MailType.RESET_PASSWORD_CONFIRM,
thirdPartyUser.getEmail(), parameter);
}
if (StringUtils.isNotEmpty(thirdPartyUser.getPhone())) {
LinkedHashMap<String, String> parameter = new LinkedHashMap<>();
parameter.put(USERNAME, thirdPartyUser.getUsername());
parameter.put(MsgVariable.PASSWORD, thirdPartyUser.getPlaintext());
parameter.put(MsgVariable.PASSWORD, thirdPartyUser.getPasswordPlainText());
smsMsgEventPublish.publish(SmsType.RESET_PASSWORD_SUCCESS,
thirdPartyUser.getPhone(), parameter);
}

View File

@ -51,7 +51,7 @@ public interface AccountConverter {
* @param param {@link UpdateUserInfoRequest}
* @return {@link UserEntity}
*/
@Mapping(target = "plaintext", ignore = true)
@Mapping(target = "passwordPlainText", ignore = true)
@Mapping(target = "deleted", ignore = true)
@Mapping(target = "identitySourceId", ignore = true)
@Mapping(target = "phoneVerified", ignore = true)
@ -124,8 +124,8 @@ public interface AccountConverter {
* entityresult
*
* @param identityProviderList {@link List<IdentityProviderEntity>}
* @param userIdpBindList {@link Iterable< UserIdpBindPO >}
* @return {@link List< BoundIdpListResult >}
* @param userIdpBindList {@link Iterable<UserIdpBindPO>}
* @return {@link List<BoundIdpListResult>}
*/
default List<BoundIdpListResult> entityConverterToBoundIdpListResult(List<IdentityProviderEntity> identityProviderList,
Iterable<UserIdpBindPO> userIdpBindList) {

View File

@ -48,12 +48,6 @@ public class UpdateUserInfoRequest implements Serializable {
@Schema(description = "昵称")
private String nickName;
/**
*
*/
@Schema(description = "个人简介")
private String personalProfile;
/**
*
*/

View File

@ -284,11 +284,6 @@ const BaseView = () => {
},
]}
/>
<ProFormTextArea
width="md"
name="personalProfile"
label={intl.formatMessage({ id: 'page.account.base.form.personal_profile' })}
/>
</ProForm>
</div>
<div className={classnames(`${prefixCls}-right`, hashId)}>

View File

@ -27,7 +27,6 @@ export default {
'page.account.base.form.full_name': '姓名',
'page.account.base.form.nick_name': '昵称',
'page.account.base.form.nick_name.rule.0': '请输入您的昵称',
'page.account.base.form.personal_profile': '个人简介',
'page.account.common.form.password': '密码',
'page.account.common.form.password.placeholder': '请输入密码',
'page.account.common.form.password.rule.0': '请输入密码',