1package tokens
2
3import (
4	"time"
5
6	"github.com/gophercloud/gophercloud"
7)
8
9// Endpoint represents a single API endpoint offered by a service.
10// It matches either a public, internal or admin URL.
11// If supported, it contains a region specifier, again if provided.
12// The significance of the Region field will depend upon your provider.
13type Endpoint struct {
14	ID        string `json:"id"`
15	Region    string `json:"region"`
16	RegionID  string `json:"region_id"`
17	Interface string `json:"interface"`
18	URL       string `json:"url"`
19}
20
21// CatalogEntry provides a type-safe interface to an Identity API V3 service
22// catalog listing. Each class of service, such as cloud DNS or block storage
23// services, could have multiple CatalogEntry representing it (one by interface
24// type, e.g public, admin or internal).
25//
26// Note: when looking for the desired service, try, whenever possible, to key
27// off the type field. Otherwise, you'll tie the representation of the service
28// to a specific provider.
29type CatalogEntry struct {
30	// Service ID
31	ID string `json:"id"`
32
33	// Name will contain the provider-specified name for the service.
34	Name string `json:"name"`
35
36	// Type will contain a type string if OpenStack defines a type for the
37	// service. Otherwise, for provider-specific services, the provider may
38	// assign their own type strings.
39	Type string `json:"type"`
40
41	// Endpoints will let the caller iterate over all the different endpoints that
42	// may exist for the service.
43	Endpoints []Endpoint `json:"endpoints"`
44}
45
46// ServiceCatalog provides a view into the service catalog from a previous,
47// successful authentication.
48type ServiceCatalog struct {
49	Entries []CatalogEntry `json:"catalog"`
50}
51
52// Domain provides information about the domain to which this token grants
53// access.
54type Domain struct {
55	ID   string `json:"id"`
56	Name string `json:"name"`
57}
58
59// User represents a user resource that exists in the Identity Service.
60type User struct {
61	Domain Domain `json:"domain"`
62	ID     string `json:"id"`
63	Name   string `json:"name"`
64}
65
66// Role provides information about roles to which User is authorized.
67type Role struct {
68	ID   string `json:"id"`
69	Name string `json:"name"`
70}
71
72// Project provides information about project to which User is authorized.
73type Project struct {
74	Domain Domain `json:"domain"`
75	ID     string `json:"id"`
76	Name   string `json:"name"`
77}
78
79// commonResult is the response from a request. A commonResult has various
80// methods which can be used to extract different details about the result.
81type commonResult struct {
82	gophercloud.Result
83}
84
85// Extract is a shortcut for ExtractToken.
86// This function is deprecated and still present for backward compatibility.
87func (r commonResult) Extract() (*Token, error) {
88	return r.ExtractToken()
89}
90
91// ExtractToken interprets a commonResult as a Token.
92func (r commonResult) ExtractToken() (*Token, error) {
93	var s Token
94	err := r.ExtractInto(&s)
95	if err != nil {
96		return nil, err
97	}
98
99	// Parse the token itself from the stored headers.
100	s.ID = r.Header.Get("X-Subject-Token")
101
102	return &s, err
103}
104
105// ExtractTokenID implements the gophercloud.AuthResult interface. The returned
106// string is the same as the ID field of the Token struct returned from
107// ExtractToken().
108func (r CreateResult) ExtractTokenID() (string, error) {
109	return r.Header.Get("X-Subject-Token"), r.Err
110}
111
112// ExtractServiceCatalog returns the ServiceCatalog that was generated along
113// with the user's Token.
114func (r commonResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
115	var s ServiceCatalog
116	err := r.ExtractInto(&s)
117	return &s, err
118}
119
120// ExtractUser returns the User that is the owner of the Token.
121func (r commonResult) ExtractUser() (*User, error) {
122	var s struct {
123		User *User `json:"user"`
124	}
125	err := r.ExtractInto(&s)
126	return s.User, err
127}
128
129// ExtractRoles returns Roles to which User is authorized.
130func (r commonResult) ExtractRoles() ([]Role, error) {
131	var s struct {
132		Roles []Role `json:"roles"`
133	}
134	err := r.ExtractInto(&s)
135	return s.Roles, err
136}
137
138// ExtractProject returns Project to which User is authorized.
139func (r commonResult) ExtractProject() (*Project, error) {
140	var s struct {
141		Project *Project `json:"project"`
142	}
143	err := r.ExtractInto(&s)
144	return s.Project, err
145}
146
147// CreateResult is the response from a Create request. Use ExtractToken()
148// to interpret it as a Token, or ExtractServiceCatalog() to interpret it
149// as a service catalog.
150type CreateResult struct {
151	commonResult
152}
153
154// GetResult is the response from a Get request. Use ExtractToken()
155// to interpret it as a Token, or ExtractServiceCatalog() to interpret it
156// as a service catalog.
157type GetResult struct {
158	commonResult
159}
160
161// RevokeResult is response from a Revoke request.
162type RevokeResult struct {
163	commonResult
164}
165
166// Token is a string that grants a user access to a controlled set of services
167// in an OpenStack provider. Each Token is valid for a set length of time.
168type Token struct {
169	// ID is the issued token.
170	ID string `json:"id"`
171
172	// ExpiresAt is the timestamp at which this token will no longer be accepted.
173	ExpiresAt time.Time `json:"expires_at"`
174}
175
176func (r commonResult) ExtractInto(v interface{}) error {
177	return r.ExtractIntoStructPtr(v, "token")
178}
179