Now displaying agent number instead of id.

Passing timezone to server side for rendering of time stamps
Configuration of preferred shells.
This commit is contained in:
Erik Brakkee 2024-08-01 19:16:00 +02:00
parent 4c52fb0f12
commit 2e12d0a9fd
8 changed files with 63 additions and 31 deletions

View File

@ -174,7 +174,11 @@ func printHelp(msg string) {
"--warning-time: advance warning time before sessio ends\n" +
"--expiry-time: expiry time of the session\n" +
"--check-interval: interval at which expiry is checked\n" +
"-insecure: allow invalid certificates\n"
"--insecure: allow invalid certificates\n" +
"--shells: comma-separated list of shells to add to the front of theshell search path\n" +
" (e.g. 'zsh,sh'). If the shell name contains a slash,then the path must exist:\n" +
" either relative to the agent's current directory or absolute. Otherwise it is looekd\n" +
" up in the system search path. "
fmt.Fprintln(os.Stderr, helpText)
os.Exit(1)
@ -211,8 +215,14 @@ func main() {
agentExpriryTime := 10 * time.Minute
tickerInterval := 60 * time.Second
insecure := false
shells := []string{"bash", "sh", "ash", "ksh", "zsh", "fish", "tcsh", "csh"}
if runtime.GOOS == "windows" {
shells = []string{"powershell", "bash"}
}
args := os.Args[1:]
additionalShells := []string{}
commaSeparated := ""
for len(args) > 0 && strings.HasPrefix(args[0], "-") {
val := ""
switch args[0] {
@ -228,12 +238,17 @@ func main() {
tickerInterval, args = parseDuration(args, val)
case "--insecure":
insecure = true
case "--shells":
commaSeparated, args = getArg(args)
additionalShells = append(additionalShells, strings.Split(commaSeparated, ",")...)
default:
printHelp("Unknown option " + args[0])
}
args = args[1:]
}
shells = append(additionalShells, shells...)
id = getId(id)
if len(args) != 1 {
@ -266,7 +281,7 @@ func main() {
wsConn := websocketutil.NewWebSocketConn(conn, false)
defer wsConn.Close()
shell := chooseShell()
shell := chooseShell(shells)
serverInfo, err := comms.AgentInitialization(wsConn, comms.NewAgentInfo(shell))
if err != nil {
log.Printf("ERROR: %v", err)
@ -355,14 +370,9 @@ func setupAuthentication(commChannel comms.CommChannel,
return passwordHandler, authorizedKeys
}
func chooseShell() string {
func chooseShell(shells []string) string {
log.Printf("Shell search path is %v", shells)
var err error
shells := []string{"bash", "sh", "ash", "ksh", "zsh", "fish", "tcsh", "csh"}
if runtime.GOOS == "windows" {
shells = []string{"powershell", "bash"}
}
shell := ""
for _, candidate := range shells {
shell, err = exec.LookPath(candidate)

View File

@ -62,6 +62,7 @@ func main() {
state := models.State{}
agent := models.Agent{
PublicId: "id",
GeneratedId: "100",
StartTime: time.Now().In(japan),
AgentInfo: comms.AgentInfo{
Username: "ci",
@ -75,6 +76,7 @@ func main() {
state.Agents = append(state.Agents, agent)
client := models.Client{
PublicId: "c1",
AgentId: "100",
ClientId: 3,
StartTime: time.Now().In(japan),
SessionType: "sftp",

View File

@ -7,6 +7,7 @@ import (
type Agent struct {
PublicId string
GeneratedId string
StartTime time.Time
AgentInfo comms.AgentInfo

View File

@ -6,6 +6,7 @@ import (
type Client struct {
PublicId string
AgentId string
ClientId int
StartTime time.Time
SessionType string

View File

@ -21,6 +21,7 @@ type AgentConnection struct {
commChannel comms.CommChannel
}
var agentIdGenerator = concurrency.NewAtomicCounter()
var clientIdGenerator = concurrency.NewAtomicCounter()
type ClientConnection struct {
@ -33,6 +34,7 @@ func NewAgent(commChannel comms.CommChannel, publicId string, agentInfo comms.Ag
return &AgentConnection{
Agent: models.Agent{
PublicId: publicId,
GeneratedId: strconv.Itoa(agentIdGenerator.IncrementAndGet()),
StartTime: time.Now(),
AgentInfo: agentInfo,
},
@ -40,11 +42,12 @@ func NewAgent(commChannel comms.CommChannel, publicId string, agentInfo comms.Ag
}
}
func NewClient(publicId string, clientConn iowrappers2.ReadWriteAddrCloser,
func NewClient(publicId string, agentId string, clientConn iowrappers2.ReadWriteAddrCloser,
agentConn net.Conn) *ClientConnection {
return &ClientConnection{
Client: models.Client{
PublicId: publicId,
AgentId: agentId,
ClientId: clientIdGenerator.IncrementAndGet(),
StartTime: time.Now(),
},
@ -197,7 +200,7 @@ func (admin *Admin) addClient(publicId string, clientConn iowrappers2.ReadWriteA
log.Println("Sending connection information to agent")
client := NewClient(publicId, clientConn, agentConn)
client := NewClient(publicId, agent.GeneratedId, clientConn, agentConn)
// Before using this connection for SSH we use it to send client metadata to the
// agent

View File

@ -59,20 +59,14 @@ func (sessions *WebSessions) NewSession(wsConnection net.Conn) *WebSession {
}
func GetUserLocation(r *http.Request) (*time.Location, error) {
// Try to get timezone from a custom header
tzName := r.Header.Get("X-Timezone")
// If not found in header, try to get from query parameter
tzName := r.URL.Query().Get("timezone")
if tzName == "" {
tzName = r.URL.Query().Get("tz")
tzName = r.Header.Get("X-Timezone")
}
// If still not found, default to UTC
//log.Println("GetUserLocation: timezone ", tzName)
if tzName == "" {
tzName = "UTC"
}
// Load the location
return time.LoadLocation(tzName)
}

View File

@ -24,15 +24,36 @@ templ BasePage(tab int) {
<title>Converge</title>
</head>
<body>
<script>
<!-- script>
htmx.logAll();
</script -->
<script>
function getTimezone() {
return Intl.DateTimeFormat().resolvedOptions().timeZone;
}
if (!window.originalWebSocket) {
console.log("timezone override for websockets")
window.originalWebSocket = htmx.createWebSocket
htmx.createWebSocket = function(url) {
let modifiedUrl = url + "?timezone=" + getTimezone()
return window.originalWebSocket(modifiedUrl)
}
}
document.body.addEventListener(
"htmx:configRequest",
function(evt) {
console.log("Adding timezone to htmx request headers");
evt.detail.headers["X-Timezone"] = getTimezone();
}
);
</script>
<script src="../static/js/bootstrap.bundle.min.js"
crossorigin="anonymous"></script>
<div class="container-fluid">
<div class="container-fluid" hx-boost="true">
<div class="row">
<div class="col">
<nav class="navbar navbar-expand-sm navbar-light bg-light">

View File

@ -45,7 +45,7 @@ templ State(state *models.State, location *time.Location) {
</thead>
for _, agent := range state.Agents {
<tr>
<td>{agent.PublicId}</td>
<td>{agent.GeneratedId}</td>
<td>{agent.StartTime.In(location).Format(time.DateTime)}</td>
<td>{agent.ExpiryTime.In(location).Format(time.DateTime)}</td>
<td>{agent.AgentInfo.Username}</td>
@ -75,7 +75,7 @@ templ State(state *models.State, location *time.Location) {
</thead>
for _, client := range state.Clients {
<tr>
<td>{client.PublicId}</td>
<td>{client.AgentId}</td>
<td>{strconv.Itoa(client.ClientId)}</td>
<td>{client.StartTime.In(location).Format(time.DateTime)}</td>
<td>{client.SessionType}</td>