Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.4 KiB
83 lines
2.4 KiB
package openid |
|
|
|
import ( |
|
"encoding/xml" |
|
"errors" |
|
"strings" |
|
) |
|
|
|
// TODO: As per 11.2 in openid 2 specs, a service may have multiple |
|
// URIs. We don't care for discovery really, but we do care for |
|
// verification though. |
|
type XrdsIdentifier struct { |
|
Type []string `xml:"Type"` |
|
URI string `xml:"URI"` |
|
LocalID string `xml:"LocalID"` |
|
Priority int `xml:"priority,attr"` |
|
} |
|
|
|
type Xrd struct { |
|
Service []*XrdsIdentifier `xml:"Service"` |
|
} |
|
|
|
type XrdsDocument struct { |
|
XMLName xml.Name `xml:"XRDS"` |
|
Xrd *Xrd `xml:"XRD"` |
|
} |
|
|
|
func parseXrds(input []byte) (opEndpoint, opLocalID string, err error) { |
|
xrdsDoc := &XrdsDocument{} |
|
err = xml.Unmarshal(input, xrdsDoc) |
|
if err != nil { |
|
return |
|
} |
|
|
|
if xrdsDoc.Xrd == nil { |
|
return "", "", errors.New("XRDS document missing XRD tag") |
|
} |
|
|
|
// 7.3.2.2. Extracting Authentication Data |
|
// Once the Relying Party has obtained an XRDS document, it |
|
// MUST first search the document (following the rules |
|
// described in [XRI_Resolution_2.0]) for an OP Identifier |
|
// Element. If none is found, the RP will search for a Claimed |
|
// Identifier Element. |
|
for _, service := range xrdsDoc.Xrd.Service { |
|
// 7.3.2.1.1. OP Identifier Element |
|
// An OP Identifier Element is an <xrd:Service> element with the |
|
// following information: |
|
// An <xrd:Type> tag whose text content is |
|
// "http://specs.openid.net/auth/2.0/server". |
|
// An <xrd:URI> tag whose text content is the OP Endpoint URL |
|
if service.hasType("http://specs.openid.net/auth/2.0/server") { |
|
opEndpoint = strings.TrimSpace(service.URI) |
|
return |
|
} |
|
} |
|
for _, service := range xrdsDoc.Xrd.Service { |
|
// 7.3.2.1.2. Claimed Identifier Element |
|
// A Claimed Identifier Element is an <xrd:Service> element |
|
// with the following information: |
|
// An <xrd:Type> tag whose text content is |
|
// "http://specs.openid.net/auth/2.0/signon". |
|
// An <xrd:URI> tag whose text content is the OP Endpoint |
|
// URL. |
|
// An <xrd:LocalID> tag (optional) whose text content is the |
|
// OP-Local Identifier. |
|
if service.hasType("http://specs.openid.net/auth/2.0/signon") { |
|
opEndpoint = strings.TrimSpace(service.URI) |
|
opLocalID = strings.TrimSpace(service.LocalID) |
|
return |
|
} |
|
} |
|
return "", "", errors.New("Could not find a compatible service") |
|
} |
|
|
|
func (xrdsi *XrdsIdentifier) hasType(tpe string) bool { |
|
for _, t := range xrdsi.Type { |
|
if t == tpe { |
|
return true |
|
} |
|
} |
|
return false |
|
}
|
|
|