Merge pull request #1634 from dataease/pr@dev@feat_default_pwd

feat: 默认密码
This commit is contained in:
fit2cloud-chenyw 2022-01-12 17:47:26 +08:00 committed by GitHub
commit a23e2601d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 184 additions and 61 deletions

View File

@ -13,31 +13,27 @@ import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@Api(tags = "权限:权限管理")
@ApiSupport(order = 10)
@RequestMapping("/api/auth")
public interface AuthApi {
@ApiOperation("登录")
@PostMapping("/login")
Object login(LoginDto loginDto) throws Exception;
@ApiOperation("获取用户信息")
@PostMapping("/userInfo")
CurrentUserDto userInfo();
@ApiOperation("是否使用初始密码")
@PostMapping("/useInitPwd")
Boolean useInitPwd();
@ApiOperation("登出")
@PostMapping("/logout")
String logout();
@ApiOperation("验证账号")
@PostMapping("/validateName")
Boolean validateName(Map<String, String> nameDto);
@ -46,7 +42,6 @@ public interface AuthApi {
@PostMapping("/isOpenLdap")
boolean isOpenLdap();
@ApiOperation("是否开启oidc")
@PostMapping("/isOpenOidc")
boolean isOpenOidc();

View File

@ -27,6 +27,7 @@ import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@ -40,6 +41,9 @@ import javax.servlet.http.HttpServletRequest;
@RestController
public class AuthServer implements AuthApi {
@Value("${dataease.init_password:DataEase123..}")
private String DEFAULT_PWD;
@Autowired
private AuthUserService authUserService;
@ -65,14 +69,19 @@ public class AuthServer implements AuthApi {
SysUserEntity user = authUserService.getLdapUserByName(username);
if (ObjectUtils.isEmpty(user) || ObjectUtils.isEmpty(user.getUserId())) {
LdapAddRequest ldapAddRequest = new LdapAddRequest();
ldapAddRequest.setUsers(new ArrayList<XpackLdapUserEntity>() {{
add(ldapUserEntity);
}});
ldapAddRequest.setUsers(new ArrayList<XpackLdapUserEntity>() {
{
add(ldapUserEntity);
}
});
ldapAddRequest.setEnabled(1L);
ldapAddRequest.setRoleIds(new ArrayList<Long>() {{
add(2L);
}});
sysUserService.validateExistUser(ldapUserEntity.getUsername(), ldapUserEntity.getNickname(), ldapUserEntity.getEmail());
ldapAddRequest.setRoleIds(new ArrayList<Long>() {
{
add(2L);
}
});
sysUserService.validateExistUser(ldapUserEntity.getUsername(), ldapUserEntity.getNickname(),
ldapUserEntity.getEmail());
sysUserService.saveLdapUsers(ldapAddRequest);
}
@ -92,9 +101,9 @@ public class AuthServer implements AuthApi {
// 普通登录需要验证密码
if (loginType == 0 || !isSupportLdap) {
//私钥解密
// 私钥解密
//md5加密
// md5加密
pwd = CodingUtil.md5(pwd);
if (!StringUtils.equals(pwd, realPwd)) {
@ -128,6 +137,16 @@ public class AuthServer implements AuthApi {
return userDto;
}
@Override
public Boolean useInitPwd() {
CurrentUserDto user = AuthUtils.getUser();
if (null == user) {
return false;
}
String md5 = CodingUtil.md5(DEFAULT_PWD);
return StringUtils.equals(AuthUtils.getUser().getPassword(), md5);
}
@Override
public String logout() {
String token = ServletUtils.getToken();
@ -158,7 +177,8 @@ public class AuthServer implements AuthApi {
@Override
public Boolean validateName(@RequestBody Map<String, String> nameDto) {
String userName = nameDto.get("userName");
if (StringUtils.isEmpty(userName)) return false;
if (StringUtils.isEmpty(userName))
return false;
SysUserEntity userEntity = authUserService.getUserByName(userName);
return !ObjectUtils.isEmpty(userEntity);
}
@ -166,29 +186,30 @@ public class AuthServer implements AuthApi {
@Override
public boolean isOpenLdap() {
Boolean licValid = PluginUtils.licValid();
if (!licValid) return false;
if (!licValid)
return false;
return authUserService.supportLdap();
}
@Override
public boolean isOpenOidc() {
Boolean licValid = PluginUtils.licValid();
if (!licValid) return false;
if (!licValid)
return false;
return authUserService.supportOidc();
}
@Override
public boolean isPluginLoaded() {
Boolean licValid = PluginUtils.licValid();
if (!licValid) return false;
if (!licValid)
return false;
return authUserService.pluginLoaded();
}
@Override
public String getPublicKey() {
return RsaProperties.publicKey;
}
}

View File

@ -22,6 +22,13 @@ export function logout() {
})
}
export function needModifyPwd() {
return request({
url: '/api/auth/useInitPwd',
method: 'post'
})
}
export function validateUserName(data) {
return request({
url: '/api/auth/validateName',

View File

@ -131,6 +131,8 @@ export default {
default_login: 'Normal'
},
commons: {
first_login_tips: 'Please change the initial password',
roger_that: 'Roger That',
apply: 'Apply',
search: 'Search',
folder: 'Folder',

View File

@ -131,6 +131,8 @@ export default {
default_login: '普通登錄'
},
commons: {
first_login_tips: '您使用的是初始密碼,記得修改密碼哦',
roger_that: '知道了',
apply: '應用',
search: '搜索',
folder: '目錄',

View File

@ -131,6 +131,8 @@ export default {
default_login: '普通登录'
},
commons: {
first_login_tips: '您使用的是初始密码,记得修改密码哦',
roger_that: '知道了',
apply: '应用',
search: '搜索',
folder: '目录',

View File

@ -14,10 +14,8 @@
>
<div v-for="item in permission_routes" :key="item.path" class="nav-item">
<app-link :to="resolvePath(item)">
<el-menu-item
v-if="!item.hidden"
:index="item.path"
>{{ item.meta ? item.meta.title : item.children[0].meta.title }}</el-menu-item>
<el-menu-item v-if="!item.hidden" :index="item.path">
{{ item.meta ? item.meta.title : item.children[0].meta.title }}</el-menu-item>
</app-link>
</div>
</el-menu>
@ -28,13 +26,22 @@
<notification class="right-menu-item hover-effect" />
<lang-select class="right-menu-item hover-effect" />
<div style="height: 100%;padding: 0 8px;" class="right-menu-item hover-effect">
<a href="https://dataease.io/docs/" target="_blank" style="display: flex;height: 100%;width: 100%;justify-content: center;align-items: center;">
<a
href="https://dataease.io/docs/"
target="_blank"
style="display: flex;height: 100%;width: 100%;justify-content: center;align-items: center;"
>
<svg-icon icon-class="docs" />
</a>
</div>
</template>
<el-dropdown class="top-dropdown" style="display: flex;align-items: center; width:100px;" trigger="click">
<el-dropdown
ref="my-drop"
class="top-dropdown"
style="display: flex;align-items: center; width:100px;"
trigger="click"
>
<div class="el-dropdown-link" style="display: flex;color: var(--TopTextColor);font-size: 14px; width:100%;">
<span style="max-width:80px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;">{{ name }}</span>
@ -62,21 +69,32 @@
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import {
mapGetters
} from 'vuex'
import AppLink from './Sidebar/Link'
import variables from '@/styles/variables.scss'
import { isExternal } from '@/utils/validate'
import {
isExternal
} from '@/utils/validate'
import Notification from '@/components/Notification'
import bus from '@/utils/bus'
import LangSelect from '@/components/LangSelect'
import { getSysUI } from '@/utils/auth'
import { pluginLoaded } from '@/api/user'
import { initTheme } from '@/utils/ThemeUtil'
import {
getSysUI
} from '@/utils/auth'
import {
pluginLoaded
} from '@/api/user'
import {
initTheme
} from '@/utils/ThemeUtil'
export default {
name: 'Topbar',
components: {
@ -85,6 +103,12 @@ export default {
LangSelect
},
props: {
showTips: {
type: Boolean,
default: false
}
},
data() {
return {
uiInfo: null,
@ -100,27 +124,42 @@ export default {
},
topMenuColor() {
if (this.$store.getters.uiInfo && this.$store.getters.uiInfo['ui.topMenuColor'] && this.$store.getters.uiInfo['ui.topMenuColor'].paramValue) { return this.$store.getters.uiInfo['ui.topMenuColor'].paramValue }
if (this.$store.getters.uiInfo && this.$store.getters.uiInfo['ui.topMenuColor'] && this.$store.getters.uiInfo[
'ui.topMenuColor'].paramValue) {
return this.$store.getters.uiInfo['ui.topMenuColor'].paramValue
}
return this.variables.topBarBg
},
topMenuActiveColor() {
if (this.$store.getters.uiInfo && this.$store.getters.uiInfo['ui.topMenuActiveColor'] && this.$store.getters.uiInfo['ui.topMenuActiveColor'].paramValue) { return this.$store.getters.uiInfo['ui.topMenuActiveColor'].paramValue }
if (this.$store.getters.uiInfo && this.$store.getters.uiInfo['ui.topMenuActiveColor'] && this.$store.getters
.uiInfo['ui.topMenuActiveColor'].paramValue) {
return this.$store.getters.uiInfo['ui.topMenuActiveColor'].paramValue
}
return this.variables.topBarMenuActive
},
topMenuTextColor() {
if (this.$store.getters.uiInfo && this.$store.getters.uiInfo['ui.topMenuTextColor'] && this.$store.getters.uiInfo['ui.topMenuTextColor'].paramValue) { return this.$store.getters.uiInfo['ui.topMenuTextColor'].paramValue }
if (this.$store.getters.uiInfo && this.$store.getters.uiInfo['ui.topMenuTextColor'] && this.$store.getters
.uiInfo['ui.topMenuTextColor'].paramValue) {
return this.$store.getters.uiInfo['ui.topMenuTextColor'].paramValue
}
return this.variables.topBarMenuText
},
topMenuTextActiveColor() {
if (this.$store.getters.uiInfo && this.$store.getters.uiInfo['ui.topMenuTextActiveColor'] && this.$store.getters.uiInfo['ui.topMenuTextActiveColor'].paramValue) { return this.$store.getters.uiInfo['ui.topMenuTextActiveColor'].paramValue }
if (this.$store.getters.uiInfo && this.$store.getters.uiInfo['ui.topMenuTextActiveColor'] && this.$store.getters
.uiInfo['ui.topMenuTextActiveColor'].paramValue) {
return this.$store.getters.uiInfo['ui.topMenuTextActiveColor'].paramValue
}
return this.variables.topBarMenuTextActive
},
/* topMenuColor() {
return this.$store.getters.uiInfo.topMenuColor
}, */
return this.$store.getters.uiInfo.topMenuColor
}, */
activeMenu() {
const route = this.$route
const { meta, path } = route
const {
meta,
path
} = route
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
// return meta.activeMenu
@ -152,6 +191,10 @@ export default {
bus.$on('set-top-menu-active-info', this.setTopMenuActiveInfo)
bus.$on('set-top-text-info', this.setTopTextInfo)
bus.$on('set-top-text-active-info', this.setTopTextActiveInfo)
this.showTips && this.$nextTick(() => {
const drop = this.$refs['my-drop']
drop && drop.show && drop.show()
})
},
created() {
this.loadUiInfo()
@ -159,13 +202,17 @@ export default {
beforeCreate() {
pluginLoaded().then(res => {
this.isPluginLoaded = res.success && res.data
if (this.isPluginLoaded) { initTheme() }
if (this.isPluginLoaded) {
initTheme()
}
})
},
methods: {
// store
initCurrentRoutes() {
const { path } = this.$route
const {
path
} = this.$route
let route = this.permission_routes.find(
item => item.path === '/' + path.split('/')[1]
)
@ -197,9 +244,9 @@ export default {
//
let path = ''
/**
* item 路由子项
* parent 路由父项
*/
* item 路由子项
* parent 路由父项
*/
const getDefaultPath = (item, parent) => {
// path
if (isExternal(item.path)) {
@ -233,7 +280,7 @@ export default {
},
//
setSidebarHide(route) {
// if (!route.children || route.children.length === 1) {
// if (!route.children || route.children.length === 1) {
if (route.name !== 'system' && (!route.children || this.showChildLength(route) === 1)) {
this.$store.dispatch('app/toggleSideBarHide', true)
} else {
@ -266,12 +313,12 @@ export default {
}
/* if (this.uiInfo['ui.themeStr'] && this.uiInfo['ui.themeStr'].paramValue) {
if (this.uiInfo['ui.themeStr'].paramValue === 'dark') {
document.body.className = 'blackTheme'
} else if (this.uiInfo['ui.themeStr'].paramValue === 'light') {
document.body.className = ''
}
} */
if (this.uiInfo['ui.themeStr'].paramValue === 'dark') {
document.body.className = 'blackTheme'
} else if (this.uiInfo['ui.themeStr'].paramValue === 'light') {
document.body.className = ''
}
} */
this.axiosFinished = true
})
},
@ -291,12 +338,14 @@ export default {
}
}
</script>
<style lang="scss" scoped>
.el-dropdown-link {
cursor: pointer;
color: #1e212a;
}
.el-icon-arrow-down {
font-size: 12px;
}
@ -312,7 +361,8 @@ export default {
}
.de-top-menu {
background-color: var(--MainBG);
background-color: var(--MainBG);
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<div :class="classObj" class="app-wrapper">
<licbar />
<topbar v-if="!fullHeightFlag" />
<topbar v-if="!fullHeightFlag && finishLoad" :show-tips="showTips" />
<de-container :style="mainStyle">
<de-aside-container v-if="!sidebar.hide" class="le-aside-container">
@ -12,6 +12,14 @@
<app-main />
</de-main-container>
</de-container>
<div v-if="showTips" class="pwd-tips">
<span>{{ $t('commons.first_login_tips') }}</span>
<div style="text-align: right; margin-bottom: 10px;">
<el-button type="primary" size="mini" @click="showTips = false">{{ $t('commons.roger_that') }}</el-button>
</div>
<div class="arrow" />
</div>
</div>
</template>
@ -23,6 +31,8 @@ import DeContainer from '@/components/dataease/DeContainer'
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
import bus from '@/utils/bus'
import { needModifyPwd } from '@/api/user'
export default {
name: 'Layout',
components: {
@ -37,7 +47,9 @@ export default {
mixins: [ResizeMixin],
data() {
return {
componentName: 'PanelMain'
componentName: 'PanelMain',
showTips: false,
finishLoad: false
}
},
computed: {
@ -76,6 +88,14 @@ export default {
}
}
},
beforeCreate() {
needModifyPwd().then(res => {
this.showTips = res.success && res.data
this.finishLoad = true
}).catch(e => {
this.finishLoad = true
})
},
mounted() {
bus.$on('PanelSwitchComponent', (c) => {
this.componentName = c.name
@ -153,4 +173,28 @@ export default {
}
}
.pwd-tips {
position: absolute;
box-shadow: 0 0 0 1000em rgb(0, 0, 0, 0.3);
height: 100px;
width: 225px;
top: 105px;
right: 115px;
z-index: 9999;
border-radius: 4px;
padding: 15px;
}
.arrow{
border-bottom: 7px solid #fff;
border-right: 7px solid #b5b5b7;
border-left: 7px solid #b5b5b7;
border-top: 7px solid #b5b5b7;
width: 0px;
height: 0px;
position: relative;
top:-60px;
left:210px;
transform: rotate(90deg);
}
</style>

View File

@ -13,12 +13,12 @@
<el-form-item :label="$t('commons.email')" prop="email">
<el-input v-model="form.email" />
</el-form-item>
<el-form-item v-if="formType !== 'modify'" :label="$t('commons.password')" prop="password">
<!-- <el-form-item v-if="formType !== 'modify'" :label="$t('commons.password')" prop="password">
<el-input v-model="form.password" autocomplete="off" show-password />
</el-form-item>
<el-form-item v-if="formType !== 'modify'" :label="$t('commons.confirmPassword')" prop="confirmPassword">
<el-input v-model="form.confirmPassword" autocomplete="off" show-password />
</el-form-item>
</el-form-item> -->
<el-form-item :label="$t('commons.gender')" prop="gender">
<el-radio-group v-model="form.gender" style="width: 178px">
@ -40,9 +40,9 @@
:load-options="loadDepts"
:auto-load-root-options="false"
:placeholder="$t('user.choose_org')"
:noChildrenText="$t('commons.treeselect.no_children_text')"
:noOptionsText="$t('commons.treeselect.no_options_text')"
:noResultsText="$t('commons.treeselect.no_results_text')"
:no-children-text="$t('commons.treeselect.no_children_text')"
:no-options-text="$t('commons.treeselect.no_options_text')"
:no-results-text="$t('commons.treeselect.no_results_text')"
@open="filterData"
/>
</el-form-item>