From ef4c3833a4330eda7afe337aa42d14f8c56c2059 Mon Sep 17 00:00:00 2001 From: q1anx1 <55543743+qianxi0410@users.noreply.github.com> Date: Sat, 20 Aug 2022 21:22:46 +0800 Subject: [PATCH] feat: add system info page (#1033) * feat: add system info page * feat: add some code * fix --- authz/authz.go | 1 + controllers/system_info.go | 78 ++++++++++++++++++++++++ go.mod | 6 +- go.sum | 32 ++++++++-- routers/router.go | 3 + util/system.go | 78 ++++++++++++++++++++++++ util/sysytem_test.go | 33 ++++++++++ web/src/App.js | 13 +++- web/src/SystemInfo.js | 111 ++++++++++++++++++++++++++++++++++ web/src/backend/SystemInfo.js | 29 +++++++++ web/src/locales/de/data.json | 9 +++ web/src/locales/en/data.json | 9 +++ web/src/locales/fr/data.json | 9 +++ web/src/locales/ja/data.json | 9 +++ web/src/locales/ko/data.json | 9 +++ web/src/locales/ru/data.json | 9 +++ web/src/locales/zh/data.json | 9 +++ 17 files changed, 439 insertions(+), 8 deletions(-) create mode 100644 controllers/system_info.go create mode 100644 util/system.go create mode 100644 util/sysytem_test.go create mode 100644 web/src/SystemInfo.js create mode 100644 web/src/backend/SystemInfo.js diff --git a/authz/authz.go b/authz/authz.go index b54cb42e..399e0eab 100644 --- a/authz/authz.go +++ b/authz/authz.go @@ -107,6 +107,7 @@ p, *, *, POST, /api/acs, *, * p, *, *, GET, /api/saml/metadata, *, * p, *, *, *, /cas, *, * p, *, *, *, /api/webauthn, *, * +p, *, *, GET, /api/get-release, *, * ` sa := stringadapter.NewAdapter(ruleText) diff --git a/controllers/system_info.go b/controllers/system_info.go new file mode 100644 index 00000000..9b466996 --- /dev/null +++ b/controllers/system_info.go @@ -0,0 +1,78 @@ +// Copyright 2022 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 controllers + +import ( + "github.com/casdoor/casdoor/object" + "github.com/casdoor/casdoor/util" +) + +type SystemInfo struct { + MemoryUsed uint64 `json:"memory_used"` + MemoryTotal uint64 `json:"memory_total"` + CpuUsage []float64 `json:"cpu_usage"` +} + +// GetSystemInfo +// @Title GetSystemInfo +// @Tag System API +// @Description get user's system info +// @Param id query string true "The id of the user" +// @Success 200 {object} object.SystemInfo The Response object +// @router /get-system-info [get] +func (c *ApiController) GetSystemInfo() { + id := c.GetString("id") + if id == "" { + id = c.GetSessionUsername() + } + + user := object.GetUser(id) + if user == nil || !user.IsGlobalAdmin { + c.ResponseError("You are not authorized to access this resource") + } + + cpuUsage, err := util.GetCpuUsage() + if err != nil { + c.ResponseError(err.Error()) + } + + memoryUsed, memoryTotal, err := util.GetMemoryUsage() + if err != nil { + c.ResponseError(err.Error()) + } + + c.Data["json"] = SystemInfo{ + CpuUsage: cpuUsage, + MemoryUsed: memoryUsed, + MemoryTotal: memoryTotal, + } + c.ServeJSON() +} + +// GitRepoVersion +// @Title GitRepoVersion +// @Tag System API +// @Description get local github repo's latest release version info +// @Success 200 {string} local latest version hash of casdoor +// @router /get-release [get] +func (c *ApiController) GitRepoVersion() { + version, err := util.GetGitRepoVersion() + if err != nil { + c.ResponseError(err.Error()) + } + + c.Data["json"] = version + c.ServeJSON() +} diff --git a/go.mod b/go.mod index 741e2ee2..bf2ed62d 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/go-pay/gopay v1.5.72 github.com/go-sql-driver/mysql v1.5.0 github.com/golang-jwt/jwt/v4 v4.2.0 + github.com/google/go-cmp v0.5.8 // indirect github.com/google/uuid v1.2.0 github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lestrrat-go/jwx v0.9.0 @@ -31,13 +32,16 @@ require ( github.com/russellhaering/gosaml2 v0.6.0 github.com/russellhaering/goxmldsig v1.1.1 github.com/satori/go.uuid v1.2.0 + github.com/shirou/gopsutil v3.21.11+incompatible + github.com/shirou/gopsutil/v3 v3.22.7 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.8.0 github.com/tealeg/xlsx v1.0.5 github.com/thanhpk/randstr v1.0.4 golang.org/x/crypto v0.0.0-20220208233918-bba287dce954 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/ini.v1 v1.62.0 // indirect diff --git a/go.sum b/go.sum index 896f4721..c4682402 100644 --- a/go.sum +++ b/go.sum @@ -156,6 +156,7 @@ github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-pay/gopay v1.5.72 h1:3zm64xMBhJBa8rXbm//q5UiGgOa4WO5XYEnU394N2Zw= github.com/go-pay/gopay v1.5.72/go.mod h1:0qOGIJuFW7PKDOjmecwKyW0mgsVImgwB9yPJj0ilpn8= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -219,8 +220,10 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -297,6 +300,7 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/markbates/going v1.0.0 h1:DQw0ZP7NbNlFGcKbcE/IVSOAFzScxRtLpd0rLMzLhq0= github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA= github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911 h1:erppMjjp69Rertg1zlgRbLJH1u+eCmRPxKjMZ5I8/Ro= @@ -340,6 +344,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R9JX0FuA/U= @@ -376,6 +381,10 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo= github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.22.7 h1:flKnuCMfUUrO+oAvwAd6GKZgnPzr098VA/UJ14nhJd4= +github.com/shirou/gopsutil/v3 v3.22.7/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI= github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s= github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= @@ -389,13 +398,15 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= @@ -406,6 +417,10 @@ github.com/tencentcloud/tencentcloud-sdk-go v1.0.154 h1:THBgwGwUQtsw6L53cSSA2wwL github.com/tencentcloud/tencentcloud-sdk-go v1.0.154/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI= github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo= github.com/thanhpk/randstr v1.0.4/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/volcengine/volc-sdk-golang v1.0.19 h1:jJp+aJgK0e//rZ9I0K2Y7ufJwvuZRo/AQsYDynXMNgA= github.com/volcengine/volc-sdk-golang v1.0.19/go.mod h1:+GGi447k4p1I5PNdbpG2GLaF0Ui9vIInTojMM0IfSS4= @@ -417,6 +432,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -537,6 +553,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -559,12 +576,15 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -626,7 +646,6 @@ golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4X golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -739,8 +758,9 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/routers/router.go b/routers/router.go index bb4e4ea6..424f23dc 100644 --- a/routers/router.go +++ b/routers/router.go @@ -202,4 +202,7 @@ func initAPI() { beego.Router("/api/webauthn/signup/finish", &controllers.ApiController{}, "Post:WebAuthnSignupFinish") beego.Router("/api/webauthn/signin/begin", &controllers.ApiController{}, "Get:WebAuthnSigninBegin") beego.Router("/api/webauthn/signin/finish", &controllers.ApiController{}, "Post:WebAuthnSigninFinish") + + beego.Router("/api/get-system-info", &controllers.ApiController{}, "GET:GetSystemInfo") + beego.Router("/api/get-release", &controllers.ApiController{}, "GET:GitRepoVersion") } diff --git a/util/system.go b/util/system.go new file mode 100644 index 00000000..d06499ee --- /dev/null +++ b/util/system.go @@ -0,0 +1,78 @@ +// Copyright 2022 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 ( + "io/ioutil" + "os" + "runtime" + "strings" + "time" + + "github.com/shirou/gopsutil/cpu" + "github.com/shirou/gopsutil/mem" +) + +// get cpu usage +func GetCpuUsage() ([]float64, error) { + usage, err := cpu.Percent(time.Second, true) + return usage, err +} + +var fileDate, version string + +// get memory usage +func GetMemoryUsage() (uint64, uint64, error) { + virtualMem, err := mem.VirtualMemory() + if err != nil { + return 0, 0, err + } + + var m runtime.MemStats + runtime.ReadMemStats(&m) + + return m.TotalAlloc, virtualMem.Total, nil +} + +// get github repo release version +func GetGitRepoVersion() (string, error) { + pwd, err := os.Getwd() + if err != nil { + return "", err + } + + fileInfos, err := ioutil.ReadDir(pwd + "/.git/refs/heads") + for _, v := range fileInfos { + if v.Name() == "master" { + if v.ModTime().String() == fileDate { + return version, nil + } else { + fileDate = v.ModTime().String() + break + } + } + } + + content, err := ioutil.ReadFile(pwd + "/.git/refs/heads/master") + if err != nil { + return "", err + } + + // Convert to full length + temp := string(content) + version = strings.ReplaceAll(temp, "\n", "") + + return version, nil +} diff --git a/util/sysytem_test.go b/util/sysytem_test.go new file mode 100644 index 00000000..09ac2517 --- /dev/null +++ b/util/sysytem_test.go @@ -0,0 +1,33 @@ +// Copyright 2022 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 ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetCpuUsage(t *testing.T) { + usage, err := GetCpuUsage() + assert.Nil(t, err) + t.Log(usage) +} + +func TestGetMemoryUsage(t *testing.T) { + used, total, err := GetMemoryUsage() + assert.Nil(t, err) + t.Log(used, total) +} diff --git a/web/src/App.js b/web/src/App.js index 98c9e23a..3ec44bb6 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -71,6 +71,7 @@ import SamlCallback from "./auth/SamlCallback"; import CasLogout from "./auth/CasLogout"; import ModelListPage from "./ModelListPage"; import ModelEditPage from "./ModelEditPage"; +import SystemInfo from "./SystemInfo"; const {Header, Footer} = Layout; @@ -148,6 +149,8 @@ class App extends Component { this.setState({selectedMenuKey: "/login"}); } else if (uri.includes("/result")) { this.setState({selectedMenuKey: "/result"}); + } else if (uri.includes("/sysinfo")) { + this.setState({selectedMenuKey: "/sysinfo"}); } else { this.setState({selectedMenuKey: -1}); } @@ -478,8 +481,14 @@ class App extends Component { ); + res.push( + + + {i18next.t("general:SysInfo")} + + + ); } - res.push( @@ -560,6 +569,7 @@ class App extends Component { this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> } /> + this.renderLoginIfNotLoggedIn()} /> } />} /> @@ -691,6 +701,7 @@ class App extends Component { this.renderHomeIfLoggedIn()} /> this.renderLoginIfNotLoggedIn()} /> this.renderLoginIfNotLoggedIn( {this.onUpdateAccount(account);}} {...props} />)} /> + this.renderLoginIfNotLoggedIn()} /> } />} /> diff --git a/web/src/SystemInfo.js b/web/src/SystemInfo.js new file mode 100644 index 00000000..8f79afce --- /dev/null +++ b/web/src/SystemInfo.js @@ -0,0 +1,111 @@ +// Copyright 2022 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. + +import {Card, Col, Divider, Progress, Row} from "antd"; +import * as SystemBackend from "./backend/SystemInfo"; +import React from "react"; +import * as Setting from "./Setting"; +import i18next from "i18next"; + +class SystemInfo extends React.Component { + + constructor(props) { + super(props); + this.state = { + cpuUsage: [], + memUsed: 0, + memTotal: 0, + latestVersion: "v1.0.0", + intervalId: null, + }; + } + + UNSAFE_componentWillMount() { + SystemBackend.getSystemInfo(this.props.account?.owner, this.props.account?.name).then(res => { + this.setState({ + cpuUsage: res.cpu_usage, + memUsed: res.memory_used, + memTotal: res.memory_total, + }); + + const id = setInterval(() => { + SystemBackend.getSystemInfo(this.props.account?.owner, this.props.account?.name).then(res => { + this.setState({ + cpuUsage: res.cpu_usage, + memUsed: res.memory_used, + memTotal: res.memory_total, + }); + }); + }, 1000 * 3); + this.setState({intervalId: id}); + }).catch(error => { + Setting.showMessage("error", `System info failed to get: ${error}`); + }); + + SystemBackend.getGitHubLatestReleaseVersion().then(res => { + this.setState({latestVersion: res}); + }).catch(err => { + Setting.showMessage("error", `get latest commit version failed: ${err}`); + }); + } + + componentWillUnmount() { + clearInterval(this.state.intervalId); + } + + render() { + return ( + + + + + + + { + this.state.cpuUsage.length !== 0 && + this.state.cpuUsage.map((usage, i) => { + return ( + + ); + }) + } + + + + + {(Number(this.state.memUsed) / 1024 / 1024).toFixed(2)} MB / {(Number(this.state.memTotal) / 1024 / 1024 / 1024).toFixed(2)} GB +

+ +
+ +
+ + +
{i18next.t("system:An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS")}
+ GitHub: casdoor +
+ {i18next.t("system:Version")}: {this.state.latestVersion.substring(0, 8)} +
+ {i18next.t("system:Official Website")}: casdoor.org +
+ {i18next.t("system:Community")}: contact us +
+ + +
+ ); + } +} + +export default SystemInfo; diff --git a/web/src/backend/SystemInfo.js b/web/src/backend/SystemInfo.js new file mode 100644 index 00000000..581b901f --- /dev/null +++ b/web/src/backend/SystemInfo.js @@ -0,0 +1,29 @@ +// Copyright 2022 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. + +import * as Setting from "../Setting"; + +export function getSystemInfo(owner, name) { + return fetch(`${Setting.ServerUrl}/api/get-system-info?id=${owner}/${encodeURIComponent(name)}`, { + method: "GET", + credentials: "include", + }).then(res => res.json()); +} + +export function getGitHubLatestReleaseVersion() { + return fetch(`${Setting.ServerUrl}/api/get-release`, { + method: "GET", + credentials: "include", + }).then(res => res.json()); +} diff --git a/web/src/locales/de/data.json b/web/src/locales/de/data.json index 836912bb..ba4e0659 100644 --- a/web/src/locales/de/data.json +++ b/web/src/locales/de/data.json @@ -198,6 +198,7 @@ "Swagger": "Swagger", "Sync": "Sync", "Syncers": "Syncers", + "SysInfo": "SysInfo", "Timestamp": "Zeitstempel", "Tokens": "Token", "URL": "URL", @@ -593,6 +594,14 @@ "Table primary key": "Primärschlüssel der Tabelle", "Table primary key - Tooltip": "Primärschlüssel der Tabelle - Tooltip" }, + "system": { + "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS", + "CPU Usage": "CPU Usage", + "Community": "Community", + "Memory Usage": "Memory Usage", + "Official Website": "Official Website", + "Version": "Version" + }, "token": { "Access token": "Zugangs-Token", "Authorization code": "Autorisierungscode", diff --git a/web/src/locales/en/data.json b/web/src/locales/en/data.json index b5098a86..3162d3bf 100644 --- a/web/src/locales/en/data.json +++ b/web/src/locales/en/data.json @@ -198,6 +198,7 @@ "Swagger": "Swagger", "Sync": "Sync", "Syncers": "Syncers", + "SysInfo": "SysInfo", "Timestamp": "Timestamp", "Tokens": "Tokens", "URL": "URL", @@ -593,6 +594,14 @@ "Table primary key": "Table primary key", "Table primary key - Tooltip": "Table primary key - Tooltip" }, + "system": { + "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS", + "CPU Usage": "CPU Usage", + "Community": "Community", + "Memory Usage": "Memory Usage", + "Official Website": "Official Website", + "Version": "Version" + }, "token": { "Access token": "Access token", "Authorization code": "Authorization code", diff --git a/web/src/locales/fr/data.json b/web/src/locales/fr/data.json index 5e8bcc58..1b24f3bd 100644 --- a/web/src/locales/fr/data.json +++ b/web/src/locales/fr/data.json @@ -198,6 +198,7 @@ "Swagger": "Swagger", "Sync": "Sync", "Syncers": "Synchronisateurs", + "SysInfo": "SysInfo", "Timestamp": "Horodatage", "Tokens": "Jetons", "URL": "URL", @@ -593,6 +594,14 @@ "Table primary key": "Clé primaire de la table", "Table primary key - Tooltip": "Clé primaire du tableau - infobulle" }, + "system": { + "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS", + "CPU Usage": "CPU Usage", + "Community": "Community", + "Memory Usage": "Memory Usage", + "Official Website": "Official Website", + "Version": "Version" + }, "token": { "Access token": "Jeton d'accès", "Authorization code": "Code d'autorisation", diff --git a/web/src/locales/ja/data.json b/web/src/locales/ja/data.json index a9885e01..39db2c2f 100644 --- a/web/src/locales/ja/data.json +++ b/web/src/locales/ja/data.json @@ -198,6 +198,7 @@ "Swagger": "Swagger", "Sync": "Sync", "Syncers": "Syncers", + "SysInfo": "システム情報", "Timestamp": "タイムスタンプ", "Tokens": "トークン", "URL": "URL", @@ -593,6 +594,14 @@ "Table primary key": "テーブルのプライマリキー", "Table primary key - Tooltip": "テーブルのプライマリキー - ツールチップ" }, + "system": { + "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS", + "CPU Usage": "CPU Usage", + "Community": "Community", + "Memory Usage": "Memory Usage", + "Official Website": "Official Website", + "Version": "Version" + }, "token": { "Access token": "アクセストークン", "Authorization code": "認証コード", diff --git a/web/src/locales/ko/data.json b/web/src/locales/ko/data.json index 60db0afa..d9cd1ccc 100644 --- a/web/src/locales/ko/data.json +++ b/web/src/locales/ko/data.json @@ -198,6 +198,7 @@ "Swagger": "Swagger", "Sync": "Sync", "Syncers": "Syncers", + "SysInfo": "SysInfo", "Timestamp": "Timestamp", "Tokens": "Tokens", "URL": "URL", @@ -593,6 +594,14 @@ "Table primary key": "Table primary key", "Table primary key - Tooltip": "Table primary key - Tooltip" }, + "system": { + "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS", + "CPU Usage": "CPU Usage", + "Community": "Community", + "Memory Usage": "Memory Usage", + "Official Website": "Official Website", + "Version": "Version" + }, "token": { "Access token": "Access token", "Authorization code": "Authorization code", diff --git a/web/src/locales/ru/data.json b/web/src/locales/ru/data.json index 0beae49d..1f2048f3 100644 --- a/web/src/locales/ru/data.json +++ b/web/src/locales/ru/data.json @@ -198,6 +198,7 @@ "Swagger": "Swagger", "Sync": "Sync", "Syncers": "Синхронизаторы", + "SysInfo": "Информация о системе", "Timestamp": "Отметка времени", "Tokens": "Жетоны", "URL": "URL", @@ -593,6 +594,14 @@ "Table primary key": "Основной ключ таблицы", "Table primary key - Tooltip": "Основная таблица - Подсказка" }, + "system": { + "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS", + "CPU Usage": "CPU Usage", + "Community": "Community", + "Memory Usage": "Memory Usage", + "Official Website": "Official Website", + "Version": "Version" + }, "token": { "Access token": "Маркер доступа", "Authorization code": "Код авторизации", diff --git a/web/src/locales/zh/data.json b/web/src/locales/zh/data.json index 68ae3c89..c9ae7e95 100644 --- a/web/src/locales/zh/data.json +++ b/web/src/locales/zh/data.json @@ -198,6 +198,7 @@ "Swagger": "API文档", "Sync": "同步", "Syncers": "同步器", + "SysInfo": "系统信息", "Timestamp": "时间戳", "Tokens": "令牌", "URL": "链接", @@ -593,6 +594,14 @@ "Table primary key": "表主键", "Table primary key - Tooltip": "表主键,如id" }, + "system": { + "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "一个支持 OAuth 2.0、OIDC、SAML 和 CAS 的 Web UI 的身份和访问管理 (IAM)/单点登录 (SSO) 平台", + "CPU Usage": "CPU Usage", + "Community": "社区", + "Memory Usage": "内存使用率", + "Official Website": "官方网站", + "Version": "版本" + }, "token": { "Access token": "访问令牌", "Authorization code": "授权码",