1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
|
// Copyright 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE.client file for details.
package params
import (
"time"
"unicode/utf8"
"github.com/go-macaroon-bakery/macaroon-bakery/v3/bakery"
"gopkg.in/errgo.v1"
"gopkg.in/httprequest.v1"
"gopkg.in/macaroon.v2"
)
// Username represents the name of a user.
type Username string
// UnmarshalText unmarshals a Username checking it is valid. It
// implements "encoding".TextUnmarshaler.
func (u *Username) UnmarshalText(b []byte) error {
if utf8.RuneCount(b) > 256 {
return errgo.New("username longer than 256 characters")
}
*u = Username(string(b))
return nil
}
// AgentLogin contains the claimed identity the agent is attempting to
// use to log in.
type AgentLogin struct {
Username Username `json:"username"`
PublicKey *bakery.PublicKey `json:"public_key"`
}
// AgentLoginResponse contains the response to an agent login attempt.
type AgentLoginResponse struct {
AgentLogin bool `json:"agent_login"`
}
// PublicKeyRequest documents the /publickey endpoint. As
// it contains no request information there is no need to ever create
// one.
type PublicKeyRequest struct {
httprequest.Route `httprequest:"GET /publickey"`
}
// PublicKeyResponse is the response to a PublicKeyRequest.
type PublicKeyResponse struct {
PublicKey *bakery.PublicKey
}
// LoginMethods holds the response from the /login endpoint
// when called with "Accept: application/json". This enumerates
// the available methods for the client to log in.
type LoginMethods struct {
// Agent is the endpoint to connect to, if the client wishes to
// authenticate as an agent.
Agent string `json:"agent,omitempty"`
// Interactive is the endpoint to connect to, if the user can
// interact with the login process.
Interactive string `json:"interactive,omitempty"`
// UbuntuSSOOAuth is the endpoint to send a request, signed with
// UbuntuSSO OAuth credentials, to if the client wishes to use
// oauth to log in to Identity Manager. Ubuntu SSO uses oauth 1.0.
UbuntuSSOOAuth string `json:"usso_oauth,omitempty"`
// UbuntuSSODischarge allows login to be performed by discharging
// a macaroon with a third-party caveat addressed to Ubuntu SSO.
UbuntuSSODischarge string `json:"usso_discharge,omitempty"`
// Form is the endpoint to GET a schema for a login form which
// can be presented to the user in an interactive manner. The
// schema will be returned as an environschema.Fields object. The
// completed form should be POSTed back to the same endpoint.
Form string `json:"form,omitempty"`
}
// QueryUsersRequest is a request to query the users in the system.
type QueryUsersRequest struct {
httprequest.Route `httprequest:"GET /v1/u"`
// ExternalID, if present, matches all identities with the given
// external ID (there should be a maximum of 1).
ExternalID string `httprequest:"external_id,form"`
// EMail, if present, matches all identities with the given email
// address.
Email string `httprequest:"email,form"`
// LastLoginSince, if present, must contain a time marshaled as
// if using Time.MarshalText. It matches all identies that have a
// last login time after the given time.
LastLoginSince string `httprequest:"last-login-since,form"`
// LastDischargeSince, if present, must contain a time marshaled as
// if using Time.MarshalText. It matches all identies that have a
// last discharge time after the given time.
LastDischargeSince string `httprequest:"last-discharge-since,form"`
// Owner, if present, matches all agent identities with the given
// owner.
Owner string `httprequest:"owner,form"`
}
// UserRequest is a request for the user details of the named user.
type UserRequest struct {
httprequest.Route `httprequest:"GET /v1/u/:username"`
Username Username `httprequest:"username,path"`
}
// User represents a user in the system.
type User struct {
Username Username `json:"username,omitempty"`
ExternalID string `json:"external_id"`
FullName string `json:"fullname"`
Email string `json:"email"`
GravatarID string `json:"gravatar_id"`
IDPGroups []string `json:"idpgroups"`
Owner Username `json:"owner,omitempty"`
PublicKeys []*bakery.PublicKey `json:"public_keys"`
SSHKeys []string `json:"ssh_keys"`
LastLogin *time.Time `json:"last_login,omitempty"`
LastDischarge *time.Time `json:"last_discharge,omitempty"`
}
// SetUserRequest is a request to set the details of a user.
// This endpoint is no longer functional.
type SetUserRequest struct {
httprequest.Route `httprequest:"PUT /v1/u/:username"`
Username Username `httprequest:"username,path"`
User `httprequest:",body"`
}
// CreateAgentRequest is a request to add an agent.
type CreateAgentRequest struct {
httprequest.Route `httprequest:"POST /v1/u"`
CreateAgentBody `httprequest:",body"`
}
// CreateAgentBody holds the body of a CreateAgentRequest.
// There must be at least one public key specified.
type CreateAgentBody struct {
FullName string `json:"fullname"`
Groups []string `json:"idpgroups"`
PublicKeys []*bakery.PublicKey `json:"public_keys"`
// A parent agent is one that can create its own agents. A parent
// agent does not have an owner and so remains a member of the
// groups it has been allocated irrespective of whether the
// creating user remains a member. Only users in the write-user
// ACL can create a parent agent.
Parent bool `json:"parent,omitempty"`
}
// CreateAgentResponse holds the response from a
// CreateAgentRequest.
type CreateAgentResponse struct {
Username Username
}
// UserGroupsRequest is a request for the list of groups associated
// with the specified user.
type UserGroupsRequest struct {
httprequest.Route `httprequest:"GET /v1/u/:username/groups"`
Username Username `httprequest:"username,path"`
}
// SetUserGroupsRequest is a request to set the list of groups associated
// with the specified user.
type SetUserGroupsRequest struct {
httprequest.Route `httprequest:"PUT /v1/u/:username/groups"`
Username Username `httprequest:"username,path"`
Groups Groups `httprequest:",body"`
}
// Groups contains a list of group names.
type Groups struct {
Groups []string `json:"groups"`
}
// ModifyUserGroupsRequest is a request to update the list of groups associated
// with the specified user.
type ModifyUserGroupsRequest struct {
httprequest.Route `httprequest:"POST /v1/u/:username/groups"`
Username Username `httprequest:"username,path"`
Groups ModifyGroups `httprequest:",body"`
}
// ModifyGroups contains a set of group list modifications.
type ModifyGroups struct {
Add []string `json:"add"`
Remove []string `json:"remove"`
}
// UserIDPGroupsRequest defines the deprecated path for
// UserGroupsRequest. It should no longer be used.
type UserIDPGroupsRequest struct {
httprequest.Route `httprequest:"GET /v1/u/:username/idpgroups"`
UserGroupsRequest
}
// UserTokenRequest is a request for a new token to represent the user.
type UserTokenRequest struct {
httprequest.Route `httprequest:"GET /v1/u/:username/macaroon"`
Username Username `httprequest:"username,path"`
}
// VerifyTokenRequest is a request to verify that the provided
// macaroon.Slice is valid and represents a user from identity.
type VerifyTokenRequest struct {
httprequest.Route `httprequest:"POST /v1/verify"`
Macaroons macaroon.Slice `httprequest:",body"`
}
// SSHKeysRequest is a request for the list of ssh keys associated
// with the specified user.
type SSHKeysRequest struct {
httprequest.Route `httprequest:"GET /v1/u/:username/ssh-keys"`
Username Username `httprequest:"username,path"`
}
// UserSSHKeysResponse holds a response to the GET /v1/u/:username/ssh-keys
// containing list of ssh keys associated with the user.
type SSHKeysResponse struct {
SSHKeys []string `json:"ssh_keys"`
}
// PutSSHKeysRequest is a request to set ssh keys to the list of ssh keys
// associated with the user.
type PutSSHKeysRequest struct {
httprequest.Route `httprequest:"PUT /v1/u/:username/ssh-keys"`
Username Username `httprequest:"username,path"`
Body PutSSHKeysBody `httprequest:",body"`
}
// PutSSHKeysBody holds the body of a PutSSHKeysRequest.
type PutSSHKeysBody struct {
SSHKeys []string `json:"ssh-keys"`
Add bool `json:"add,omitempty"`
}
// DeleteSSHKeysRequest is a request to remove ssh keys from the list of ssh keys
// associated with the user.
type DeleteSSHKeysRequest struct {
httprequest.Route `httprequest:"DELETE /v1/u/:username/ssh-keys"`
Username Username `httprequest:"username,path"`
Body DeleteSSHKeysBody `httprequest:",body"`
}
// DeleteSSHKeysBody holds the body of a DeleteSSHKeysRequest.
type DeleteSSHKeysBody struct {
SSHKeys []string `json:"ssh-keys"`
}
// UserExtraInfoRequest is a request for the arbitrary extra information
// stored about the user.
type UserExtraInfoRequest struct {
httprequest.Route `httprequest:"GET /v1/u/:username/extra-info"`
Username Username `httprequest:"username,path"`
}
// SetUserExtraInfoRequest is a request to updated the arbitrary extra
// information stored about the user.
type SetUserExtraInfoRequest struct {
httprequest.Route `httprequest:"PUT /v1/u/:username/extra-info"`
Username Username `httprequest:"username,path"`
ExtraInfo map[string]interface{} `httprequest:",body"`
}
// UserExtraInfoItemRequest is a request for a single element of the
// arbitrary extra information stored about the user.
type UserExtraInfoItemRequest struct {
httprequest.Route `httprequest:"GET /v1/u/:username/extra-info/:item"`
Username Username `httprequest:"username,path"`
Item string `httprequest:"item,path"`
}
// SetUserExtraInfoItemRequest is a request to update a single element of
// the arbitrary extra information stored about the user.
type SetUserExtraInfoItemRequest struct {
httprequest.Route `httprequest:"PUT /v1/u/:username/extra-info/:item"`
Username Username `httprequest:"username,path"`
Item string `httprequest:"item,path"`
Data interface{} `httprequest:",body"`
}
// WhoAmIRequest holds parameters for requesting the current user name.
type WhoAmIRequest struct {
httprequest.Route `httprequest:"GET /v1/whoami"`
}
// WhoAmIResponse holds information on the currently
// authenticated user.
type WhoAmIResponse struct {
User string `json:"user"`
}
// DischargeTokenForUserRequest is the request to get a discharge token
// for a specific user.
type DischargeTokenForUserRequest struct {
httprequest.Route `httprequest:"GET /v1/discharge-token-for-user"`
Username Username `httprequest:"username,form"`
}
// DischargeTokenForUserResponse holds the discharge token, in the form
// of a macaroon, for the requested user.
type DischargeTokenForUserResponse struct {
DischargeToken *bakery.Macaroon
}
// IDPChoice lists available IDPs for authentication.
type IDPChoice struct {
IDPs []IDPChoiceDetails `json:"idps"`
}
// IDPChoiceDetails provides details about a IDP choice for authentication.
type IDPChoiceDetails struct {
Domain string `json:"domain"`
Description string `json:"description"`
Icon string `json:"icon"`
Name string `json:"name"`
URL string `json:"url"`
}
// GetUserWithIDRequest is a request for the user details of the user with the
// given ID.
type GetUserWithIDRequest struct {
httprequest.Route `httprequest:"GET /v1/uid"`
UserID string `httprequest:"id,form"`
}
// GetUserGroupsWithIDRequest is a request for the groups of the user with the
// given ID.
type GetUserGroupsWithIDRequest struct {
httprequest.Route `httprequest:"GET /v1/uid/groups"`
UserID string `httprequest:"id,form"`
}
// GroupsResponse is the response to a GetUserGroupsWithIDRequest.
type GroupsResponse struct {
Groups []string `json:"groups"`
}
// ClearUserMFACredentialsRequest is a request to delete
// all MFA credentials for a user.
type ClearUserMFACredentialsRequest struct {
httprequest.Route `httprequest:"DELETE /v1/mfa/:username"`
Username Username `httprequest:"username,path"`
}
var (
// BrandName holds the brand name of the entity running Candid.
BrandName string
// BrandLogoLocation holds the logo location of the entity running
// Candid.
BrandLogoLocation string
)
// TemplateBrandParameters holds branding information for the entity
// running Candid.
type TemplateBrandParameters struct {
// BrandName holds the brand name of the entity running Candid.
BrandName string
// LogoLocation holds the logo location of the entity running
// Candid.
BrandLogoLocation string
}
// BrandParameters returns branding information for the entity
// running Candid.
func BrandParameters() TemplateBrandParameters {
return TemplateBrandParameters{
BrandName: BrandName,
BrandLogoLocation: BrandLogoLocation,
}
}
|