Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/api/identity.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,5 @@ This resource provides information about user authentication sessions, including
| `ip` | string | The IP address from which the session was created (optional). |
| `fingerprintID` | string | A fingerprint identifier for the session (optional). |
| `createdAt` | metav1.Time | The timestamp when the session was created. |
| `expiresAt` | *metav1.Time | The timestamp when the session expires (optional). |
| `lastUpdatedAt` | *metav1.Time | Last time the authentication provider updated this session (optional). |
| `userAgent` | string | Client User-Agent string for this session, if the provider supplies it (optional). |
32 changes: 26 additions & 6 deletions internal/apiserver/identity/sessions/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sessions

import (
"context"
"strings"
"time"

identityv1alpha1 "go.miloapis.com/milo/pkg/apis/identity/v1alpha1"
Expand Down Expand Up @@ -97,14 +98,22 @@ func (r *REST) Delete(ctx context.Context, name string, _ rest.ValidateObjectFun

func (r *REST) Destroy() {}

// Satisfy rest.TableConvertor with a no-op conversion (returning nil uses default table printer)
func truncateForTable(s string, max int) string {
if max <= 0 || len(s) <= max {
return s
}
return strings.TrimSpace(s[:max]) + "…"
}

func (r *REST) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
table := &metav1.Table{
ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string"},
{Name: "Provider", Type: "string"},
{Name: "UserUID", Type: "string"},
{Name: "Age", Type: "date"},
{Name: "Name", Type: "string", Format: "name", Description: "Metadata name of the session.", Priority: 0},
{Name: "Provider", Type: "string", Description: "Authentication provider.", Priority: 0},
{Name: "Age", Type: "date", Description: "Creation timestamp.", Priority: 0},
{Name: "User agent", Type: "string", Description: "Client User-Agent (truncated in table view).", Priority: 1},
{Name: "Last updated", Type: "string", Description: "Provider last update time (RFC3339), if known.", Priority: 1},
{Name: "UserUID", Type: "string", Description: "Owning user UID.", Priority: 1},
},
}

Expand All @@ -115,8 +124,19 @@ func (r *REST) ConvertToTable(ctx context.Context, object runtime.Object, tableO
// metav1.Table wants a date in the cell; pass the timestamp
age = s.CreationTimestamp
}
lastUpdated := ""
if s.Status.LastUpdatedAt != nil {
lastUpdated = s.Status.LastUpdatedAt.Time.Format(time.RFC3339)
}
table.Rows = append(table.Rows, metav1.TableRow{
Cells: []interface{}{s.Name, s.Status.Provider, s.Status.UserUID, age.Time.Format(time.RFC3339)},
Cells: []interface{}{
s.Name,
s.Status.Provider,
age.Time.Format(time.RFC3339),
truncateForTable(s.Status.UserAgent, 80),
lastUpdated,
s.Status.UserUID,
},
Object: runtime.RawExtension{Object: s},
})
}
Expand Down
28 changes: 22 additions & 6 deletions pkg/apis/identity/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,29 @@ type Session struct {
Status SessionStatus `json:"status,omitempty"`
}

// SessionStatus contains session metadata exposed for display and management.
// All fields except those required for identity are optional and populated by the authentication provider.
type SessionStatus struct {
UserUID string `json:"userUID"`
Provider string `json:"provider"`
IP string `json:"ip,omitempty"`
FingerprintID string `json:"fingerprintID,omitempty"`
CreatedAt metav1.Time `json:"createdAt"`
ExpiresAt *metav1.Time `json:"expiresAt,omitempty"`
// UserUID is the unique identifier of the user who owns this session.
UserUID string `json:"userUID"`

// Provider is the authentication provider for this session (e.g. "zitadel").
Provider string `json:"provider"`

// IP is the client IP address associated with the session, if known.
IP string `json:"ip,omitempty"`

// FingerprintID is an optional device or client fingerprint from the provider.
FingerprintID string `json:"fingerprintID,omitempty"`

// CreatedAt is when the session was created.
CreatedAt metav1.Time `json:"createdAt"`

// LastUpdatedAt is the last time the provider updated this session (e.g. Zitadel change_date).
LastUpdatedAt *metav1.Time `json:"lastUpdatedAt,omitempty"`

// UserAgent is the client User-Agent string for this session, if the provider supplies it.
UserAgent string `json:"userAgent,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
4 changes: 2 additions & 2 deletions pkg/apis/identity/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 29 additions & 15 deletions pkg/apis/identity/v1alpha1/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading