Added user connection verification; Added filter to auto hide revoked certs; Some fixes
This commit is contained in:
parent
6e9a553884
commit
a65bda0f19
7 changed files with 50 additions and 39 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>-->
|
|
||||||
<!--<!– <th scope="col">Connection status</th>–>-->
|
|
||||||
<!-- </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>-->
|
|
||||||
<!--<!– <td>{{ row.ConnectionStatus }}</td>–>-->
|
|
||||||
<!-- </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
25
main.go
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue