Skip to content

Commit 1ce2408

Browse files
authored
add emissary events data to ui (#4)
2 parents cf70719 + 4d357a9 commit 1ce2408

3 files changed

Lines changed: 59 additions & 13 deletions

File tree

cmd/drawbridge/api.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,13 +291,18 @@ func (d *Drawbridge) SetUpProtectedServiceTunnel() error {
291291
if emissaryRequestType != "PS_LIST" {
292292
emissaryRequestedServiceId = emissaryRequestPayload[8:11]
293293
}
294+
295+
// Create and insert an Emissary event into the db.
294296
eventUUID, err := utils.NewUUID()
295297
if err != nil {
296298
slog.Error("Emissary Event", slog.Any("Error", err))
297299
}
300+
// Retrieve the client certificate from the connection by casting the connection as a tls.Conn.
301+
clientCert := clientConn.(*tls.Conn).ConnectionState().PeerCertificates[0]
302+
deviceUUID := clientCert.Subject.SerialNumber
298303
event := emissary.Event{
299304
ID: eventUUID,
300-
DeviceID: eventUUID,
305+
DeviceID: deviceUUID,
301306
ConnectionIP: conn.RemoteAddr().String(),
302307
Type: emissaryRequestType,
303308
TargetService: emissaryRequestedServiceId,
@@ -312,7 +317,8 @@ func (d *Drawbridge) SetUpProtectedServiceTunnel() error {
312317
slog.Error("Emissary Event", slog.Any("DB Error", err))
313318
}
314319

315-
if emissaryRequestType == "PS_CONN" {
320+
switch emissaryRequestType {
321+
case "PS_CONN":
316322
// May be used later after we standardize how and when to read the tcp connection into the buf above.
317323
// d.getRequestProtectedServiceName(clientConn)
318324
emissaryRequestedServiceIdNum, err := strconv.Atoi(emissaryRequestedServiceId)
@@ -357,18 +363,17 @@ func (d *Drawbridge) SetUpProtectedServiceTunnel() error {
357363
io.Copy(clientConn, resourceConn)
358364
// Shut down the connection.
359365
clientConn.Close()
360-
361-
} else {
366+
case "PS_LIST":
362367
// On a new connection, write available services to TCP connection so Emissary can know which
363-
// d.ProtectedServices
364-
368+
// Protected Services are available
365369
var serviceList string
366370
for _, value := range d.ProtectedServices {
367371
// We pad the service id with zeros as we want a fixed-width id for easy parsing. This will allow support for up to 1000 Protected Services.
368372
serviceList += fmt.Sprintf("%s%s,", utils.PadWithZeros(int(value.Service.ID)), value.Service.Name)
369373
}
370374
serviceConnectCommand := fmt.Sprintf("PS_LIST: %s", serviceList)
371375
clientConn.Write([]byte(serviceConnectCommand))
376+
default:
372377
}
373378
}(conn)
374379
}

cmd/drawbridge/persistence/emissary_client_event.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package persistence
22

33
import (
44
"dhens/drawbridge/cmd/drawbridge/emissary"
5+
"dhens/drawbridge/cmd/utils"
56
"fmt"
67
)
78

@@ -26,16 +27,17 @@ func (r *SQLiteRepository) MigrateEmissaryClientEvent() error {
2627

2728
var queryLatestDeviceEventForEachDevice = `
2829
SELECT
29-
c.id AS device_id,
30-
device_ip,
31-
c.name AS device_name,
32-
e.type,
33-
e.target_service,
34-
e.connection_type,
35-
e.timestamp
30+
e.id AS event_id,
31+
e.device_id,
32+
e.device_ip,
33+
e.type,
34+
e.target_service,
35+
e.connection_type,
36+
e.timestamp
3637
FROM
3738
(
3839
SELECT
40+
id,
3941
device_id,
4042
device_ip,
4143
type,
@@ -96,6 +98,7 @@ func (r *SQLiteRepository) GetLatestEventForEachDeviceId(deviceIDs []string) (ma
9698
); err != nil {
9799
return nil, fmt.Errorf("error scanning emissary client database row into a emissary client struct: %s", err)
98100
}
101+
event.Timestamp = utils.BeautifulTimeSince(event.Timestamp)
99102
events[event.DeviceID] = event
100103
}
101104
return events, nil

cmd/utils/utils.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"path"
1313
"path/filepath"
1414
"strings"
15+
"time"
1516
)
1617

1718
// Save file if it does not already exist.
@@ -359,3 +360,40 @@ func NewUUID() (string, error) {
359360
func RandInt(min, max int) int {
360361
return min + rand.Intn(max-min)
361362
}
363+
364+
func BeautifulTimeSince(timestamp string) string {
365+
// Parse the timestamp string
366+
t, err := time.Parse(time.RFC3339, timestamp)
367+
if err != nil {
368+
return "Invalid timestamp"
369+
}
370+
371+
// Calculate the duration between the timestamp and the current time
372+
duration := time.Since(t)
373+
374+
// Define the time thresholds
375+
minuteThreshold := time.Minute
376+
hourThreshold := time.Hour
377+
dayThreshold := 24 * time.Hour
378+
379+
switch {
380+
case duration < minuteThreshold:
381+
return "less than a minute ago"
382+
case duration < 2*minuteThreshold:
383+
return "around a minute ago"
384+
case duration < hourThreshold:
385+
minutes := int(duration.Minutes())
386+
return fmt.Sprintf("%d minutes ago", minutes)
387+
case duration < 2*hourThreshold:
388+
return "around 1 hour ago"
389+
case duration < dayThreshold:
390+
hours := int(duration.Hours())
391+
return fmt.Sprintf("around %d hours ago", hours)
392+
default:
393+
days := int(duration.Hours() / 24)
394+
if days == 1 {
395+
return "1 day ago"
396+
}
397+
return fmt.Sprintf("%d days ago", days)
398+
}
399+
}

0 commit comments

Comments
 (0)