Added user connection verification; Added filter to auto hide revoked certs; Some fixes

This commit is contained in:
Ilya Sosnovsky 2020-11-02 19:30:36 +03:00
parent 6e9a553884
commit a65bda0f19
7 changed files with 50 additions and 39 deletions

View File

@ -24,8 +24,8 @@ fi
cp -f /etc/openvpn/setup/openvpn.conf /etc/openvpn/openvpn.conf cp -f /etc/openvpn/setup/openvpn.conf /etc/openvpn/openvpn.conf
[ -d /etc/openvpn/certs/pki ] && chmod 755 /etc/openvpn/certs/pki [ -d $EASY_RSA_LOC/pki ] && chmod 755 $EASY_RSA_LOC/pki
[ -f /etc/openvpn/certs/pki/crl.pem ] && chmod 644 /etc/openvpn/certs/pki/crl.pem [ -f $EASY_RSA_LOC/pki/crl.pem ] && chmod 644 $EASY_RSA_LOC/pki/crl.pem
mkdir -p /etc/openvpn/ccd mkdir -p /etc/openvpn/ccd

View File

@ -8,6 +8,7 @@ dh /etc/openvpn/easyrsa/pki/dh.pem
crl-verify /etc/openvpn/easyrsa/pki/crl.pem crl-verify /etc/openvpn/easyrsa/pki/crl.pem
tls-auth /etc/openvpn/easyrsa/pki/ta.key tls-auth /etc/openvpn/easyrsa/pki/ta.key
key-direction 0 key-direction 0
duplicate-cn
cipher AES-128-CBC cipher AES-128-CBC
management 127.0.0.1 8989 management 127.0.0.1 8989
keepalive 10 60 keepalive 10 60

View File

@ -10,7 +10,7 @@ services:
cap_add: cap_add:
- NET_ADMIN - NET_ADMIN
ports: ports:
- 1194:1194 - 7777:1194
volumes: volumes:
- ./easyrsa:/etc/openvpn/easyrsa - ./easyrsa:/etc/openvpn/easyrsa
- ./ccd:/etc/openvpn/ccd - ./ccd:/etc/openvpn/ccd

View File

