mirror of
https://gitee.com/goploy/goploy.git
synced 2024-11-29 18:57:59 +08:00
A ext login
This commit is contained in:
parent
bcd20d37b1
commit
1372f06931
@ -5,13 +5,16 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/zhenorzz/goploy/middleware"
|
||||
"github.com/zhenorzz/goploy/permission"
|
||||
"github.com/zhenorzz/goploy/response"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/zhenorzz/goploy/config"
|
||||
@ -24,6 +27,7 @@ type User Controller
|
||||
func (u User) Routes() []core.Route {
|
||||
return []core.Route{
|
||||
core.NewWhiteRoute("/user/login", http.MethodPost, u.Login).LogFunc(middleware.AddLoginLog),
|
||||
core.NewWhiteRoute("/user/extLogin", http.MethodPost, u.ExtLogin).LogFunc(middleware.AddLoginLog),
|
||||
core.NewRoute("/user/info", http.MethodGet, u.Info),
|
||||
core.NewRoute("/user/changePassword", http.MethodPut, u.ChangePassword),
|
||||
core.NewRoute("/user/getList", http.MethodGet, u.GetList).Permissions(permission.ShowMemberPage),
|
||||
@ -36,7 +40,7 @@ func (u User) Routes() []core.Route {
|
||||
|
||||
func (User) Login(gp *core.Goploy) core.Response {
|
||||
type ReqData struct {
|
||||
Account string `json:"account" validate:"min=5,max=25"`
|
||||
Account string `json:"account" validate:"min=1,max=25"`
|
||||
Password string `json:"password" validate:"password"`
|
||||
}
|
||||
var reqData ReqData
|
||||
@ -126,6 +130,69 @@ func (User) Login(gp *core.Goploy) core.Response {
|
||||
}
|
||||
}
|
||||
|
||||
func (User) ExtLogin(gp *core.Goploy) core.Response {
|
||||
type ReqData struct {
|
||||
Account string `json:"account" validate:"min=1,max=25"`
|
||||
Time int64 `json:"time"`
|
||||
Token string `json:"token" validate:"len=32"`
|
||||
}
|
||||
var reqData ReqData
|
||||
if err := decodeJson(gp.Body, &reqData); err != nil {
|
||||
return response.JSON{Code: response.IllegalParam, Message: err.Error()}
|
||||
}
|
||||
|
||||
if time.Now().Unix() > reqData.Time+30 {
|
||||
return response.JSON{Code: response.IllegalParam, Message: "request time expired"}
|
||||
}
|
||||
|
||||
h := md5.New()
|
||||
h.Write([]byte(reqData.Account + config.Toml.JWT.Key + strconv.FormatInt(reqData.Time, 10)))
|
||||
signedToken := hex.EncodeToString(h.Sum(nil))
|
||||
|
||||
if signedToken != reqData.Token {
|
||||
return response.JSON{Code: response.IllegalParam, Message: "sign error"}
|
||||
}
|
||||
|
||||
userData, err := model.User{Account: reqData.Account}.GetDataByAccount()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
if userData.State == model.Disable {
|
||||
return response.JSON{Code: response.AccountDisabled, Message: "Account is disabled"}
|
||||
}
|
||||
|
||||
namespaceList, err := model.Namespace{UserID: userData.ID}.GetAllByUserID()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
} else if len(namespaceList) == 0 {
|
||||
return response.JSON{Code: response.Error, Message: "No space assigned, please contact the administrator"}
|
||||
}
|
||||
|
||||
token, err := userData.CreateToken()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
_ = model.User{ID: userData.ID, LastLoginTime: time.Now().Format("20060102150405")}.UpdateLastLoginTime()
|
||||
|
||||
cookie := http.Cookie{
|
||||
Name: config.Toml.Cookie.Name,
|
||||
Value: token,
|
||||
Path: "/",
|
||||
MaxAge: config.Toml.Cookie.Expire,
|
||||
HttpOnly: true,
|
||||
}
|
||||
http.SetCookie(gp.ResponseWriter, &cookie)
|
||||
|
||||
return response.JSON{
|
||||
Data: struct {
|
||||
Token string `json:"token"`
|
||||
NamespaceList model.Namespaces `json:"namespaceList"`
|
||||
}{Token: token, NamespaceList: namespaceList},
|
||||
}
|
||||
}
|
||||
|
||||
func (User) Info(gp *core.Goploy) core.Response {
|
||||
type RespData struct {
|
||||
UserInfo struct {
|
||||
@ -180,7 +247,7 @@ func (User) GetOption(*core.Goploy) core.Response {
|
||||
|
||||
func (User) Add(gp *core.Goploy) core.Response {
|
||||
type ReqData struct {
|
||||
Account string `json:"account" validate:"min=5,max=25"`
|
||||
Account string `json:"account" validate:"min=1,max=25"`
|
||||
Password string `json:"password" validate:"omitempty,password"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Contact string `json:"contact" validate:"omitempty,len=11,numeric"`
|
||||
|
@ -42,7 +42,7 @@ type RouteApi interface {
|
||||
}
|
||||
|
||||
type Response interface {
|
||||
Write(http.ResponseWriter) error
|
||||
Write(http.ResponseWriter, *http.Request) error
|
||||
}
|
||||
|
||||
type Route struct {
|
||||
@ -149,7 +149,7 @@ func (rt Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
_, resp := rt.doRequest(w, r)
|
||||
if err := resp.Write(w); err != nil {
|
||||
if err := resp.Write(w, r); err != nil {
|
||||
Log(ERROR, err.Error())
|
||||
}
|
||||
return
|
||||
|
@ -10,5 +10,4 @@ import (
|
||||
|
||||
type Empty struct{}
|
||||
|
||||
//JSON response
|
||||
func (Empty) Write(http.ResponseWriter) error { return nil }
|
||||
func (Empty) Write(http.ResponseWriter, *http.Request) error { return nil }
|
||||
|
@ -15,8 +15,7 @@ type File struct {
|
||||
Filename string
|
||||
}
|
||||
|
||||
//JSON response
|
||||
func (f File) Write(w http.ResponseWriter) error {
|
||||
func (f File) Write(w http.ResponseWriter, _ *http.Request) error {
|
||||
file, err := os.Open(f.Filename)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -15,7 +15,6 @@ type JSON struct {
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
// response code
|
||||
const (
|
||||
Pass = 0
|
||||
Deny = 1
|
||||
@ -28,6 +27,6 @@ const (
|
||||
)
|
||||
|
||||
//JSON response
|
||||
func (j JSON) Write(w http.ResponseWriter) error {
|
||||
func (j JSON) Write(w http.ResponseWriter, _ *http.Request) error {
|
||||
return json.NewEncoder(w).Encode(j)
|
||||
}
|
||||
|
19
response/Redirect.go
Normal file
19
response/Redirect.go
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2022 The Goploy Authors. All rights reserved.
|
||||
// Use of this source code is governed by a GPLv3-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package response
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Redirect struct {
|
||||
URL string
|
||||
Code int
|
||||
}
|
||||
|
||||
func (rdr Redirect) Write(w http.ResponseWriter, r *http.Request) error {
|
||||
http.Redirect(w, r, rdr.URL, rdr.Code)
|
||||
return nil
|
||||
}
|
@ -18,8 +18,7 @@ type SftpFile struct {
|
||||
Disposition string // attachment | inline
|
||||
}
|
||||
|
||||
//JSON response
|
||||
func (sf SftpFile) Write(w http.ResponseWriter) error {
|
||||
func (sf SftpFile) Write(w http.ResponseWriter, _ *http.Request) error {
|
||||
defer sf.Client.Close()
|
||||
|
||||
sftpClient, err := sftp.NewClient(sf.Client)
|
||||
|
@ -29,6 +29,23 @@ export class Login extends Request {
|
||||
}
|
||||
}
|
||||
|
||||
export class extLogin extends Request {
|
||||
readonly url = '/user/extLogin'
|
||||
readonly method = 'post'
|
||||
public param: {
|
||||
account: string
|
||||
token: string
|
||||
time: number
|
||||
}
|
||||
public declare datagram: {
|
||||
namespaceList: { id: number; name: string; roleId: number }[]
|
||||
}
|
||||
constructor(param: extLogin['param']) {
|
||||
super()
|
||||
this.param = param
|
||||
}
|
||||
}
|
||||
|
||||
export class Info extends Request {
|
||||
readonly url = '/user/info'
|
||||
readonly method = 'get'
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
import { UserState } from './types'
|
||||
import { RootState } from '../../types'
|
||||
import { Login, Info } from '@/api/user'
|
||||
import { Login, extLogin, Info } from '@/api/user'
|
||||
import { setLogin, logout } from '@/utils/auth'
|
||||
import { getNamespaceId, setNamespace } from '@/utils/namespace'
|
||||
import { resetRouter } from '@/router'
|
||||
@ -51,6 +51,27 @@ const actions: ActionTree<UserState, RootState> = {
|
||||
})
|
||||
},
|
||||
|
||||
// user ext login
|
||||
extLogin(_, userInfo) {
|
||||
return new Promise((resolve, reject) => {
|
||||
new extLogin(userInfo)
|
||||
.request()
|
||||
.then((response) => {
|
||||
const { data } = response
|
||||
if (!getNamespaceId()) {
|
||||
const namespace = data.namespaceList[data.namespaceList.length - 1]
|
||||
setNamespace(namespace)
|
||||
}
|
||||
|
||||
setLogin('ok')
|
||||
resolve(response)
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// get user info
|
||||
getInfo({ commit }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -15,7 +15,7 @@ export function isExternal(path: string): boolean {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUsername(str: string): boolean {
|
||||
return str.trim().length >= 5
|
||||
return str.trim().length >= 1
|
||||
}
|
||||
|
||||
export function validPassword(str: string): boolean {
|
||||
@ -29,6 +29,7 @@ export function validPassword(str: string): boolean {
|
||||
|
||||
/* 合法uri*/
|
||||
export function validateURL(textval: string): boolean {
|
||||
const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||||
const urlregex =
|
||||
/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||||
return urlregex.test(textval)
|
||||
}
|
||||
|
@ -117,6 +117,14 @@ watch(
|
||||
useRoute(),
|
||||
(route) => {
|
||||
redirect.value = route.query?.redirect
|
||||
console.log(route.query)
|
||||
if (route.query['account'] && route.query['time'] && route.query['token']) {
|
||||
handleExtLogin(
|
||||
route.query['account'] as string,
|
||||
Number(route.query['time']),
|
||||
route.query['token'] as string
|
||||
)
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
@ -133,6 +141,21 @@ function showPwd() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleExtLogin(account: string, time: number, token: string) {
|
||||
store
|
||||
.dispatch('user/extLogin', { account, time, token })
|
||||
.then(() => {
|
||||
router.push({
|
||||
path: redirect.value || '/',
|
||||
query: redirect.value ? param2Obj(redirect.value) : {},
|
||||
})
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleLogin() {
|
||||
form.value?.validate((valid) => {
|
||||
if (valid) {
|
||||
|
Loading…
Reference in New Issue
Block a user