mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-16 20:40:45 +08:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
56d0de64dc | ||
![]() |
1813e8e8c7 | ||
![]() |
e27c764a55 | ||
![]() |
e5a2057382 | ||
![]() |
8457ff7433 | ||
![]() |
888a6f2feb | ||
![]() |
b57b64fc36 | ||
![]() |
0d239ba1cf | ||
![]() |
8927e08217 | ||
![]() |
0636069584 | ||
![]() |
4d0f73c84e |
@@ -28,6 +28,7 @@ ldapServerPort = 389
|
||||
ldapsCertId = ""
|
||||
ldapsServerPort = 636
|
||||
radiusServerPort = 1812
|
||||
radiusDefaultOrganization = "built-in"
|
||||
radiusSecret = "secret"
|
||||
quota = {"organization": -1, "user": -1, "application": -1, "provider": -1}
|
||||
logConfig = {"filename": "logs/casdoor.log", "maxdays":99999, "perm":"0770"}
|
||||
|
@@ -22,6 +22,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -617,6 +618,17 @@ func (c *ApiController) Login() {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to login in: %s"), err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if provider.EmailRegex != "" {
|
||||
reg, err := regexp.Compile(provider.EmailRegex)
|
||||
if err != nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to login in: %s"), err.Error()))
|
||||
return
|
||||
}
|
||||
if !reg.MatchString(userInfo.Email) {
|
||||
c.ResponseError(fmt.Sprintf(c.T("check:Email is invalid")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if authForm.Method == "signup" {
|
||||
|
@@ -195,6 +195,12 @@ type GitHubUserEmailInfo struct {
|
||||
Visibility string `json:"visibility"`
|
||||
}
|
||||
|
||||
type GitHubErrorInfo struct {
|
||||
Message string `json:"message"`
|
||||
DocumentationUrl string `json:"documentation_url"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
func (idp *GithubIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
req, err := http.NewRequest("GET", "https://api.github.com/user", nil)
|
||||
if err != nil {
|
||||
@@ -236,13 +242,23 @@ func (idp *GithubIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var userEmails []GitHubUserEmailInfo
|
||||
err = json.Unmarshal(emailBody, &userEmails)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if respEmail.StatusCode != 200 {
|
||||
var errMessage GitHubErrorInfo
|
||||
err = json.Unmarshal(emailBody, &errMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
githubUserInfo.Email = idp.getEmailFromEmailsResult(userEmails)
|
||||
fmt.Printf("GithubIdProvider:GetUserInfo() error, status code = %d, error message = %v\n", respEmail.StatusCode, errMessage)
|
||||
} else {
|
||||
var userEmails []GitHubUserEmailInfo
|
||||
err = json.Unmarshal(emailBody, &userEmails)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
githubUserInfo.Email = idp.getEmailFromEmailsResult(userEmails)
|
||||
}
|
||||
}
|
||||
|
||||
userInfo := UserInfo{
|
||||
|
5
main.go
5
main.go
@@ -83,6 +83,11 @@ func main() {
|
||||
// logs.SetLevel(logs.LevelInformational)
|
||||
logs.SetLogFuncCall(false)
|
||||
|
||||
err = util.StopOldInstance(port)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go ldap.StartLdapServer()
|
||||
go radius.StartRadiusServer()
|
||||
go object.ClearThroughputPerSecond()
|
||||
|
@@ -19,288 +19,90 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Dashboard struct {
|
||||
OrganizationCounts []int `json:"organizationCounts"`
|
||||
UserCounts []int `json:"userCounts"`
|
||||
ProviderCounts []int `json:"providerCounts"`
|
||||
ApplicationCounts []int `json:"applicationCounts"`
|
||||
SubscriptionCounts []int `json:"subscriptionCounts"`
|
||||
RoleCounts []int `json:"roleCounts"`
|
||||
GroupCounts []int `json:"groupCounts"`
|
||||
ResourceCounts []int `json:"resourceCounts"`
|
||||
CertCounts []int `json:"certCounts"`
|
||||
PermissionCounts []int `json:"permissionCounts"`
|
||||
TransactionCounts []int `json:"transactionCounts"`
|
||||
ModelCounts []int `json:"modelCounts"`
|
||||
AdapterCounts []int `json:"adapterCounts"`
|
||||
EnforcerCounts []int `json:"enforcerCounts"`
|
||||
type DashboardDateItem struct {
|
||||
CreatedTime string `json:"createTime"`
|
||||
}
|
||||
|
||||
func GetDashboard(owner string) (*Dashboard, error) {
|
||||
type DashboardMapItem struct {
|
||||
dashboardDateItems []DashboardDateItem
|
||||
itemCount int64
|
||||
}
|
||||
|
||||
func GetDashboard(owner string) (*map[string][]int64, error) {
|
||||
if owner == "All" {
|
||||
owner = ""
|
||||
}
|
||||
|
||||
dashboard := &Dashboard{
|
||||
OrganizationCounts: make([]int, 31),
|
||||
UserCounts: make([]int, 31),
|
||||
ProviderCounts: make([]int, 31),
|
||||
ApplicationCounts: make([]int, 31),
|
||||
SubscriptionCounts: make([]int, 31),
|
||||
RoleCounts: make([]int, 31),
|
||||
GroupCounts: make([]int, 31),
|
||||
ResourceCounts: make([]int, 31),
|
||||
CertCounts: make([]int, 31),
|
||||
PermissionCounts: make([]int, 31),
|
||||
TransactionCounts: make([]int, 31),
|
||||
ModelCounts: make([]int, 31),
|
||||
AdapterCounts: make([]int, 31),
|
||||
EnforcerCounts: make([]int, 31),
|
||||
dashboard := make(map[string][]int64)
|
||||
dashboardMap := sync.Map{}
|
||||
tableNames := []string{"organization", "user", "provider", "application", "subscription", "role", "group", "resource", "cert", "permission", "transaction", "model", "adapter", "enforcer"}
|
||||
|
||||
time30day := time.Now().AddDate(0, 0, -30)
|
||||
var wg sync.WaitGroup
|
||||
var err error
|
||||
wg.Add(len(tableNames))
|
||||
ch := make(chan error, len(tableNames))
|
||||
for _, tableName := range tableNames {
|
||||
dashboard[tableName+"Counts"] = make([]int64, 31)
|
||||
tableName := tableName
|
||||
go func(ch chan error) {
|
||||
defer wg.Done()
|
||||
dashboardDateItems := []DashboardDateItem{}
|
||||
var countResult int64
|
||||
|
||||
dbQueryBefore := ormer.Engine.Cols("created_time")
|
||||
dbQueryAfter := ormer.Engine.Cols("created_time")
|
||||
|
||||
if owner != "" {
|
||||
dbQueryAfter = dbQueryAfter.And("owner = ?", owner)
|
||||
dbQueryBefore = dbQueryBefore.And("owner = ?", owner)
|
||||
}
|
||||
|
||||
if countResult, err = dbQueryBefore.And("created_time < ?", time30day).Table(tableName).Count(); err != nil {
|
||||
ch <- err
|
||||
return
|
||||
}
|
||||
if err = dbQueryAfter.And("created_time >= ?", time30day).Table(tableName).Find(&dashboardDateItems); err != nil {
|
||||
ch <- err
|
||||
return
|
||||
}
|
||||
|
||||
dashboardMap.Store(tableName, DashboardMapItem{
|
||||
dashboardDateItems: dashboardDateItems,
|
||||
itemCount: countResult,
|
||||
})
|
||||
}(ch)
|
||||
}
|
||||
|
||||
organizations := []Organization{}
|
||||
users := []User{}
|
||||
providers := []Provider{}
|
||||
applications := []Application{}
|
||||
subscriptions := []Subscription{}
|
||||
roles := []Role{}
|
||||
groups := []Group{}
|
||||
resources := []Resource{}
|
||||
certs := []Cert{}
|
||||
permissions := []Permission{}
|
||||
transactions := []Transaction{}
|
||||
models := []Model{}
|
||||
adapters := []Adapter{}
|
||||
enforcers := []Enforcer{}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(14)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&organizations, &Organization{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&users, &User{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&providers, &Provider{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&applications, &Application{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&subscriptions, &Subscription{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&roles, &Role{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&groups, &Group{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&resources, &Resource{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&certs, &Cert{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&permissions, &Permission{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&transactions, &Transaction{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&models, &Model{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&adapters, &Adapter{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&enforcers, &Enforcer{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
wg.Wait()
|
||||
close(ch)
|
||||
|
||||
for err = range ch {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
nowTime := time.Now()
|
||||
for i := 30; i >= 0; i-- {
|
||||
cutTime := nowTime.AddDate(0, 0, -i)
|
||||
dashboard.OrganizationCounts[30-i] = countCreatedBefore(organizations, cutTime)
|
||||
dashboard.UserCounts[30-i] = countCreatedBefore(users, cutTime)
|
||||
dashboard.ProviderCounts[30-i] = countCreatedBefore(providers, cutTime)
|
||||
dashboard.ApplicationCounts[30-i] = countCreatedBefore(applications, cutTime)
|
||||
dashboard.SubscriptionCounts[30-i] = countCreatedBefore(subscriptions, cutTime)
|
||||
dashboard.RoleCounts[30-i] = countCreatedBefore(roles, cutTime)
|
||||
dashboard.GroupCounts[30-i] = countCreatedBefore(groups, cutTime)
|
||||
dashboard.ResourceCounts[30-i] = countCreatedBefore(resources, cutTime)
|
||||
dashboard.CertCounts[30-i] = countCreatedBefore(certs, cutTime)
|
||||
dashboard.PermissionCounts[30-i] = countCreatedBefore(permissions, cutTime)
|
||||
dashboard.TransactionCounts[30-i] = countCreatedBefore(transactions, cutTime)
|
||||
dashboard.ModelCounts[30-i] = countCreatedBefore(models, cutTime)
|
||||
dashboard.AdapterCounts[30-i] = countCreatedBefore(adapters, cutTime)
|
||||
dashboard.EnforcerCounts[30-i] = countCreatedBefore(enforcers, cutTime)
|
||||
for _, tableName := range tableNames {
|
||||
item, exist := dashboardMap.Load(tableName)
|
||||
if !exist {
|
||||
continue
|
||||
}
|
||||
dashboard[tableName+"Counts"][30-i] = countCreatedBefore(item.(DashboardMapItem), cutTime)
|
||||
}
|
||||
}
|
||||
return dashboard, nil
|
||||
return &dashboard, nil
|
||||
}
|
||||
|
||||
func countCreatedBefore(objects interface{}, before time.Time) int {
|
||||
count := 0
|
||||
switch obj := objects.(type) {
|
||||
case []Organization:
|
||||
for _, o := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", o.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []User:
|
||||
for _, u := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", u.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Provider:
|
||||
for _, p := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", p.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Application:
|
||||
for _, a := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", a.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Subscription:
|
||||
for _, s := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", s.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Role:
|
||||
for _, r := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", r.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Group:
|
||||
for _, g := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", g.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Resource:
|
||||
for _, r := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", r.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Cert:
|
||||
for _, c := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", c.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Permission:
|
||||
for _, p := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", p.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Transaction:
|
||||
for _, t := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", t.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Model:
|
||||
for _, m := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", m.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Adapter:
|
||||
for _, a := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", a.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Enforcer:
|
||||
for _, e := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", e.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
func countCreatedBefore(dashboardMapItem DashboardMapItem, before time.Time) int64 {
|
||||
count := dashboardMapItem.itemCount
|
||||
for _, e := range dashboardMapItem.dashboardDateItems {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", e.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
|
@@ -16,6 +16,7 @@ package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/beego/beego/context"
|
||||
@@ -70,6 +71,7 @@ type Provider struct {
|
||||
IdP string `xorm:"mediumtext" json:"idP"`
|
||||
IssuerUrl string `xorm:"varchar(100)" json:"issuerUrl"`
|
||||
EnableSignAuthnRequest bool `json:"enableSignAuthnRequest"`
|
||||
EmailRegex string `xorm:"varchar(200)" json:"emailRegex"`
|
||||
|
||||
ProviderUrl string `xorm:"varchar(200)" json:"providerUrl"`
|
||||
}
|
||||
@@ -200,6 +202,13 @@ func UpdateProvider(id string, provider *Provider) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if provider.EmailRegex != "" {
|
||||
_, err := regexp.Compile(provider.EmailRegex)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
if name != provider.Name {
|
||||
err := providerChangeTrigger(name, provider.Name)
|
||||
if err != nil {
|
||||
@@ -234,6 +243,13 @@ func AddProvider(provider *Provider) (bool, error) {
|
||||
provider.IntranetEndpoint = util.GetEndPoint(provider.IntranetEndpoint)
|
||||
}
|
||||
|
||||
if provider.EmailRegex != "" {
|
||||
_, err := regexp.Compile(provider.EmailRegex)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.Insert(provider)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -421,7 +437,7 @@ func FromProviderToIdpInfo(ctx *context.Context, provider *Provider) *idp.Provid
|
||||
providerInfo.ClientId = provider.ClientId2
|
||||
providerInfo.ClientSecret = provider.ClientSecret2
|
||||
}
|
||||
} else if provider.Type == "AzureAD" || provider.Type == "AzureADB2C" || provider.Type == "ADFS" || provider.Type == "Okta" {
|
||||
} else if provider.Type == "ADFS" || provider.Type == "AzureAD" || provider.Type == "AzureADB2C" || provider.Type == "Casdoor" || provider.Type == "Okta" {
|
||||
providerInfo.HostUrl = provider.Domain
|
||||
}
|
||||
|
||||
|
@@ -309,22 +309,29 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
||||
}, nil
|
||||
}
|
||||
|
||||
var oldTokenScope string
|
||||
if application.TokenFormat == "JWT-Standard" {
|
||||
_, err = ParseStandardJwtToken(refreshToken, cert)
|
||||
oldToken, err := ParseStandardJwtToken(refreshToken, cert)
|
||||
if err != nil {
|
||||
return &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
||||
}, nil
|
||||
}
|
||||
oldTokenScope = oldToken.Scope
|
||||
} else {
|
||||
_, err = ParseJwtToken(refreshToken, cert)
|
||||
oldToken, err := ParseJwtToken(refreshToken, cert)
|
||||
if err != nil {
|
||||
return &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
||||
}, nil
|
||||
}
|
||||
oldTokenScope = oldToken.Scope
|
||||
}
|
||||
|
||||
if scope == "" {
|
||||
scope = oldTokenScope
|
||||
}
|
||||
|
||||
// generate a new token
|
||||
|
@@ -237,6 +237,7 @@ type MfaAccount struct {
|
||||
AccountName string `xorm:"varchar(100)" json:"accountName"`
|
||||
Issuer string `xorm:"varchar(100)" json:"issuer"`
|
||||
SecretKey string `xorm:"varchar(100)" json:"secretKey"`
|
||||
Origin string `xorm:"varchar(100)" json:"origin"`
|
||||
}
|
||||
|
||||
type FaceId struct {
|
||||
|
@@ -68,8 +68,10 @@ func handleAccessRequest(w radius.ResponseWriter, r *radius.Request) {
|
||||
log.Printf("handleAccessRequest() username=%v, org=%v, password=%v", username, organization, password)
|
||||
|
||||
if organization == "" {
|
||||
w.Write(r.Response(radius.CodeAccessReject))
|
||||
return
|
||||
organization = conf.GetConfigString("radiusDefaultOrganization")
|
||||
if organization == "" {
|
||||
organization = "built-in"
|
||||
}
|
||||
}
|
||||
|
||||
var user *object.User
|
||||
|
97
util/process.go
Normal file
97
util/process.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getPidByPort(port int) (int, error) {
|
||||
var cmd *exec.Cmd
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
cmd = exec.Command("cmd", "/c", "netstat -ano | findstr :"+strconv.Itoa(port))
|
||||
case "darwin", "linux":
|
||||
cmd = exec.Command("lsof", "-i", ":"+strconv.Itoa(port))
|
||||
default:
|
||||
return 0, fmt.Errorf("unsupported OS: %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
if exitErr.ExitCode() == 1 {
|
||||
return 0, nil
|
||||
}
|
||||
} else {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
lines := strings.Split(string(output), "\n")
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) > 0 {
|
||||
if runtime.GOOS == "windows" {
|
||||
if fields[1] == "0.0.0.0:"+strconv.Itoa(port) {
|
||||
pid, err := strconv.Atoi(fields[len(fields)-1])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return pid, nil
|
||||
}
|
||||
} else {
|
||||
pid, err := strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return pid, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func StopOldInstance(port int) error {
|
||||
pid, err := getPidByPort(port)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if pid == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
process, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = process.Kill()
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
fmt.Printf("The old instance with pid: %d has been stopped\n", pid)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@@ -633,6 +633,20 @@ class ProviderEditPage extends React.Component {
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
{
|
||||
this.state.provider.category === "OAuth" ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Email regex"), i18next.t("provider:Email regex - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22}>
|
||||
<TextArea rows={4} value={this.state.provider.emailRegex} onChange={e => {
|
||||
this.updateProviderField("emailRegex", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
this.state.provider.type === "Custom" ? (
|
||||
<React.Fragment>
|
||||
|
@@ -105,6 +105,18 @@ class MfaAccountTable extends React.Component {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("mfaAccount:Origin"),
|
||||
dataIndex: "origin",
|
||||
key: "origin",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Input value={text} onChange={e => {
|
||||
this.updateField(table, index, "origin", e.target.value);
|
||||
}} />
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("mfaAccount:Secret Key"),
|
||||
dataIndex: "secretKey",
|
||||
|
Reference in New Issue
Block a user