Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions core/app/auth/api_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type APIAuthConfig struct {
ApiInterfaceStatus string
ApiKey string
IpWhiteList string
ApiKeyValidityTime string
ApiKeyValidityTime int
}

type APIAuthConfigLoader func(c *gin.Context) (APIAuthConfig, error)
Expand Down Expand Up @@ -83,16 +83,19 @@ func LoadAPIAuthConfig(_ *gin.Context) (APIAuthConfig, error) {
if config.IpWhiteList, err = settingRepo.GetValueByKey("IpWhiteList"); err != nil {
return config, err
}
if config.ApiKeyValidityTime, err = settingRepo.GetValueByKey("ApiKeyValidityTime"); err != nil {
apiValidity, err := settingRepo.GetValueByKey("ApiKeyValidityTime")
if err != nil {
return config, err
}
if config.ApiKeyValidityTime, err = strconv.Atoi(apiValidity); err != nil {
return config, err
}
return config, nil
}

func isValid1PanelTimestamp(panelTimestamp string, apiKeyValidityTime string) bool {
apiTime, err := strconv.Atoi(apiKeyValidityTime)
if err != nil || apiTime < 0 {
global.LOG.Errorf("apiTime %d, err: %v", apiTime, err)
func isValid1PanelTimestamp(panelTimestamp string, apiKeyValidityTime int) bool {
apiTime := apiKeyValidityTime
if apiTime < 0 {
return false
}
if apiTime == 0 {
Expand Down
20 changes: 14 additions & 6 deletions core/app/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,19 @@ func VerifyMFALogin(c *gin.Context, sessionID, code, entrance string) (string, s
if session.Entrance != entrance {
return "", "", buserr.New("ErrEntrance")
}
mfaSecret, err := settingRepo.Get(repo.WithByKey("MFASecret"))
mfaSecret, err := settingRepo.GetValueByKey("MFASecret")
if err != nil {
return "", "", err
}
mfaInterval, err := settingRepo.Get(repo.WithByKey("MFAInterval"))
mfaInterval, err := settingRepo.GetValueByKey("MFAInterval")
if err != nil {
return "", "", err
}
if !mfa.ValidCode(code, mfaInterval.Value, mfaSecret.Value) {
interval, err := strconv.Atoi(mfaInterval)
if err != nil {
return "", "", err
}
if !mfa.ValidCode(interval, code, mfaSecret) {
return "", "ErrMFA", nil
}
mfaSessions.Delete(sessionID)
Expand Down Expand Up @@ -194,13 +198,13 @@ func LoadMFA(req dto.MfaRequest) (mfa.Otp, error) {
return otp, nil
}
func MFABind(req dto.MfaCredential) error {
success := mfa.ValidCode(req.Code, req.Interval, req.Secret)
success := mfa.ValidCode(req.Interval, req.Code, req.Secret)
if !success {
return errors.New("code is not valid")
}

settingRepo := repo.NewISettingRepo()
if err := settingRepo.Update("MFAInterval", req.Interval); err != nil {
if err := settingRepo.Update("MFAInterval", strconv.Itoa(req.Interval)); err != nil {
return err
}
if err := settingRepo.Update("MFAStatus", constant.StatusEnable); err != nil {
Expand All @@ -227,6 +231,8 @@ func GetCurrentUserInfo() (*dto.CurrentUserInfo, error) {
}
delete(stringSettingMap, "SessionTimeout")
delete(stringSettingMap, "ExpirationDays")
delete(stringSettingMap, "MFAInterval")
delete(stringSettingMap, "ApiKeyValidityTime")
arr, err := json.Marshal(stringSettingMap)
if err != nil {
return nil, err
Expand All @@ -236,6 +242,8 @@ func GetCurrentUserInfo() (*dto.CurrentUserInfo, error) {
}
info.SessionTimeout, _ = strconv.Atoi(settingMap["SessionTimeout"])
info.ExpirationDays, _ = strconv.Atoi(settingMap["ExpirationDays"])
info.MFAInterval, _ = strconv.Atoi(settingMap["MFAInterval"])
info.ApiKeyValidityTime, _ = strconv.Atoi(settingMap["ApiKeyValidityTime"])
info.Name = settingMap["UserName"]
return &info, nil
}
Expand Down Expand Up @@ -296,7 +304,7 @@ func UpdateApiConfig(req dto.ApiInterfaceConfig) error {
if err := settingRepo.UpdateOrCreate("IpWhiteList", req.IpWhiteList); err != nil {
return err
}
if err := settingRepo.UpdateOrCreate("ApiKeyValidityTime", req.ApiKeyValidityTime); err != nil {
if err := settingRepo.UpdateOrCreate("ApiKeyValidityTime", strconv.Itoa(req.ApiKeyValidityTime)); err != nil {
return err
}
return nil
Expand Down
44 changes: 26 additions & 18 deletions core/app/dto/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ type PasskeyBeginResponse struct {
PublicKey interface{} `json:"publicKey"`
}

type MfaRequest struct {
Title string `json:"title" validate:"required"`
Interval int `json:"interval" validate:"required"`
}

type MfaCredential struct {
Secret string `json:"secret" validate:"required"`
Code string `json:"code" validate:"required"`
Interval string `json:"interval" validate:"required"`
}

type Login struct {
Name string `json:"name" validate:"required"`
Password string `json:"password" validate:"required"`
Expand All @@ -37,11 +26,6 @@ type Login struct {
Language string `json:"language" validate:"required,oneof=zh en 'zh-Hant' ko ja ru ms 'pt-BR' tr 'es-ES'"`
}

type MFALogin struct {
SessionID string `json:"sessionId" validate:"required"`
Code string `json:"code" validate:"required"`
}

type SystemSetting struct {
IsDemo bool `json:"isDemo"`
Language string `json:"language"`
Expand All @@ -52,19 +36,43 @@ type PasskeyID struct {
ID string `json:"id" validate:"required"`
}

// mfa
type MFALogin struct {
SessionID string `json:"sessionId" validate:"required"`
Code string `json:"code" validate:"required"`
}

type MfaRequest struct {
Title string `json:"title" validate:"required"`
Interval int `json:"interval" validate:"required"`
}

type MfaCredential struct {
Secret string `json:"secret" validate:"required"`
Code string `json:"code" validate:"required"`
Interval int `json:"interval" validate:"required"`
}

type ApiInterfaceConfig struct {
ApiInterfaceStatus string `json:"apiInterfaceStatus"`
ApiKey string `json:"apiKey"`
IpWhiteList string `json:"ipWhiteList"`
ApiKeyValidityTime int `json:"apiKeyValidityTime"`
}

type CurrentUserInfo struct {
Name string `json:"name"`
SessionTimeout int `json:"sessionTimeout"`
MFAStatus string `json:"mfaStatus"`
MFAInterval string `json:"mfaInterval"`
MFAInterval int `json:"mfaInterval"`
ExpirationDays int `json:"expirationDays"`
ExpirationTime string `json:"expirationTime"`
ComplexitySetting string `json:"complexitySetting"`

ApiInterfaceStatus string `json:"apiInterfaceStatus"`
ApiKey string `json:"apiKey"`
IpWhiteList string `json:"ipWhiteList"`
ApiKeyValidityTime string `json:"apiKeyValidityTime"`
ApiKeyValidityTime int `json:"apiKeyValidityTime"`
}
type CurrentUserUpdate struct {
Name string `json:"name" validate:"required"`
Expand Down
7 changes: 0 additions & 7 deletions core/app/dto/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,6 @@ type MenuLabelSort struct {
Sort int `json:"sort"`
}

type ApiInterfaceConfig struct {
ApiInterfaceStatus string `json:"apiInterfaceStatus"`
ApiKey string `json:"apiKey"`
IpWhiteList string `json:"ipWhiteList"`
ApiKeyValidityTime string `json:"apiKeyValidityTime"`
}

type TerminalInfo struct {
LineHeight string `json:"lineHeight"`
LetterSpacing string `json:"letterSpacing"`
Expand Down
5 changes: 3 additions & 2 deletions core/constant/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,9 @@ var WebUrlMap = map[string]struct{}{
"/xpack/cluster/postgres": {},
"/xpack/cluster/redis": {},

"/enterprise/users/list": {},
"/enterprise/users/roles": {},
"/enterprise/users/list": {},
"/enterprise/users/roles": {},
"/enterprise/license-required": {},
}

var DynamicRoutes = []string{
Expand Down
9 changes: 1 addition & 8 deletions core/utils/mfa/mfa.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package mfa
import (
"bytes"
"encoding/base64"
"strconv"
"time"

"github.com/1Panel-dev/1Panel/core/global"
"github.com/skip2/go-qrcode"
"github.com/xlzd/gotp"
)
Expand All @@ -32,12 +30,7 @@ func GetOtp(username, title string, interval int) (otp Otp, err error) {
return
}

func ValidCode(code, intervalStr, secret string) bool {
interval, err := strconv.Atoi(intervalStr)
if err != nil {
global.LOG.Errorf("type conversion failed, err: %v", err)
return false
}
func ValidCode(interval int, code, secret string) bool {
totp := gotp.NewTOTP(secret, 6, interval, nil)
now := time.Now().Unix()
prevTime := now - int64(interval)
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/api/interface/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ export namespace Login {
export interface MFABind {
secret: string;
code: string;
interval: string;
interval: number;
}
export interface ApiConfig {
apiInterfaceStatus: string;
apiKey: string;
ipWhiteList: string;
apiKeyValidityTime: string;
apiKeyValidityTime: number;
}
export interface PasswordUpdate {
oldPassword: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<template>
<div>
<el-popover
ref="nodeChangeRef"
placement="right-end"
:show-arrow="false"
:offset="0"
Expand Down Expand Up @@ -117,7 +116,6 @@ const nodeOptions = ref([]);
const loading = ref();
const switchingNode = ref(false);
const userInfoRef = ref();
const nodeChangeRef = ref();
const props = defineProps({
version: String,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,22 @@
</el-tooltip>
</span>
</template>
<el-switch
@change="handleApi"
v-model="form.apiInterfaceStatus"
active-value="Enable"
inactive-value="Disable"
/>
<div class="setting-action-row">
<el-switch
@change="handleApi"
v-model="form.apiInterfaceStatus"
active-value="Enable"
inactive-value="Disable"
/>
<el-button
v-if="form.apiInterfaceStatus === 'Enable'"
link
type="primary"
@click="openApiDetail"
>
{{ $t('commons.button.view') }}
</el-button>
</div>
<span class="input-help">{{ $t('setting.apiInterfaceHelper') }}</span>
</el-form-item>
</el-form>
Expand Down Expand Up @@ -356,7 +366,7 @@
<span class="input-help">{{ $t('setting.ipWhiteListHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('setting.apiKeyValidityTime')" prop="apiKeyValidityTime">
<el-input :placeholder="$t('setting.apiKeyValidityTimeEgs')" v-model="form.apiKeyValidityTime">
<el-input :placeholder="$t('setting.apiKeyValidityTimeEgs')" v-model.number="form.apiKeyValidityTime">
<template #append>{{ $t('commons.units.minute') }}</template>
</el-input>
<span class="input-help">
Expand Down Expand Up @@ -667,6 +677,11 @@ const handleApiDialogClose = () => {
form.apiInterfaceStatus = savedApiStatus.value;
};

const openApiDetail = async () => {
await ensureApiKey();
apiDialogOpen.value = true;
};

const openPasskeyDrawer = async () => {
const settingRes = await loadPasskeySettingInfo();
hasBindDomain.value = !!settingRes?.data.bindDomain?.trim().length;
Expand Down Expand Up @@ -862,7 +877,7 @@ const onBindMFA = async (formEl: FormInstance | undefined) => {
const param = {
code: mfaForm.code,
secret: mfaForm.secret,
interval: mfaForm.interval + '',
interval: mfaForm.interval,
};
loading.value = true;
await bindMFA(param)
Expand All @@ -887,7 +902,7 @@ const onSaveApi = async (formEl: FormInstance | undefined) => {
apiKey: form.apiKey,
ipWhiteList: form.ipWhiteList,
apiInterfaceStatus: form.apiInterfaceStatus,
apiKeyValidityTime: form.apiKeyValidityTime + '',
apiKeyValidityTime: form.apiKeyValidityTime,
};
loading.value = true;
await updateApiConfig(param)
Expand Down Expand Up @@ -981,7 +996,7 @@ const handleApi = async () => {
apiKey: form.apiKey,
ipWhiteList: form.ipWhiteList,
apiInterfaceStatus: form.apiInterfaceStatus,
apiKeyValidityTime: form.apiKeyValidityTime + '',
apiKeyValidityTime: form.apiKeyValidityTime,
};
await updateApiConfig(param)
.then(() => {
Expand Down Expand Up @@ -1024,6 +1039,12 @@ defineExpose({
border-top: 1px solid var(--el-border-color-lighter);
}

.setting-action-row {
display: flex;
align-items: center;
gap: 12px;
}

.api-key-input {
width: calc(100% - 125px);
}
Expand Down
Loading