show the owner name in admin UI (#24)

* fixes #21

* updated changelog
config-options-for-ports
PLACE 4 years ago committed by GitHub
parent 7384a63250
commit 89ab8fa297
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [master]
### Changes
- The admin UI will now show the device owner's name or email if available.
- The admin UI will now show the auth provider for a given device if more than 1 auth provider is in use.
## [0.1.1]
### Changes

@ -12,6 +12,7 @@ import (
"github.com/pkg/errors"
"github.com/place1/wg-access-server/internal/storage"
"github.com/place1/wg-access-server/pkg/authnz/authsession"
"github.com/sirupsen/logrus"
)
@ -45,7 +46,7 @@ func (d *DeviceManager) StartSync(disableMetadataCollection bool) error {
return nil
}
func (d *DeviceManager) AddDevice(user string, name string, publicKey string) (*storage.Device, error) {
func (d *DeviceManager) AddDevice(identity *authsession.Identity, name string, publicKey string) (*storage.Device, error) {
if name == "" {
return nil, errors.New("device name must not be empty")
}
@ -56,11 +57,14 @@ func (d *DeviceManager) AddDevice(user string, name string, publicKey string) (*
}
device := &storage.Device{
Owner: user,
Name: name,
PublicKey: publicKey,
Address: clientAddr,
CreatedAt: time.Now(),
Owner: identity.Subject,
OwnerName: identity.Name,
OwnerEmail: identity.Email,
OwnerProvider: identity.Provider,
Name: name,
PublicKey: publicKey,
Address: clientAddr,
CreatedAt: time.Now(),
}
if err := d.SaveDevice(device); err != nil {

@ -25,7 +25,7 @@ func (d *DeviceService) AddDevice(ctx context.Context, req *proto.AddDeviceReq)
return nil, status.Errorf(codes.PermissionDenied, "not authenticated")
}
device, err := d.DeviceManager.AddDevice(user.Subject, req.GetName(), req.GetPublicKey())
device, err := d.DeviceManager.AddDevice(user, req.GetName(), req.GetPublicKey())
if err != nil {
logrus.Error(err)
return nil, status.Errorf(codes.Internal, "failed to add device")
@ -89,6 +89,9 @@ func mapDevice(d *storage.Device) *proto.Device {
return &proto.Device{
Name: d.Name,
Owner: d.Owner,
OwnerName: d.OwnerName,
OwnerEmail: d.OwnerEmail,
OwnerProvider: d.OwnerProvider,
PublicKey: d.PublicKey,
Address: d.Address,
CreatedAt: TimeToTimestamp(&d.CreatedAt),

@ -12,11 +12,14 @@ type Storage interface {
}
type Device struct {
Owner string `json:"owner"`
Name string `json:"name"`
PublicKey string `json:"publicKey"`
Address string `json:"address"`
CreatedAt time.Time `json:"createdAt"`
Owner string `json:"owner"`
OwnerName string `json:"ownerName"`
OwnerEmail string `json:"ownerEmail"`
OwnerProvider string `json:"ownerProvider"`
Name string `json:"name"`
PublicKey string `json:"publicKey"`
Address string `json:"address"`
CreatedAt time.Time `json:"createdAt"`
/**
* Metadata fields below.

@ -40,7 +40,10 @@ func basicAuthLogin(c *BasicAuthConfig, runtime *authruntime.ProviderRuntime) ht
if ok := checkCreds(c.Users, u, p); ok {
runtime.SetSession(w, r, &authsession.AuthSession{
Identity: &authsession.Identity{
Subject: u,
Provider: "basic",
Subject: u,
Name: u,
Email: "", // basic auth has no email
},
})
runtime.Done(w, r)

@ -1,10 +1,10 @@
package authconfig
import (
"strings"
"context"
"net/http"
"net/url"
"strings"
"time"
"github.com/coreos/go-oidc"
@ -102,9 +102,17 @@ func (c *OIDCConfig) callbackHandler(runtime *authruntime.ProviderRuntime, oauth
return
}
var claims struct {
Name string `json:"name"`
}
info.Claims(&claims)
runtime.SetSession(w, r, &authsession.AuthSession{
Identity: &authsession.Identity{
Subject: info.Subject,
Provider: c.Name,
Subject: info.Subject,
Email: info.Email,
Name: claims.Name,
},
})

@ -1,6 +1,18 @@
package authsession
type Identity struct {
// Provider is the name of the authentication provider
// that authenticated (created) this Identity struct.
Provider string
// Subject is the canonical identifer for this Identity.
Subject string
Claims Claims
// Name is the name of the person this Identity refers to.
// It may be empty.
Name string
// Email is the email address of the person this Identity refers to.
// It may be empty.
Email string
// Claims are any additional claims that middleware have
// added to this Identity.
Claims Claims
}

@ -25,6 +25,9 @@ message Device {
int64 receive_bytes = 8;
int64 transmit_bytes = 9;
string endpoint = 10;
string owner_name = 11;
string owner_email = 12;
string owner_provider = 13;
}
message AddDeviceReq {

@ -37,6 +37,9 @@ type Device struct {
ReceiveBytes int64 `protobuf:"varint,8,opt,name=receive_bytes,json=receiveBytes,proto3" json:"receive_bytes,omitempty"`
TransmitBytes int64 `protobuf:"varint,9,opt,name=transmit_bytes,json=transmitBytes,proto3" json:"transmit_bytes,omitempty"`
Endpoint string `protobuf:"bytes,10,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
OwnerName string `protobuf:"bytes,11,opt,name=owner_name,json=ownerName,proto3" json:"owner_name,omitempty"`
OwnerEmail string `protobuf:"bytes,12,opt,name=owner_email,json=ownerEmail,proto3" json:"owner_email,omitempty"`
OwnerProvider string `protobuf:"bytes,13,opt,name=owner_provider,json=ownerProvider,proto3" json:"owner_provider,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -137,6 +140,27 @@ func (m *Device) GetEndpoint() string {
return ""
}
func (m *Device) GetOwnerName() string {
if m != nil {
return m.OwnerName
}
return ""
}
func (m *Device) GetOwnerEmail() string {
if m != nil {
return m.OwnerEmail
}
return ""
}
func (m *Device) GetOwnerProvider() string {
if m != nil {
return m.OwnerProvider
}
return ""
}
type AddDeviceReq struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
PublicKey string `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
@ -376,37 +400,40 @@ func init() {
func init() { proto.RegisterFile("devices.proto", fileDescriptor_6d27ec3f2c0e2043) }
var fileDescriptor_6d27ec3f2c0e2043 = []byte{
// 467 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xcb, 0x6f, 0xd3, 0x40,
0x10, 0xc6, 0xe3, 0xa4, 0x79, 0x78, 0x92, 0x14, 0x3a, 0x81, 0x6a, 0x65, 0x40, 0x58, 0x5b, 0x55,
0xf2, 0xc9, 0x15, 0x41, 0x48, 0x70, 0x40, 0x22, 0xa8, 0x20, 0x04, 0x9c, 0x2c, 0xee, 0x96, 0x63,
0x0f, 0xad, 0x55, 0xbf, 0xea, 0xdd, 0x16, 0xe5, 0x0f, 0xe0, 0x7f, 0xe6, 0x88, 0xbc, 0x6b, 0xa7,
0x76, 0x1a, 0x1e, 0x27, 0x7b, 0xbe, 0xef, 0xdb, 0x99, 0x9d, 0x9f, 0x6c, 0x98, 0x47, 0x74, 0x1b,
0x87, 0x24, 0xdc, 0xa2, 0xcc, 0x65, 0x8e, 0x43, 0xf5, 0xb0, 0x9e, 0x5f, 0xe4, 0xf9, 0x45, 0x42,
0x67, 0xaa, 0x5a, 0xdf, 0x7c, 0x3f, 0x93, 0x71, 0x4a, 0x42, 0x06, 0x69, 0xa1, 0x73, 0xd6, 0x93,
0xdd, 0x00, 0xa5, 0x85, 0xdc, 0x68, 0x93, 0xff, 0xea, 0xc3, 0xe8, 0x5c, 0xb5, 0x45, 0x84, 0x83,
0x2c, 0x48, 0x89, 0x19, 0xb6, 0xe1, 0x98, 0x9e, 0x7a, 0xc7, 0x47, 0x30, 0xcc, 0x7f, 0x64, 0x54,
0xb2, 0xbe, 0x12, 0x75, 0x81, 0xcf, 0x00, 0x8a, 0x9b, 0x75, 0x12, 0x87, 0xfe, 0x15, 0x6d, 0xd8,
0x40, 0x59, 0xa6, 0x56, 0xbe, 0xd0, 0x06, 0x19, 0x8c, 0x83, 0x28, 0x2a, 0x49, 0x08, 0x76, 0xa0,
0xbc, 0xa6, 0xc4, 0x37, 0x00, 0x61, 0x49, 0x81, 0xa4, 0xc8, 0x0f, 0x24, 0x1b, 0xda, 0x86, 0x33,
0x5d, 0x5a, 0xae, 0xbe, 0x9f, 0xdb, 0xdc, 0xcf, 0xfd, 0xd6, 0x2c, 0xe0, 0x99, 0x75, 0x7a, 0x25,
0xf1, 0x29, 0x98, 0x61, 0x9e, 0x65, 0x14, 0x4a, 0x8a, 0xd8, 0xc8, 0x36, 0x9c, 0x89, 0x77, 0x27,
0xe0, 0x67, 0x58, 0x24, 0x81, 0x90, 0xfe, 0x65, 0x90, 0x45, 0xe2, 0x32, 0xb8, 0x22, 0xbf, 0xa2,
0xc0, 0xc6, 0xff, 0x9c, 0x70, 0x54, 0x1d, 0xfb, 0xd4, 0x9c, 0xaa, 0x74, 0x3c, 0x81, 0x79, 0x49,
0x21, 0xc5, 0xb7, 0xe4, 0xaf, 0x37, 0x92, 0x04, 0x9b, 0xd8, 0x86, 0x33, 0xf0, 0x66, 0xb5, 0xf8,
0xbe, 0xd2, 0xf0, 0x14, 0x0e, 0x65, 0x19, 0x64, 0x22, 0x8d, 0x65, 0x9d, 0x32, 0x55, 0x6a, 0xde,
0xa8, 0x3a, 0x66, 0xc1, 0x84, 0xb2, 0xa8, 0xc8, 0xe3, 0x4c, 0x32, 0x50, 0x2c, 0xb6, 0x35, 0x5f,
0xc1, 0x6c, 0x15, 0x45, 0x1a, 0xbe, 0x47, 0xd7, 0x7b, 0xf9, 0x77, 0x49, 0xf7, 0x77, 0x48, 0xf3,
0x87, 0x70, 0xf8, 0x35, 0x16, 0x52, 0xf7, 0x10, 0x1e, 0x5d, 0xf3, 0x57, 0x3b, 0x8a, 0xc0, 0x13,
0x18, 0xc6, 0x92, 0x52, 0xc1, 0x0c, 0x7b, 0xe0, 0x4c, 0x97, 0x73, 0x4d, 0xc1, 0xad, 0xe7, 0x6a,
0x8f, 0x9f, 0xc2, 0x83, 0x73, 0x4a, 0x48, 0xd2, 0x5f, 0xaf, 0xc3, 0x17, 0x70, 0x54, 0x75, 0x5f,
0x25, 0x49, 0x6b, 0xe4, 0xeb, 0xfb, 0xe2, 0xff, 0x4d, 0x5d, 0xfe, 0xec, 0xc3, 0xb8, 0x3e, 0x83,
0x2f, 0xc0, 0xdc, 0xd2, 0xc0, 0x45, 0x1d, 0x6f, 0xf3, 0xb1, 0xba, 0x3d, 0x78, 0x0f, 0xdf, 0xc2,
0xb4, 0xb5, 0x2b, 0x3e, 0xae, 0xfd, 0x2e, 0x11, 0x6b, 0xaf, 0x2c, 0x78, 0x0f, 0xdf, 0xc1, 0xac,
0xbd, 0x33, 0x1e, 0x6f, 0xfb, 0x77, 0x40, 0x58, 0xc7, 0xf7, 0x3e, 0x9f, 0x0f, 0xd5, 0x0f, 0xc4,
0x7b, 0xf8, 0x51, 0xc3, 0xbe, 0xdb, 0x1c, 0x59, 0x6b, 0x58, 0x87, 0x92, 0xf5, 0x27, 0x47, 0xf0,
0xde, 0x7a, 0xa4, 0xac, 0x97, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x2f, 0x41, 0xb7, 0x19, 0xe1,
0x03, 0x00, 0x00,
// 513 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xdb, 0x6e, 0xd3, 0x40,
0x10, 0x8d, 0x93, 0xe6, 0xe2, 0x49, 0x5c, 0xe8, 0x04, 0xaa, 0x95, 0x01, 0x35, 0x72, 0x55, 0x29,
0x4f, 0xa9, 0x08, 0x42, 0x82, 0x07, 0x24, 0x82, 0x5a, 0x84, 0x00, 0x21, 0x64, 0xf1, 0x6e, 0x39,
0xde, 0xa1, 0x5d, 0xd5, 0xb7, 0x7a, 0xb7, 0x41, 0xf9, 0x00, 0xbe, 0x93, 0x5f, 0x41, 0xbb, 0xeb,
0xa4, 0x49, 0x5a, 0x2e, 0x4f, 0xf6, 0x9c, 0x73, 0xe6, 0x76, 0xc6, 0x06, 0x8f, 0xd3, 0x42, 0x24,
0x24, 0x27, 0x65, 0x55, 0xa8, 0x02, 0xdb, 0xe6, 0xe1, 0x1f, 0x5d, 0x14, 0xc5, 0x45, 0x4a, 0xa7,
0x26, 0x9a, 0xdf, 0x7c, 0x3f, 0x55, 0x22, 0x23, 0xa9, 0xe2, 0xac, 0xb4, 0x3a, 0xff, 0xc9, 0xae,
0x80, 0xb2, 0x52, 0x2d, 0x2d, 0x19, 0xfc, 0x6a, 0x41, 0xe7, 0xcc, 0x94, 0x45, 0x84, 0xbd, 0x3c,
0xce, 0x88, 0x39, 0x23, 0x67, 0xec, 0x86, 0xe6, 0x1d, 0x1f, 0x41, 0xbb, 0xf8, 0x91, 0x53, 0xc5,
0x9a, 0x06, 0xb4, 0x01, 0x3e, 0x03, 0x28, 0x6f, 0xe6, 0xa9, 0x48, 0xa2, 0x2b, 0x5a, 0xb2, 0x96,
0xa1, 0x5c, 0x8b, 0x7c, 0xa2, 0x25, 0x32, 0xe8, 0xc6, 0x9c, 0x57, 0x24, 0x25, 0xdb, 0x33, 0xdc,
0x2a, 0xc4, 0xd7, 0x00, 0x49, 0x45, 0xb1, 0x22, 0x1e, 0xc5, 0x8a, 0xb5, 0x47, 0xce, 0xb8, 0x3f,
0xf5, 0x27, 0x76, 0xbe, 0xc9, 0x6a, 0xbe, 0xc9, 0xb7, 0xd5, 0x02, 0xa1, 0x5b, 0xab, 0x67, 0x0a,
0x9f, 0x82, 0x9b, 0x14, 0x79, 0x4e, 0x89, 0x22, 0xce, 0x3a, 0x23, 0x67, 0xdc, 0x0b, 0x6f, 0x01,
0xfc, 0x08, 0xc3, 0x34, 0x96, 0x2a, 0xba, 0x8c, 0x73, 0x2e, 0x2f, 0xe3, 0x2b, 0x8a, 0xb4, 0x0b,
0xac, 0xfb, 0xcf, 0x0e, 0x07, 0x3a, 0xed, 0xc3, 0x2a, 0x4b, 0xe3, 0x78, 0x0c, 0x5e, 0x45, 0x09,
0x89, 0x05, 0x45, 0xf3, 0xa5, 0x22, 0xc9, 0x7a, 0x23, 0x67, 0xdc, 0x0a, 0x07, 0x35, 0xf8, 0x4e,
0x63, 0x78, 0x02, 0xfb, 0xaa, 0x8a, 0x73, 0x99, 0x09, 0x55, 0xab, 0x5c, 0xa3, 0xf2, 0x56, 0xa8,
0x95, 0xf9, 0xd0, 0xa3, 0x9c, 0x97, 0x85, 0xc8, 0x15, 0x03, 0xe3, 0xc5, 0x3a, 0xd6, 0x2e, 0x1a,
0x3b, 0x23, 0xe3, 0x7a, 0xdf, 0xba, 0x68, 0x90, 0x2f, 0xda, 0xfa, 0x23, 0xe8, 0x5b, 0x9a, 0xb2,
0x58, 0xa4, 0x6c, 0x60, 0x78, 0x9b, 0x71, 0xae, 0x11, 0x3d, 0x82, 0x15, 0x94, 0x55, 0xb1, 0x10,
0x9c, 0x2a, 0xe6, 0x19, 0x8d, 0x67, 0xd0, 0xaf, 0x35, 0x18, 0xcc, 0x60, 0x30, 0xe3, 0xdc, 0xde,
0x38, 0xa4, 0xeb, 0x7b, 0xcf, 0xbc, 0x7d, 0xd0, 0xe6, 0xce, 0x41, 0x83, 0x87, 0xb0, 0xff, 0x59,
0x48, 0x65, 0x6b, 0xc8, 0x90, 0xae, 0x83, 0x97, 0x3b, 0x88, 0xc4, 0x63, 0x68, 0x0b, 0x45, 0x99,
0x64, 0xce, 0xa8, 0x35, 0xee, 0x4f, 0x3d, 0x6b, 0xf6, 0xa4, 0xee, 0x6b, 0xb9, 0xe0, 0x04, 0x1e,
0x9c, 0x51, 0x4a, 0x8a, 0xfe, 0x3a, 0x4e, 0x30, 0x84, 0x03, 0x5d, 0x7d, 0x96, 0xa6, 0x1b, 0x2d,
0x5f, 0xdd, 0x05, 0xff, 0xaf, 0xeb, 0xf4, 0x67, 0x13, 0xba, 0x75, 0x0e, 0x3e, 0x07, 0x77, 0xed,
0x06, 0x0e, 0x6b, 0xf9, 0xa6, 0x3f, 0xfe, 0x76, 0x8d, 0xa0, 0x81, 0x6f, 0xa0, 0xbf, 0xb1, 0x2b,
0x3e, 0xae, 0xf9, 0x6d, 0x47, 0xfc, 0x7b, 0x61, 0x19, 0x34, 0xf0, 0x2d, 0x0c, 0x36, 0x77, 0xc6,
0xc3, 0x75, 0xfd, 0x2d, 0x23, 0xfc, 0xc3, 0x3b, 0x5f, 0xe9, 0xb9, 0xfe, 0x4f, 0x83, 0x06, 0xbe,
0xb7, 0x66, 0xdf, 0x6e, 0x8e, 0x6c, 0xa3, 0xd9, 0x96, 0x4b, 0xfe, 0x9f, 0x18, 0x19, 0x34, 0xe6,
0x1d, 0x43, 0xbd, 0xf8, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x89, 0x1c, 0x7b, 0x9d, 0x48, 0x04, 0x00,
0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

@ -26,12 +26,20 @@ export class AllDevices extends React.Component {
const rows = this.devices.current();
// show the provider column
// when there is more than 1 provider in use
// i.e. not all devices are from the same auth provider.
const showProviderCol = rows.length >= 2 && rows.some(r => r.ownerProvider !== rows[0].ownerProvider);
return (
<TableContainer>
<Table stickyHeader>
<TableHead>
<TableRow>
<TableCell>Owner</TableCell>
{showProviderCol &&
<TableCell>Auth Provider</TableCell>
}
<TableCell>Device</TableCell>
<TableCell>Connected</TableCell>
<TableCell>Last Seen</TableCell>
@ -41,8 +49,11 @@ export class AllDevices extends React.Component {
{rows.map((row, i) => (
<TableRow key={i}>
<TableCell component="th" scope="row">
{row.owner}
{row.ownerName || row.ownerEmail || row.owner}
</TableCell>
{showProviderCol &&
<TableCell>{row.ownerProvider}</TableCell>
}
<TableCell>{row.name}</TableCell>
<TableCell>{row.connected ? 'yes' : 'no'}</TableCell>
<TableCell>{lastSeen(row.lastHandshakeTime)}</TableCell>

@ -136,6 +136,9 @@ export declare namespace Device {
receiveBytes: number,
transmitBytes: number,
endpoint: string,
ownerName: string,
ownerEmail: string,
ownerProvider: string,
}
}
@ -231,6 +234,30 @@ export class Device extends jspb.Message {
(jspb.Message as any).setProto3StringField(this, 10, value);
}
getOwnerName(): string {
return jspb.Message.getFieldWithDefault(this, 11, "");
}
setOwnerName(value: string): void {
(jspb.Message as any).setProto3StringField(this, 11, value);
}
getOwnerEmail(): string {
return jspb.Message.getFieldWithDefault(this, 12, "");
}
setOwnerEmail(value: string): void {
(jspb.Message as any).setProto3StringField(this, 12, value);
}
getOwnerProvider(): string {
return jspb.Message.getFieldWithDefault(this, 13, "");
}
setOwnerProvider(value: string): void {
(jspb.Message as any).setProto3StringField(this, 13, value);
}
serializeBinary(): Uint8Array {
const writer = new jspb.BinaryWriter();
Device.serializeBinaryToWriter(this, writer);
@ -249,6 +276,9 @@ export class Device extends jspb.Message {
receiveBytes: this.getReceiveBytes(),
transmitBytes: this.getTransmitBytes(),
endpoint: this.getEndpoint(),
ownerName: this.getOwnerName(),
ownerEmail: this.getOwnerEmail(),
ownerProvider: this.getOwnerProvider(),
};
}
@ -294,6 +324,18 @@ export class Device extends jspb.Message {
if (field10.length > 0) {
writer.writeString(10, field10);
}
const field11 = message.getOwnerName();
if (field11.length > 0) {
writer.writeString(11, field11);
}
const field12 = message.getOwnerEmail();
if (field12.length > 0) {
writer.writeString(12, field12);
}
const field13 = message.getOwnerProvider();
if (field13.length > 0) {
writer.writeString(13, field13);
}
}
static deserializeBinary(bytes: Uint8Array): Device {
@ -351,6 +393,18 @@ export class Device extends jspb.Message {
const field10 = reader.readString()
message.setEndpoint(field10);
break;
case 11:
const field11 = reader.readString()
message.setOwnerName(field11);
break;
case 12:
const field12 = reader.readString()
message.setOwnerEmail(field12);
break;
case 13:
const field13 = reader.readString()
message.setOwnerProvider(field13);
break;
default:
reader.skipField();
break;
@ -801,6 +855,9 @@ function DeviceFromObject(obj: Device.AsObject | undefined): Device | undefined
message.setReceiveBytes(obj.receiveBytes);
message.setTransmitBytes(obj.transmitBytes);
message.setEndpoint(obj.endpoint);
message.setOwnerName(obj.ownerName);
message.setOwnerEmail(obj.ownerEmail);
message.setOwnerProvider(obj.ownerProvider);
return message;
}

Loading…
Cancel
Save