Merge pull request #186 from lanrenwo/act_log_device

优化审计日志的UI + 增加客户端的系统型号
This commit is contained in:
bjdgyc 2022-11-13 17:22:23 +08:00 committed by GitHub
commit 8c9e371df8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 97 additions and 74 deletions

View File

@ -41,17 +41,19 @@ type User struct {
}
type UserActLog struct {
Id int `json:"id" xorm:"pk autoincr not null"`
Username string `json:"username" xorm:"varchar(60)"`
GroupName string `json:"group_name" xorm:"varchar(60)"`
IpAddr string `json:"ip_addr" xorm:"varchar(32)"`
RemoteAddr string `json:"remote_addr" xorm:"varchar(32)"`
Os uint8 `json:"os" xorm:"not null default 0 Int"`
Client uint8 `json:"client" xorm:"not null default 0 Int"`
Version string `json:"version" xorm:"varchar(15)"`
Status uint8 `json:"status" xorm:"not null default 0 Int"`
Info string `json:"info" xorm:"varchar(255) not null default ''"` // 详情
CreatedAt time.Time `json:"created_at" xorm:"DateTime created"`
Id int `json:"id" xorm:"pk autoincr not null"`
Username string `json:"username" xorm:"varchar(60)"`
GroupName string `json:"group_name" xorm:"varchar(60)"`
IpAddr string `json:"ip_addr" xorm:"varchar(32)"`
RemoteAddr string `json:"remote_addr" xorm:"varchar(32)"`
Os uint8 `json:"os" xorm:"not null default 0 Int"`
Client uint8 `json:"client" xorm:"not null default 0 Int"`
Version string `json:"version" xorm:"varchar(15)"`
DeviceType string `json:"device_type" xorm:"varchar(128) not null default ''"`
PlatformVersion string `json:"platform_version" xorm:"varchar(15) not null default ''"`
Status uint8 `json:"status" xorm:"not null default 0 Int"`
Info string `json:"info" xorm:"varchar(255) not null default ''"` // 详情
CreatedAt time.Time `json:"created_at" xorm:"DateTime created"`
}
type IpMap struct {

View File

@ -55,7 +55,7 @@ var (
},
InfoOps: []string{ // 信息
UserLogoutLose: "用户掉线",
UserLogoutBanner: "用户取消弹窗",
UserLogoutBanner: "用户取消弹窗/客户端发起的logout",
UserLogoutClient: "用户/客户端主动断开",
UserLogoutTimeout: "Session过期被踢下线",
UserLogoutAdmin: "账号被管理员踢下线",
@ -121,8 +121,8 @@ func (ua *UserActLogProcess) ParseUserAgent(userAgent string) (os_idx, client_id
if len(userAgent) == 0 {
return 5, 2, ""
}
// os
os_idx = 2
// OS
os_idx = 5
if strings.Contains(userAgent, "windows") {
os_idx = 0
} else if strings.Contains(userAgent, "mac os") || strings.Contains(userAgent, "darwin_i386") {
@ -131,15 +131,17 @@ func (ua *UserActLogProcess) ParseUserAgent(userAgent string) (os_idx, client_id
os_idx = 4
} else if strings.Contains(userAgent, "android") {
os_idx = 3
} else if strings.Contains(userAgent, "linux") {
os_idx = 2
}
// client
// Client
client_idx = 2
if strings.Contains(userAgent, "anyconnect") {
client_idx = 0
} else if strings.Contains(userAgent, "openconnect") {
client_idx = 1
}
// ver
// Verion
uaSlice := strings.Split(userAgent, " ")
ver = uaSlice[len(uaSlice)-1]
if ver[0] == 'v' {

View File

@ -48,18 +48,18 @@ func TestParseUserAgent(t *testing.T) {
},
{
name: "linux",
args: args{userAgent: "open anyconnect vpn agent v7.08"},
args: args{userAgent: "cisco anyconnect vpn agent for linux v7.08"},
want: res{os_idx: 2, client_idx: 0, ver: "7.08"},
},
{
name: "openconnect",
args: args{userAgent: "openconnect-gui 1.5.3 v7.08"},
want: res{os_idx: 2, client_idx: 1, ver: "7.08"},
want: res{os_idx: 5, client_idx: 1, ver: "7.08"},
},
{
name: "unknown",
args: args{userAgent: "unknown 1.4.3 aabcd"},
want: res{os_idx: 2, client_idx: 2, ver: ""},
want: res{os_idx: 5, client_idx: 2, ver: ""},
},
}
for _, tt := range tests {

View File

@ -67,10 +67,12 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) {
}
// 用户活动日志
ua := dbdata.UserActLog{
Username: cr.Auth.Username,
GroupName: cr.GroupSelect,
RemoteAddr: r.RemoteAddr,
Status: dbdata.UserAuthSuccess,
Username: cr.Auth.Username,
GroupName: cr.GroupSelect,
RemoteAddr: r.RemoteAddr,
Status: dbdata.UserAuthSuccess,
DeviceType: cr.DeviceId.DeviceType,
PlatformVersion: cr.DeviceId.PlatformVersion,
}
// TODO 用户密码校验
err = dbdata.CheckUser(cr.Auth.Username, cr.Auth.Password, cr.GroupSelect)
@ -100,6 +102,8 @@ func LinkAuth(w http.ResponseWriter, r *http.Request) {
sess.MacAddr = strings.ToLower(cr.MacAddressList.MacAddress)
sess.UniqueIdGlobal = cr.DeviceId.UniqueIdGlobal
sess.UserAgent = userAgent
sess.DeviceType = ua.DeviceType
sess.PlatformVersion = ua.PlatformVersion
sess.RemoteAddr = r.RemoteAddr
// 获取客户端mac地址
macHw, err := net.ParseMAC(sess.MacAddr)

View File

@ -196,11 +196,13 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
return
}
dbdata.UserActLogIns.Add(dbdata.UserActLog{
Username: sess.Username,
GroupName: sess.Group,
IpAddr: cSess.IpAddr.String(),
RemoteAddr: cSess.RemoteAddr,
Status: dbdata.UserConnected,
Username: sess.Username,
GroupName: sess.Group,
IpAddr: cSess.IpAddr.String(),
RemoteAddr: cSess.RemoteAddr,
DeviceType: sess.DeviceType,
PlatformVersion: sess.PlatformVersion,
Status: dbdata.UserConnected,
}, cSess.UserAgent)
go LinkCstp(conn, bufRW, cSess)

View File

@ -64,19 +64,21 @@ type DtlsSession struct {
}
type Session struct {
mux sync.RWMutex
Sid string // auth返回的 session-id
Token string // session信息的唯一token
DtlsSid string // dtls协议的 session_id
MacAddr string // 客户端mac地址
UniqueIdGlobal string // 客户端唯一标示
MacHw net.HardwareAddr
Username string // 用户名
Group string
AuthStep string
AuthPass string
RemoteAddr string
UserAgent string
mux sync.RWMutex
Sid string // auth返回的 session-id
Token string // session信息的唯一token
DtlsSid string // dtls协议的 session_id
MacAddr string // 客户端mac地址
UniqueIdGlobal string // 客户端唯一标示
MacHw net.HardwareAddr
Username string // 用户名
Group string
AuthStep string
AuthPass string
RemoteAddr string
UserAgent string
DeviceType string
PlatformVersion string
LastLogin time.Time
IsActive bool
@ -455,11 +457,13 @@ func DelSessByStoken(stoken string) {
func AddUserActLog(cs *ConnSession) {
ua := dbdata.UserActLog{
Username: cs.Sess.Username,
GroupName: cs.Sess.Group,
IpAddr: cs.IpAddr.String(),
RemoteAddr: cs.RemoteAddr,
Status: dbdata.UserLogout,
Username: cs.Sess.Username,
GroupName: cs.Sess.Group,
IpAddr: cs.IpAddr.String(),
RemoteAddr: cs.RemoteAddr,
DeviceType: cs.Sess.DeviceType,
PlatformVersion: cs.Sess.PlatformVersion,
Status: dbdata.UserLogout,
}
ua.Info = dbdata.UserActLogIns.GetInfoOpsById(cs.UserLogoutCode)
dbdata.UserActLogIns.Add(ua, cs.UserAgent)
@ -467,12 +471,14 @@ func AddUserActLog(cs *ConnSession) {
func AddUserActLogBySess(sess *Session) {
ua := dbdata.UserActLog{
Username: sess.Username,
GroupName: sess.Group,
IpAddr: "",
RemoteAddr: sess.RemoteAddr,
Status: dbdata.UserLogout,
Username: sess.Username,
GroupName: sess.Group,
IpAddr: "",
RemoteAddr: sess.RemoteAddr,
DeviceType: sess.DeviceType,
PlatformVersion: sess.PlatformVersion,
Status: dbdata.UserLogout,
}
ua.Info = dbdata.UserActLogIns.GetInfoOpsById(1)
ua.Info = dbdata.UserActLogIns.GetInfoOpsById(dbdata.UserLogoutBanner)
dbdata.UserActLogIns.Add(ua, sess.UserAgent)
}

View File

@ -67,12 +67,12 @@
prop="id"
label="ID"
sortable="custom"
width="60">
width="100">
</el-table-column>
<el-table-column
prop="username"
label="用户名"
width="80">
width="140">
</el-table-column>
<el-table-column
prop="group_name"
@ -88,21 +88,36 @@
<el-tag size="small" v-if="row.status == item.key" disable-transitions :type="item.tag">{{item.value}}</el-tag>
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column
prop="info"
label="操作详情"
min-width="200">
</el-table-column>
<el-table-column
prop="created_at"
label="操作时间"
width="150"
:formatter="tableDateFormat">
</el-table-column>
<el-table-column
prop="os"
label="操作系统"
width="82">
min-width="210">
<template slot-scope="{ row }">
<span v-for="(value, item, index) in osOps" :key="index">
{{ row.os == item? value: "" }}
</span>
<div class="sub_txt">型号:
<span v-if="row.device_type != ''">{{ row.device_type }} / {{ row.platform_version }}</span>
<span v-else> - </span>
</div>
</template>
</el-table-column>
</el-table-column>
<el-table-column
prop="client"
label="客户端"
width="100">
width="150">
<template slot-scope="{ row }">
<span v-for="(value, item, index) in clientOps" :key="index">
{{ row.client == item? value: "" }}
@ -119,19 +134,8 @@
prop="remote_addr"
label="外网IP"
width="120">
</el-table-column>
<el-table-column
prop="info"
label="详情">
</el-table-column>
<el-table-column
prop="created_at"
label="操作时间"
width="130"
:formatter="tableDateFormat">
</el-table-column>
</el-table-column>
</el-table>
<div class="sh-20"></div>
<el-pagination
background
@ -253,4 +257,7 @@ export default {
/deep/ .el-table td {
padding: 5px 0;
}
.sub_txt {
color: #88909B;
}
</style>

View File

@ -2,11 +2,11 @@
<div>
<el-card>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="用户访问日志" name="access_audit">
<AuditAccess ref="auditAccess"></AuditAccess>
</el-tab-pane>
<el-tab-pane label="用户活动日志" name="act_log">
<AuditActLog ref="auditActLog"></AuditActLog>
</el-tab-pane>
<el-tab-pane label="用户访问日志" name="access_audit">
<AuditAccess ref="auditAccess"></AuditAccess>
</el-tab-pane>
</el-tabs>
</el-card>
@ -33,7 +33,7 @@ export default {
},
data() {
return {
activeName: "access_audit",
activeName: "act_log",
}
},
methods: {