Skip to content

Commit b96398a

Browse files
committed
Implement refresh and revoke for lg identifier backend session
With this change the libregraph identifier backend does have an implementation for the refresh session and destroy session calls. Refreshing a session simply loads the user from the backend, providing the current session ID in the request headers similar to the already existing request headers. Destroying a session implements a new endpoint which is modeled after the Microsoft Graph revokeSignInSessions but is only for a single session (hooked at `/api/v1/me/revokeSignInSession`). If a backend implements this endpoint it must do so for a POST request and return an odata boolean value.
1 parent 5ee8000 commit b96398a

File tree

1 file changed

+72
-4
lines changed

1 file changed

+72
-4
lines changed

identifier/backends/libregraph/libregraph.go

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ const (
5454
)
5555

5656
const (
57-
apiPathMe = "/api/v1/me"
58-
apiPathUsers = "/api/v1/users"
57+
apiPathMe = "/api/v1/me"
58+
apiPathUsers = "/api/v1/users"
59+
apiPathRevokeSignInSession = "/api/v1/me/revokeSignInSession"
5960
)
6061

6162
var libreGraphSpportedScopes = []string{
@@ -521,7 +522,7 @@ func (b *LibreGraphIdentifierBackend) GetUser(ctx context.Context, entryID strin
521522
return user, nil
522523
}
523524

524-
// ResolveUserByUsername implements the Beckend interface, providing lookup for
525+
// ResolveUserByUsername implements the Backend interface, providing lookup for
525526
// user by providing the username. Requests are bound to the provided context.
526527
func (b *LibreGraphIdentifierBackend) ResolveUserByUsername(ctx context.Context, username string) (backends.UserFromBackend, error) {
527528
// Libregraph backend accept both user name and ID lookups, so this is
@@ -531,11 +532,72 @@ func (b *LibreGraphIdentifierBackend) ResolveUserByUsername(ctx context.Context,
531532

532533
// RefreshSession implements the Backend interface.
533534
func (b *LibreGraphIdentifierBackend) RefreshSession(ctx context.Context, userID string, sessionRef *string, claims map[string]interface{}) error {
535+
user, err := b.GetUser(ctx, userID, sessionRef, nil)
536+
if err != nil {
537+
return err
538+
}
539+
if user == nil {
540+
return fmt.Errorf("refresh session did not yield a user")
541+
}
534542
return nil
535543
}
536544

537-
// DestroySession implements the Backend interface providing destroy to KC session.
545+
// DestroySession implements the Backend interface providing explicit revoke
546+
// of the backend session.
538547
func (b *LibreGraphIdentifierBackend) DestroySession(ctx context.Context, sessionRef *string) error {
548+
var requestedScopes map[string]bool
549+
record, _ := identifier.FromRecordContext(ctx)
550+
if record != nil {
551+
if record.HelloRequest != nil {
552+
requestedScopes = record.HelloRequest.Scopes
553+
}
554+
}
555+
556+
_, revokeSessionURL := b.getRevokeSigninSessionURL(requestedScopes)
557+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, revokeSessionURL, http.NoBody)
558+
if err != nil {
559+
return fmt.Errorf("libregraph identifier backend destroy session request error: %w", err)
560+
}
561+
562+
if sessionRef != nil {
563+
sessionID := *sessionRef
564+
if !strings.HasPrefix(sessionID, libreGraphIdentifierBackendName+":") {
565+
// Only send the session ID if it is not a ref generated by lico.
566+
req.Header.Set("X-SessionID", sessionID)
567+
}
568+
}
569+
570+
if record == nil {
571+
record, _ = identifier.RecordFromRequestContext(ctx, b.config)
572+
}
573+
if record != nil {
574+
// Inject HTTP headers.
575+
if record.RealIP != "" {
576+
req.Header.Set("X-User-Real-IP", record.RealIP)
577+
}
578+
if record.UserAgent != "" {
579+
req.Header.Set("X-User-Real-User-Agent", record.UserAgent)
580+
}
581+
}
582+
req.Header.Set("User-Agent", utils.DefaultHTTPUserAgent)
583+
584+
response, err := b.client.Do(req)
585+
if err != nil {
586+
return fmt.Errorf("libregraph identifier backend destroy session request failed: %w", err)
587+
}
588+
defer response.Body.Close()
589+
590+
switch response.StatusCode {
591+
case http.StatusOK:
592+
// breaks
593+
case http.StatusNotFound:
594+
return nil
595+
case http.StatusUnauthorized:
596+
return nil
597+
default:
598+
return fmt.Errorf("libregraph identifier backend logon request unexpected response status: %d", response.StatusCode)
599+
}
600+
539601
return nil
540602
}
541603

@@ -590,3 +652,9 @@ func (b *LibreGraphIdentifierBackend) getUserURL(requestedScopes map[string]bool
590652

591653
return scope, baseURL + apiPathUsers
592654
}
655+
656+
func (b *LibreGraphIdentifierBackend) getRevokeSigninSessionURL(requestedScopes map[string]bool) (string, string) {
657+
scope, baseURL := b.getBaseURL(requestedScopes)
658+
659+
return scope, baseURL + apiPathRevokeSignInSession
660+
}

0 commit comments

Comments
 (0)