@ -108,6 +108,9 @@ new Vue({
showWhenStatus: 'Active' showWhenStatus: 'Active'
} }
], ],
filters: {
hide_revoked: true
},
u: { u: {
newUserName: '', newUserName: '',
// newUserPassword: 'nopass', // newUserPassword: 'nopass',
@ -127,9 +130,6 @@ new Vue({
} }
}, },
watch: { watch: {
// u: function () {
// this.u.columns = Object.keys(this.u.data[0]) //.reverse()
// }
}, },
mounted: function () { mounted: function () {
this.u_get_data() this.u_get_data()
@ -209,11 +209,22 @@ new Vue({
modalShowCcdDisplay: function () { modalShowCcdDisplay: function () {
return this.u.modalShowCcdVisible ? {display: 'flex'} : {} return this.u.modalShowCcdVisible ? {display: 'flex'} : {}
}, },
filteredRows: function() {
var _this = this;
if(_this.filters.hide_revoked) {
return _this.rows.filter(function(account) {
return account.AccountStatus === "Active";
});
} else {
return _this.rows;
}
}
}, },
methods: { methods: {
rowStyleClassFn: function(row) { rowStyleClassFn: function(row) {
return row.ConnectionStatus == '' ? '' : 'active-row'; return row.ConnectionStatus == 'Connected' ? 'connected-user' : '' ;
}, },
rowActionFn: function(e) { rowActionFn: function(e) {
this.username = e.target.dataset.username; this.username = e.target.dataset.username;

View File

@ -44,6 +44,10 @@ body {
margin: 0.1rem; margin: 0.1rem;
} }
.connected-user {
background-color: rgba(162, 245, 169, 0.5);
}
.new-user-btn { .new-user-btn {
margin-right: 2rem; margin-right: 2rem;
} }

View File

@ -9,42 +9,20 @@
</head> </head>
<body> <body>
<div id="app"> <div id="app">
<!-- <div class="dropdown-menu dropdown-custom" :style="uCtxStyle" v-show="u.ctxVisible">-->
<!-- <button class="dropdown-item" type="button" :data-name="name" :data-text="text" @click.left.stop="u_ctx_click" v-for="text, name in u.ctxMenuItems">{{text}}</button>-->
<!-- </div>-->
<!-- <table class="table table-bordered table-hover">-->
<!-- <thead class="thead-dark">-->
<!-- <tr>-->
<!-- <th scope="col">Name</th>-->
<!-- <th scope="col">Account status</th>-->
<!-- <th scope="col">Expiration date</th>-->
<!-- <th scope="col">Revocation date</th>-->
<!--&lt;!&ndash; <th scope="col">Connection status</th>&ndash;&gt;-->
<!-- </tr>-->
<!-- </thead>-->
<!-- <tbody>-->
<!-- <tr v-for="row in u.data" :data-name="row.Identity" v-bind:style="row.ConnectionStatus" @contextmenu.prevent="u_ctx_show">-->
<!-- <td>{{ row.Identity }}</td>-->
<!-- <td>{{ row.AccountStatus }}</td>-->
<!-- <td>{{ row.ExpirationDate }}</td>-->
<!-- <td>{{ row.RevocationDate }}</td>-->
<!--&lt;!&ndash; <td>{{ row.ConnectionStatus }}</td>&ndash;&gt;-->
<!-- </tr>-->
<!-- </tbody>-->
<!-- </table>-->
<vue-good-table <vue-good-table
:columns="columns" :columns="columns"
:rows="rows" :rows="filteredRows"
:line-numbers="true" :line-numbers="true"
:row-style-class="rowStyleClassFn" :row-style-class="rowStyleClassFn"
:search-options="{ enabled: true}" > :search-options="{ enabled: true}" >
<div slot="table-actions"> <div slot="table-actions">
<button type="button" class="btn btn-sm btn-success el-square" v-on:click.stop="u.modalNewUserVisible=true">Add user</button> <button type="button" class="btn btn-sm btn-success el-square" v-on:click.stop="u.modalNewUserVisible=true">Add user</button>
<button type="button" class="btn btn-sm btn-secondary el-square" v-on:click.stop="filters.hide_revoked=!filters.hide_revoked" v-show="filters.hide_revoked">Show revoked</button>
<button type="button" class="btn btn-sm btn-secondary el-square" v-on:click.stop="filters.hide_revoked=!filters.hide_revoked" v-show="!filters.hide_revoked">Hide revoked</button>
</div> </div>
<div slot="emptystate"> <div slot="emptystate" class="d-flex justify-content-center">
This will show up when there are no rows <h4>No users have been created yet.</h4>
<button type="button" class="btn btn-sm btn-success el-square" v-on:click.stop="u.modalNewUserVisible=true">Add user</button>
</div> </div>
<template slot="table-row" slot-scope="props"> <template slot="table-row" slot-scope="props">
<span v-if="props.column.field == 'actions'"> <span v-if="props.column.field == 'actions'">

25
main.go
View File

@ -373,17 +373,24 @@ func checkUserExist(username string) bool {
func usersList() []openvpnClient { func usersList() []openvpnClient {
users := []openvpnClient{} users := []openvpnClient{}
activeClients := mgmtGetActiveClients()
for _, line := range indexTxtParser(fRead(*indexTxtPath)) { for _, line := range indexTxtParser(fRead(*indexTxtPath)) {
if line.Identity != "server" { if line.Identity != "server" {
ovpnClient := openvpnClient{Identity: line.Identity, ExpirationDate: indexTxtDateToHumanReadable(line.ExpirationDate)}
switch { switch {
case line.Flag == "V": case line.Flag == "V":
users = append(users, openvpnClient{Identity: line.Identity, ExpirationDate: indexTxtDateToHumanReadable(line.ExpirationDate), AccountStatus: "Active"}) ovpnClient.AccountStatus = "Active"
case line.Flag == "R": case line.Flag == "R":
users = append(users, openvpnClient{Identity: line.Identity, RevocationDate: indexTxtDateToHumanReadable(line.RevocationDate), ExpirationDate: indexTxtDateToHumanReadable(line.ExpirationDate), AccountStatus: "Revoked"}) ovpnClient.AccountStatus = "Revoked"
ovpnClient.RevocationDate = indexTxtDateToHumanReadable(line.RevocationDate)
case line.Flag == "E": case line.Flag == "E":
users = append(users, openvpnClient{Identity: line.Identity, RevocationDate: indexTxtDateToHumanReadable(line.RevocationDate), ExpirationDate: indexTxtDateToHumanReadable(line.ExpirationDate), AccountStatus: "Expired"}) ovpnClient.AccountStatus = "Expired"
} }
if isUserConnected(line.Identity, activeClients) {
ovpnClient.ConnectionStatus = "Connected"
}
users = append(users, ovpnClient)
} }
} }
return users return users
@ -520,6 +527,16 @@ func mgmtGetActiveClients() []clientStatus {
return activeClients return activeClients
} }
func isUserConnected(username string, connectedUsers []clientStatus) bool {
for _, connectedUser := range connectedUsers {
if connectedUser.CommonName == username {
return true
}
}
return false
}
func indexTxtDateToHumanReadable(datetime string) string { func indexTxtDateToHumanReadable(datetime string) string {
layout := "060102150405Z" layout := "060102150405Z"
t, err := time.Parse(layout, datetime) t, err := time.Parse(layout, datetime)