Commit 2ddc7cf4 authored by ale's avatar ale

Drop the groups param from the exchange API

There seems to be no good reason to change group membership when
exchanging tokens, let's try just passing the old one over.
parent bef0bea2
Pipeline #1424 passed with stages
in 1 minute and 42 seconds
...@@ -115,13 +115,17 @@ parameters: ...@@ -115,13 +115,17 @@ parameters:
* `cur_nonce`: nonce for *cur_tkt* * `cur_nonce`: nonce for *cur_tkt*
* `new_svc`: destination SSO service * `new_svc`: destination SSO service
* `new_nonce`: nonce for the new SSO ticket * `new_nonce`: nonce for the new SSO ticket
* `new_groups` (optional): a comma-separated list of groups that the
destination service might check membership for
Note that annoyingly *cur_svc* and *cur_nonce* are redundant, as they Note that annoyingly *cur_svc* and *cur_nonce* are redundant, as they
are already contained within *cur_tkt*, but the SSO ticket API won't are already contained within *cur_tkt*, but the SSO ticket API won't
allow us to decode the ticket without verifying it at the same time. allow us to decode the ticket without verifying it at the same time.
The new ticket will not be valid any longer than the original one, or
the configured TTL for the new service, whichever comes first.
Group membership in the original ticket is passed along unchanged to
the new ticket.
# Implementation notes # Implementation notes
......
...@@ -287,9 +287,8 @@ func (h *Server) handleExchange(w http.ResponseWriter, req *http.Request) { ...@@ -287,9 +287,8 @@ func (h *Server) handleExchange(w http.ResponseWriter, req *http.Request) {
curNonce := req.FormValue("cur_nonce") curNonce := req.FormValue("cur_nonce")
newService := req.FormValue("new_svc") newService := req.FormValue("new_svc")
newNonce := req.FormValue("new_nonce") newNonce := req.FormValue("new_nonce")
reqGroups := strings.Split(req.FormValue("new_groups"), ",")
token, err := h.loginService.Exchange(curToken, curService, curNonce, newService, newNonce, reqGroups) token, err := h.loginService.Exchange(curToken, curService, curNonce, newService, newNonce)
switch { switch {
case err == ErrUnauthorized: case err == ErrUnauthorized:
log.Printf("unauthorized exchange request (%s -> %s)", curService, newService) log.Printf("unauthorized exchange request (%s -> %s)", curService, newService)
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"net/url" "net/url"
"regexp" "regexp"
"strings" "strings"
"time"
"git.autistici.org/id/go-sso" "git.autistici.org/id/go-sso"
) )
...@@ -86,7 +87,7 @@ func (s *LoginService) Authorize(username, service, destination, nonce string, g ...@@ -86,7 +87,7 @@ func (s *LoginService) Authorize(username, service, destination, nonce string, g
} }
// Exchange a token for a new one scoped to a different service. // Exchange a token for a new one scoped to a different service.
func (s *LoginService) Exchange(curToken, curService, curNonce, newService, nonce string, requiredGroups []string) (string, error) { func (s *LoginService) Exchange(curToken, curService, curNonce, newService, nonce string) (string, error) {
// Check that the current token is valid for the current service. // Check that the current token is valid for the current service.
curTkt, err := s.validator.Validate(curToken, curNonce, curService, nil) curTkt, err := s.validator.Validate(curToken, curNonce, curService, nil)
if err != nil { if err != nil {
...@@ -97,18 +98,19 @@ func (s *LoginService) Exchange(curToken, curService, curNonce, newService, nonc ...@@ -97,18 +98,19 @@ func (s *LoginService) Exchange(curToken, curService, curNonce, newService, nonc
if err := s.validateServiceExchange(curService, newService); err != nil { if err := s.validateServiceExchange(curService, newService); err != nil {
return "", err return "", err
} }
// Match the original service groups against the new service
// required groups. // The new ticket will not be valid any longer than the
var groups []string // original one, or for a maximum of whatever service-specific
if requiredGroups != nil { // TTL we have configured, whichever comes first.
groups = intersectGroups(curTkt.Groups, requiredGroups) ttlLeft := time.Until(curTkt.Expires)
if groups == nil { if svcTTL := s.config.getServiceTTL(newService); svcTTL < ttlLeft {
return "", ErrUnauthorized ttlLeft = svcTTL
}
} }
// Generate a new signed ticket for the new service. // Generate a new signed ticket for the new service. Groups
tkt := sso.NewTicket(curTkt.User, newService, s.config.Domain, nonce, groups, s.config.getServiceTTL(newService)) // in the original ticket are passed identically to the newly
// generated ticket.
tkt := sso.NewTicket(curTkt.User, newService, s.config.Domain, nonce, curTkt.Groups, ttlLeft)
return s.signer.Sign(tkt) return s.signer.Sign(tkt)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment