mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-09 23:17:21 +08:00
feat(system-security): Optimize Route Matching for Secure Entry (#7537)
This commit is contained in:
parent
cd266d2567
commit
da73f26ebe
8 changed files with 60 additions and 172 deletions
|
@ -70,10 +70,7 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||||
if req.Resource != "" && req.Resource != "all" {
|
if req.Resource != "" && req.Resource != "all" {
|
||||||
opts = append(opts, appRepo.WithResource(req.Resource))
|
opts = append(opts, appRepo.WithResource(req.Resource))
|
||||||
}
|
}
|
||||||
if req.Type == "php" {
|
|
||||||
info, _ := NewISettingService().GetSettingInfo()
|
|
||||||
opts = append(opts, appRepo.WithPanelVersion(info.SystemVersion))
|
|
||||||
}
|
|
||||||
if req.ShowCurrentArch {
|
if req.ShowCurrentArch {
|
||||||
info, err := NewIDashboardService().LoadOsInfo()
|
info, err := NewIDashboardService().LoadOsInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -101,12 +98,22 @@ func (a AppService) PageApp(req request.AppSearch) (interface{}, error) {
|
||||||
opts = append(opts, commonRepo.WithByIDs(appIds))
|
opts = append(opts, commonRepo.WithByIDs(appIds))
|
||||||
}
|
}
|
||||||
var res response.AppRes
|
var res response.AppRes
|
||||||
|
|
||||||
total, apps, err := appRepo.Page(req.Page, req.PageSize, opts...)
|
total, apps, err := appRepo.Page(req.Page, req.PageSize, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var appDTOs []*response.AppDto
|
var appDTOs []*response.AppDto
|
||||||
|
info := &dto.SettingInfo{}
|
||||||
|
if req.Type == "php" {
|
||||||
|
info, _ = NewISettingService().GetSettingInfo()
|
||||||
|
}
|
||||||
for _, ap := range apps {
|
for _, ap := range apps {
|
||||||
|
if req.Type == "php" {
|
||||||
|
if ap.RequiredPanelVersion == 0 || !common.CompareAppVersion(fmt.Sprintf("%f", ap.RequiredPanelVersion), info.SystemVersion) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
appDTO := &response.AppDto{
|
appDTO := &response.AppDto{
|
||||||
ID: ap.ID,
|
ID: ap.ID,
|
||||||
Name: ap.Name,
|
Name: ap.Name,
|
||||||
|
@ -789,7 +796,7 @@ func (a AppService) GetAppUpdate() (*response.AppUpdateRes, error) {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
if list.Extra.Version != "" && setting.SystemVersion != list.Extra.Version && !common.CompareVersion(setting.SystemVersion, list.Extra.Version) {
|
if list.Extra.Version != "" && setting.SystemVersion != list.Extra.Version && !common.CompareVersion(setting.SystemVersion, list.Extra.Version) {
|
||||||
global.LOG.Errorf("The current version is too low to synchronize with the App Store. The minimum required version is %s", list.Extra.Version)
|
global.LOG.Errorf("The current version %s is too low to synchronize with the App Store. The minimum required version is %s", setting.SystemVersion, list.Extra.Version)
|
||||||
return nil, buserr.New("ErrVersionTooLow")
|
return nil, buserr.New("ErrVersionTooLow")
|
||||||
}
|
}
|
||||||
res.AppList = list
|
res.AppList = list
|
||||||
|
|
|
@ -86,6 +86,13 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
||||||
}
|
}
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
|
|
||||||
|
runtimeDir := path.Join(constant.RuntimeDir, create.Type)
|
||||||
|
if !fileOp.Stat(runtimeDir) {
|
||||||
|
if err := fileOp.CreateDir(runtimeDir, constant.DirPerm); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch create.Type {
|
switch create.Type {
|
||||||
case constant.RuntimePHP:
|
case constant.RuntimePHP:
|
||||||
if create.Resource == constant.ResourceLocal {
|
if create.Resource == constant.ResourceLocal {
|
||||||
|
|
|
@ -47,6 +47,33 @@ func CompareVersion(version1, version2 string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CompareAppVersion(version1, version2 string) bool {
|
||||||
|
v1s := extractNumbers(version1)
|
||||||
|
v2s := extractNumbers(version2)
|
||||||
|
|
||||||
|
maxLen := max(len(v1s), len(v2s))
|
||||||
|
v1s = append(v1s, make([]string, maxLen-len(v1s))...)
|
||||||
|
v2s = append(v2s, make([]string, maxLen-len(v2s))...)
|
||||||
|
|
||||||
|
for i := 0; i < maxLen; i++ {
|
||||||
|
v1, err1 := strconv.Atoi(v1s[i])
|
||||||
|
v2, err2 := strconv.Atoi(v2s[i])
|
||||||
|
if err1 != nil {
|
||||||
|
v1 = 0
|
||||||
|
}
|
||||||
|
if err2 != nil {
|
||||||
|
v2 = 0
|
||||||
|
}
|
||||||
|
if v1 > v2 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if v1 < v2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func ComparePanelVersion(version1, version2 string) bool {
|
func ComparePanelVersion(version1, version2 string) bool {
|
||||||
if version1 == version2 {
|
if version1 == version2 {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -132,6 +132,7 @@ var WebUrlMap = map[string]struct{}{
|
||||||
"/xpack/alert/log": {},
|
"/xpack/alert/log": {},
|
||||||
"/xpack/alert/setting": {},
|
"/xpack/alert/setting": {},
|
||||||
"/xpack/setting": {},
|
"/xpack/setting": {},
|
||||||
|
"xpack/node": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
var DynamicRoutes = []string{
|
var DynamicRoutes = []string{
|
||||||
|
|
|
@ -20,7 +20,7 @@ func Init() {
|
||||||
baseDir := "/opt"
|
baseDir := "/opt"
|
||||||
port := "9999"
|
port := "9999"
|
||||||
mode := ""
|
mode := ""
|
||||||
version := "v1.0.0"
|
version := "v2.0.0"
|
||||||
username, password, entrance := "", "", ""
|
username, password, entrance := "", "", ""
|
||||||
v := viper.NewWithOptions()
|
v := viper.NewWithOptions()
|
||||||
v.SetConfigType("yaml")
|
v.SetConfigType("yaml")
|
||||||
|
|
|
@ -75,7 +75,7 @@ export const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/:code?',
|
path: '/:code?',
|
||||||
name: 'entrance',
|
name: 'entrance',
|
||||||
component: () => import('@/views/login/entrance/index.vue'),
|
component: () => import('@/views/login/index.vue'),
|
||||||
props: true,
|
props: true,
|
||||||
},
|
},
|
||||||
...routerArray,
|
...routerArray,
|
||||||
|
|
|
@ -1,165 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div v-if="init">
|
|
||||||
<div v-if="errStatus === ''">
|
|
||||||
<div class="login-background">
|
|
||||||
<div class="login-wrapper">
|
|
||||||
<div :class="screenWidth > 1110 ? 'left inline-block' : ''">
|
|
||||||
<div class="login-title">
|
|
||||||
<span>{{ globalStore.themeConfig.title || $t('setting.description') }}</span>
|
|
||||||
</div>
|
|
||||||
<img src="@/assets/images/1panel-login.png" alt="" v-if="screenWidth > 1110" />
|
|
||||||
</div>
|
|
||||||
<div :class="screenWidth > 1110 ? 'right inline-block' : ''">
|
|
||||||
<div class="login-container">
|
|
||||||
<LoginForm ref="loginRef"></LoginForm>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else>
|
|
||||||
<div v-if="errStatus.indexOf('code-') !== -1">
|
|
||||||
<ErrCode :code="errStatus.replaceAll('code-', '')" />
|
|
||||||
</div>
|
|
||||||
<div v-if="errStatus === 'err-found'">
|
|
||||||
<ErrFound />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="login">
|
|
||||||
import LoginForm from '../components/login-form.vue';
|
|
||||||
import ErrCode from '@/components/error-message/error_code.vue';
|
|
||||||
import ErrFound from '@/components/error-message/404.vue';
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
import { GlobalStore } from '@/store';
|
|
||||||
import { getXpackSettingForTheme } from '@/utils/xpack';
|
|
||||||
const globalStore = GlobalStore();
|
|
||||||
|
|
||||||
const screenWidth = ref(null);
|
|
||||||
const errStatus = ref('x');
|
|
||||||
const init = ref(false);
|
|
||||||
|
|
||||||
const mySafetyCode = defineProps({
|
|
||||||
code: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const getStatus = async () => {
|
|
||||||
let code = mySafetyCode.code;
|
|
||||||
if (code != '') {
|
|
||||||
globalStore.entrance = code;
|
|
||||||
}
|
|
||||||
await getXpackSettingForTheme();
|
|
||||||
let info = globalStore.errStatus;
|
|
||||||
if (info?.startsWith('err-') || info?.startsWith('code-')) {
|
|
||||||
errStatus.value = info;
|
|
||||||
init.value = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
errStatus.value = '';
|
|
||||||
init.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
globalStore.isOnRestart = false;
|
|
||||||
getStatus();
|
|
||||||
screenWidth.value = document.body.clientWidth;
|
|
||||||
window.onresize = () => {
|
|
||||||
return (() => {
|
|
||||||
screenWidth.value = document.body.clientWidth;
|
|
||||||
})();
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@mixin login-center {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-background {
|
|
||||||
height: 100vh;
|
|
||||||
background: url(@/assets/images/1panel-login-bg.png) no-repeat,
|
|
||||||
radial-gradient(153.25% 257.2% at 118.99% 181.67%, rgba(50, 132, 255, 0.2) 0%, rgba(82, 120, 255, 0) 100%)
|
|
||||||
/* warning: gradient uses a rotation that is not supported by CSS and may not behave as expected */,
|
|
||||||
radial-gradient(123.54% 204.83% at 25.87% 195.17%, rgba(111, 76, 253, 0.15) 0%, rgba(122, 76, 253, 0) 78.85%)
|
|
||||||
/* warning: gradient uses a rotation that is not supported by CSS and may not behave as expected */,
|
|
||||||
linear-gradient(0deg, rgba(0, 94, 235, 0.03), rgba(0, 94, 235, 0.03)),
|
|
||||||
radial-gradient(109.58% 109.58% at 31.53% -36.58%, rgba(0, 94, 235, 0.3) 0%, rgba(0, 94, 235, 0) 100%)
|
|
||||||
/* warning: gradient uses a rotation that is not supported by CSS and may not behave as expected */,
|
|
||||||
rgba(0, 57, 142, 0.05);
|
|
||||||
|
|
||||||
.login-wrapper {
|
|
||||||
padding-top: 8%;
|
|
||||||
width: 80%;
|
|
||||||
margin: 0 auto;
|
|
||||||
// @media only screen and (max-width: 1440px) {
|
|
||||||
// width: 100%;
|
|
||||||
// padding-top: 6%;
|
|
||||||
// }
|
|
||||||
.left {
|
|
||||||
vertical-align: middle;
|
|
||||||
text-align: right;
|
|
||||||
width: 60%;
|
|
||||||
img {
|
|
||||||
object-fit: contain;
|
|
||||||
width: 100%;
|
|
||||||
@media only screen and (min-width: 1440px) {
|
|
||||||
width: 85%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.right {
|
|
||||||
vertical-align: middle;
|
|
||||||
width: 40%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-title {
|
|
||||||
text-align: right;
|
|
||||||
margin-right: 10%;
|
|
||||||
span:first-child {
|
|
||||||
color: #005eeb;
|
|
||||||
font-size: 40px;
|
|
||||||
font-family: pingFangSC-Regular;
|
|
||||||
font-weight: 600;
|
|
||||||
@media only screen and (max-width: 768px) {
|
|
||||||
font-size: 35px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media only screen and (max-width: 1110px) {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
font-size: 35px;
|
|
||||||
text-align: center;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-container {
|
|
||||||
margin-top: 40px;
|
|
||||||
padding: 40px 0;
|
|
||||||
width: 390px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color: rgba(255, 255, 255, 0.55);
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 2px 4px 22px rgba(0, 94, 235, 0.2);
|
|
||||||
@media only screen and (max-width: 1440px) {
|
|
||||||
margin-top: 60px;
|
|
||||||
}
|
|
||||||
@media only screen and (max-width: 1110px) {
|
|
||||||
margin: 60px auto 0;
|
|
||||||
}
|
|
||||||
@media only screen and (max-width: 768px) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -29,9 +29,20 @@ import { getXpackSettingForTheme } from '@/utils/xpack';
|
||||||
const gStore = GlobalStore();
|
const gStore = GlobalStore();
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
|
|
||||||
|
const mySafetyCode = defineProps({
|
||||||
|
code: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const screenWidth = ref(null);
|
const screenWidth = ref(null);
|
||||||
|
|
||||||
const getStatus = async () => {
|
const getStatus = async () => {
|
||||||
|
let code = mySafetyCode.code;
|
||||||
|
if (code != '') {
|
||||||
|
gStore.entrance = code;
|
||||||
|
}
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await checkIsSafety(gStore.entrance)
|
await checkIsSafety(gStore.entrance)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue