admin

package
v1.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2022 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CSRFCookie          = "csrf_token"
	CSRFReferenceCookie = "csrf_reference_token"
	CSRFHeader          = "X-CSRF-TOKEN"
)

Parameters and names for double-cookie submit CSRF protection

View Source
const (
	UserClaims = "user_claims"
)

Variables

View Source
var (
	ErrInvalidResendAction = errors.New("invalid resend action")
	ErrIDRequred           = errors.New("request requires a valid ID to determine endpoint")
	ErrCSRFVerification    = errors.New("csrf verification failed for request")
)

Functions

func Authorization

func Authorization(tm *tokens.TokenManager) gin.HandlerFunc

Authorization middleware ensures that the request has a valid Bearer JWT in the Authorization header of the request otherwise it returns a 401 unauthorized error.

func DoubleCookie

func DoubleCookie() gin.HandlerFunc

DoubleCookie is Cross Site Request Forgery (CSRF/XSRF) protection middleware that checks the presence of an X-CSRF-TOKEN header containing a cryptographically random token that matches a token contained in the CSRF-TOKEN cookie in the request. Because of the same-origin policy, an attacker cannot access the cookies or scripts of the safe site therefore it will not be able to guess what token to put in the request, thereby protecting from CSRF attacks. Note that Double Cookie CSRF protection requires TLS to prevent MITM attacks.

func GenerateCSRFToken

func GenerateCSRFToken() (_ string, err error)

func GetAccessToken

func GetAccessToken(c *gin.Context) (tks string, err error)

GetAccessToken retrieves the bearer token from the authorization header and parses it to return only the access token. If the header is missing or the token is not available an error is returned.

func NotAllowed

func NotAllowed(c *gin.Context)

NotAllowed returns a JSON 405 response for the API.

func NotFound

func NotFound(c *gin.Context)

NotFound returns a JSON 404 response for the API.

func SetDoubleCookieTokens

func SetDoubleCookieTokens(c *gin.Context, domain string, exp time.Time) error

SetDoubleCookieTokens is a helper function to set cookies on a gin-request. The exp parameter is the Unix timestamp the cookie should be expired, which in most cases is extracted from the exp field of the refresh token claims.

Types

type APIv2

type APIv2 struct {
	// contains filtered or unexported fields
}

APIv2 implements the Service interface.

func (*APIv2) Authenticate

func (s *APIv2) Authenticate(ctx context.Context, in *AuthRequest) (out *AuthReply, err error)

Authenticate the the client to the Server using the supplied credentials. This method calls ProtectAuthenticate before performing the authentication.

func (*APIv2) Autocomplete

func (s *APIv2) Autocomplete(ctx context.Context) (out *AutocompleteReply, err error)

func (*APIv2) CreateReviewNote

func (s *APIv2) CreateReviewNote(ctx context.Context, in *ModifyReviewNoteRequest) (out *ReviewNote, err error)

func (*APIv2) DeleteContact added in v1.3.1

func (s *APIv2) DeleteContact(ctx context.Context, vaspID string, kind string) (out *Reply, err error)

func (*APIv2) DeleteReviewNote

func (s *APIv2) DeleteReviewNote(ctx context.Context, vaspID string, noteID string) (out *Reply, err error)

func (*APIv2) DeleteVASP added in v1.3.1

func (s *APIv2) DeleteVASP(ctx context.Context, id string) (out *Reply, err error)

func (*APIv2) Do

func (s *APIv2) Do(req *http.Request, data interface{}, checkStatus bool) (rep *http.Response, err error)

Do executes an http request against the server, performs error checking, and deserializes the response data into the specified struct if requested.

func (*APIv2) ListCertificates added in v1.5.0

func (s *APIv2) ListCertificates(ctx context.Context, id string) (out *ListCertificatesReply, err error)

func (*APIv2) ListCountries added in v1.6.1

func (s *APIv2) ListCountries(ctx context.Context) (out []*CountryRecord, err error)

func (*APIv2) ListReviewNotes

func (s *APIv2) ListReviewNotes(ctx context.Context, id string) (out *ListReviewNotesReply, err error)

func (*APIv2) ListVASPs

func (s *APIv2) ListVASPs(ctx context.Context, in *ListVASPsParams) (out *ListVASPsReply, err error)

func (*APIv2) Login

func (s *APIv2) Login(ctx context.Context) (err error)

Login prepares the client for authorized requests. It uses the internal credentials to set the access and refresh tokens but does not return an error if the internal credentials is nil. Login can be called manually by the user, or it is called automatically on requests that must be authenticated.

func (*APIv2) Logout

func (s *APIv2) Logout(ctx context.Context) (err error)

Logout removes the cached access and refresh tokens requiring the API to login again

func (*APIv2) NewRequest

func (s *APIv2) NewRequest(ctx context.Context, method, path string, data interface{}, params *url.Values) (req *http.Request, err error)

NewRequest creates an http.Request with the specified context and method, resolving the path to the root endpoint of the API (e.g. /v2) and serializes the data to JSON. This method also sets the default headers of all GDS Admin API v2 client requests.

func (*APIv2) ProtectAuthenticate

func (s *APIv2) ProtectAuthenticate(ctx context.Context) (err error)

ProtectAuthenticate sets cookies for CSRF protection (not necessary in the API but good for testing)

func (*APIv2) Reauthenticate

func (s *APIv2) Reauthenticate(ctx context.Context, in *AuthRequest) (out *AuthReply, err error)

Reauthenticate the the client to the Server using the supplied credentials. This method calls ProtectAuthenticate before performing the reauthentication.

func (*APIv2) Refresh

func (s *APIv2) Refresh(ctx context.Context) (err error)

Refresh prepares the client to continue making authorized requests. It uses the internal credentials to update the access and refresh tokens but does not return an error if the internal credentials is nil. Refresh can be called manually by the user, or it is called automatically on requests that must be authenticated.

func (*APIv2) ReplaceContact added in v1.3.1

func (s *APIv2) ReplaceContact(ctx context.Context, in *ReplaceContactRequest) (out *Reply, err error)

func (*APIv2) Resend

func (s *APIv2) Resend(ctx context.Context, in *ResendRequest) (out *ResendReply, err error)

func (*APIv2) RetrieveVASP

func (s *APIv2) RetrieveVASP(ctx context.Context, id string) (out *RetrieveVASPReply, err error)

func (*APIv2) Review

func (s *APIv2) Review(ctx context.Context, in *ReviewRequest) (out *ReviewReply, err error)

func (*APIv2) ReviewTimeline

func (s *APIv2) ReviewTimeline(ctx context.Context, in *ReviewTimelineParams) (out *ReviewTimelineReply, err error)

func (*APIv2) ReviewToken added in v1.3.1

func (s *APIv2) ReviewToken(ctx context.Context, vaspID string) (out *ReviewTokenReply, err error)

func (*APIv2) Status

func (s *APIv2) Status(ctx context.Context) (out *StatusReply, err error)

func (*APIv2) Summary

func (s *APIv2) Summary(ctx context.Context) (out *SummaryReply, err error)

func (*APIv2) Tokens

func (s *APIv2) Tokens() (accessToken, refreshToken string)

Tokens returns the access and refresh tokens. It is not part of the DirectoryAdministrationClient interface, so callers will have to type check *APIv2 to get access to this method. It's intent is to provide the cached tokens to the internal credentials on refresh or for auditing purposes and use in testing.

func (*APIv2) UpdateReviewNote

func (s *APIv2) UpdateReviewNote(ctx context.Context, in *ModifyReviewNoteRequest) (out *ReviewNote, err error)

func (*APIv2) UpdateVASP

func (s *APIv2) UpdateVASP(ctx context.Context, in *UpdateVASPRequest) (out *UpdateVASPReply, err error)

type AuthReply

type AuthReply struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
}

AuthReply returns access and refresh tokens. The access token should be used as a a Bearer token in the Authorization header for all authenticated requests including Reauthentication. The refresh token is used in the Reauthenticate method to retrieve new access tokens without requiring a new login.

type AuthRequest

type AuthRequest struct {
	Credential string `json:"credential"`
}

AuthRequest is used by both the Authenticate and Reauthenticate API calls. In Authenticate, the credential should be the OAuth2 JWT token supplied by the Identity Service Provider. In Reauthenticate the credential should be the refresh token returned by the Authenticate request.

type AutocompleteReply

type AutocompleteReply struct {
	Names map[string]string `json:"names"`
}

AutocompleteReply contains a mapping of name to VASP UUID for the search bar.

type Certificate added in v1.5.0

type Certificate struct {
	SerialNumber string                 `json:"serial_number"`
	IssuedAt     string                 `json:"issued_at"`
	ExpiresAt    string                 `json:"expires_at"`
	Status       string                 `json:"status"`
	Details      map[string]interface{} `json:"details"`
}

Certififcate contains some high level information about a certificate issued to a VASP as well as the actual trisa.gds.models.v1beta1.Certificate marshaled by protojson.

type ClientOption added in v1.5.0

type ClientOption func(c *APIv2) error

ClientOption allows us to configure the APIv2 client when it is created.

func WithClient added in v1.5.0

func WithClient(client *http.Client) ClientOption

type CountryRecord added in v1.6.1

type CountryRecord struct {
	ISOCode       string `json:"iso_code"`
	Registrations int    `json:"registrations"`
}

CountryRecord contains aggregate information relating to VASP registrations in a single country.

type Credentials

type Credentials interface {
	// Login is called when the client does not have access or refresh tokens or when
	// both the access and refresh tokens are expired. The only API methods available to
	// the Credentials object are the endpoints that are unauthenticated.
	Login(api DirectoryAdministrationClient) (accessToken, refreshToken string, err error)

	// Refresh is called when the client has a valid refresh token but the access token is expired.
	Refresh(api DirectoryAdministrationClient) (accessToken, refreshToken string, err error)

	// Logout is not called explicitly by the client but is available on the client to
	// be called manually by the user. The intent is for any cached tokens to be
	// destroyed, requiring authentication before another request can be made.
	Logout(api DirectoryAdministrationClient) (err error)
}

Credentials is a generic interface that can be used to provide an access token to the admin API client for authentication. The credentials can be stored on disk, generated from private keys, or fetched via an Oauth2 workflow. The methods of the interface are passed a client so that the Credentials can use the API to make requests to the server, particularly the authenticate and reauthenticate endpoints.

type DirectoryAdministrationClient

type DirectoryAdministrationClient interface {
	Login(ctx context.Context) (err error)
	Refresh(ctx context.Context) (err error)
	Logout(ctx context.Context) (err error)
	Status(ctx context.Context) (out *StatusReply, err error)
	Authenticate(ctx context.Context, in *AuthRequest) (out *AuthReply, err error)
	Reauthenticate(ctx context.Context, in *AuthRequest) (out *AuthReply, err error)
	Summary(ctx context.Context) (out *SummaryReply, err error)
	Autocomplete(ctx context.Context) (out *AutocompleteReply, err error)
	ReviewTimeline(ctx context.Context, params *ReviewTimelineParams) (out *ReviewTimelineReply, err error)
	ListCountries(ctx context.Context) (out []*CountryRecord, err error)
	ListVASPs(ctx context.Context, params *ListVASPsParams) (out *ListVASPsReply, err error)
	RetrieveVASP(ctx context.Context, id string) (out *RetrieveVASPReply, err error)
	UpdateVASP(ctx context.Context, in *UpdateVASPRequest) (out *UpdateVASPReply, err error)
	DeleteVASP(ctx context.Context, id string) (out *Reply, err error)
	ListCertificates(ctx context.Context, vaspID string) (out *ListCertificatesReply, err error)
	ReplaceContact(ctx context.Context, in *ReplaceContactRequest) (out *Reply, err error)
	DeleteContact(ctx context.Context, vaspID string, kind string) (out *Reply, err error)
	CreateReviewNote(ctx context.Context, in *ModifyReviewNoteRequest) (out *ReviewNote, err error)
	ListReviewNotes(ctx context.Context, id string) (out *ListReviewNotesReply, err error)
	UpdateReviewNote(ctx context.Context, in *ModifyReviewNoteRequest) (out *ReviewNote, err error)
	DeleteReviewNote(ctx context.Context, vaspID string, noteID string) (out *Reply, err error)
	ReviewToken(ctx context.Context, vaspID string) (out *ReviewTokenReply, err error)
	Review(ctx context.Context, in *ReviewRequest) (out *ReviewReply, err error)
	Resend(ctx context.Context, in *ResendRequest) (out *ResendReply, err error)
}

DirectoryAdministrationClient defines client-side interactions with the API.

func New

func New(endpoint string, creds Credentials, opts ...ClientOption) (_ DirectoryAdministrationClient, err error)

New creates a new admin.v2 API client from the provided http.Client. If no http Client is provided, a defaul one is created.

type ListCertificatesReply added in v1.5.0

type ListCertificatesReply struct {
	Certificates []Certificate `json:"certificates"`
}

ListCertificatesReply contains a list of certificates that have been issued to a VASP.

type ListReviewNotesReply

type ListReviewNotesReply struct {
	Notes []ReviewNote `json:"notes"`
}

ListReviewNotesReply contains information about a group of notes.

type ListVASPsParams

type ListVASPsParams struct {
	StatusFilters []string `url:"status,omitempty" form:"status"`
	Page          int      `url:"page,omitempty" form:"page" default:"1"`             // defaults to page 1 if not included
	PageSize      int      `url:"page_size,omitempty" form:"page_size" default:"100"` // defaults to 100 if not included
}

ListVASPsParams is a request-like struct that passes query params to the ListVASPs GET request. All query params are optional and modify how and what data is retrieved.

type ListVASPsReply

type ListVASPsReply struct {
	VASPs    []VASPSnippet `json:"vasps"`
	Count    int           `json:"count"`
	Page     int           `json:"page"`
	PageSize int           `json:"page_size"`
}

ListVASPsReply contains a summary data structure of all VASPs managed by the directory. The list reply contains standard pagination information, including the count of all VASPs and the links to previous and next.

type ModifyReviewNoteRequest

type ModifyReviewNoteRequest struct {
	// The ID of the VASP (optional - is part of the URL).
	VASP string `json:"vasp,omitempty"`

	// The ID of the note.
	// For CreateReviewNote, this is optional since it can be generated.
	// For UpdateReviewNote, this is optional since it is part of the URL.
	NoteID string `json:"note_id,omitempty"`

	// Actual text of the note.
	Text string `json:"text"`
}

ModifyReviewNoteRequest is a request-like struct for creating or updating notes.

type ReplaceContactRequest added in v1.3.1

type ReplaceContactRequest struct {
	// The ID of the VASP (optional - is part of the URL).
	VASP string `json:"vasp,omitempty"`

	// The kind of contact to replace, must be one of
	// ("administrative", "technical", "legal", "billing").
	Kind string `json:"kind"`

	// The new contact to replace the existing contact with, must be marshalled into a
	// gds.models.v1beta1.Contact protocol buffer.
	Contact map[string]interface{} `json:"contact,omitempty"`
}

ReplaceContactRequest is a request-like struct for replacing a contact on a VASP.

type Reply

type Reply struct {
	Success bool   `json:"success"`
	Error   string `json:"error,omitempty" yaml:"error,omitempty"`
}

Reply contains standard fields that are used for generic API responses and errors

func ErrorResponse

func ErrorResponse(err interface{}) Reply

ErrorResponse constructs an new response from the error or returns a success: false.

type ResendAction

type ResendAction string

ResendActions to use in ResendRequests

const (
	ResendVerifyContact ResendAction = "verify_contact"
	ResendReview        ResendAction = "review"
	ResendDeliverCerts  ResendAction = "deliver_certs"
	ResendRejection     ResendAction = "rejection"
	ReissuanceReminder  ResendAction = "reissuance_reminder"
	ReissuanceStarted   ResendAction = "reissuance_started"
)

func (*ResendAction) UnmarshalJSON

func (a *ResendAction) UnmarshalJSON(b []byte) (err error)

type ResendReply

type ResendReply struct {
	Sent    int    `json:"sent"`
	Message string `json:"message"`
}

ResendReply returns the number of emails sent and a status message from the server.

type ResendRequest

type ResendRequest struct {
	// The ID of the VASP to resend emails for (optional - is part of the URL)
	ID string `json:"vasp_id,omitempty"`

	// The resend action type, must parse to a ResendAction enumeration. If the action
	// is "rejection" then a reason must be supplied for the rejection as well.
	Action ResendAction `json:"action"`
	Reason string       `json:"reason,omitempty"`
}

ResendRequest allows extra attempts to resend emails to be made if they were not delivered or recieved the first time. This is a routine action that may need to be carried out from time to time.

type RetrieveVASPReply

type RetrieveVASPReply struct {
	Name             string                   `json:"name"`
	VASP             map[string]interface{}   `json:"vasp"`
	VerifiedContacts map[string]string        `json:"verified_contacts"`
	Traveler         bool                     `json:"traveler"`
	AuditLog         []map[string]interface{} `json:"audit_log"`
	EmailLog         []map[string]interface{} `json:"email_log"`
}

RetrieveVASPReply returns a pb.VASP record that has been marshaled by protojson and includes extra information such as verified contacts, whether or not the VASP is a Traveler node, and other pre-computed data to facilitate administrative actions. The serialized pb.VASP record is returned to make sure that the Admin API keeps up with changes in the TRISA library. Admin API developers should reference the trisacrypto/trisa library to ensure they have all of the requried data that is returned. Go developers should unmarshal the data into a *pb.VASP struct.

type ReviewNote

type ReviewNote struct {
	// The ID of the note.
	ID string `json:"id"`

	// Created, modified timestamps.
	Created  string `json:"created"`
	Modified string `json:"modified"`

	// Author, last editor of the note.
	Author string `json:"author"`
	Editor string `json:"editor"`

	// Actual text of the note.
	Text string `json:"text"`
}

type ReviewReply

type ReviewReply struct {
	// Status must be a valid trisa.gds.models.v1beta1.VerificationState
	Status  string `json:"status"`
	Message string `json:"message"`
}

ReviewReply returns verification status of the VASP Registration.

type ReviewRequest

type ReviewRequest struct {
	// The ID of the VASP to perform the review for (optional - is part of the URL)
	ID string `json:"vasp_id,omitempty"`

	// The verification token sent in the review email.
	// Lightweight authentication should be replaced by authentication and audit logs.
	AdminVerificationToken string `json:"admin_verification_token"`

	// If accept is false the request will be rejected and a reject reason must be
	// specfied. If it is true, then the certificate issuance process will begin.
	Accept       bool   `json:"accept"`
	RejectReason string `json:"reject_reason,omitempty"`
}

Registration review requests are sent via email to the TRISA admin email address with a lightweight token for review. This endpoint allows administrators to submit a review determination back to the directory server.

TODO: adapt this so there is no admin verification token and authentication is used.

type ReviewTimelineParams

type ReviewTimelineParams struct {
	Start string `url:"start,omitempty" form:"start"`
	End   string `url:"end,omitempty" form:"end"`
}

ReviewTimelineParams contains the start and end date for the requested timeline.

type ReviewTimelineRecord

type ReviewTimelineRecord struct {
	Week          string         `json:"week"`
	VASPsUpdated  int            `json:"vasps_updated"`
	Registrations map[string]int `json:"registrations"`
}

ReviewTimelineRecord contains counts of VASP registration states over a single week.

type ReviewTimelineReply

type ReviewTimelineReply struct {
	Weeks []ReviewTimelineRecord `json:"weeks"`
}

ReviewTimelineReply returns a list of time series records containing registration counts.

type ReviewTokenReply added in v1.3.1

type ReviewTokenReply struct {
	AdminVerificationToken string `json:"admin_verification_token"`
}

ReviewToken requests are used to determine if the VASP is eligible to be reviewed. If the admin verification token can be retrieved by an authenticated user, it can be presented in the ReviewRequest to complete the review. If a 404 is returned, it means that the VASP is not in a state where it can be reviewed.

type StatusReply

type StatusReply struct {
	Status    string    `json:"status"`
	Timestamp time.Time `json:"timestamp,omitempty"`
	Version   string    `json:"version,omitempty"`
}

StatusReply is returned on status requests. Note that no request is needed.

type SummaryReply

type SummaryReply struct {
	VASPsCount           int            `json:"vasps_count"`           // the total number of VASPs in any state in GDS
	PendingRegistrations int            `json:"pending_registrations"` // the number of registrations pending (in any pre-review status)
	ContactsCount        int            `json:"contacts_count"`        // the number of contacts in the system
	VerifiedContacts     int            `json:"verified_contacts"`     // the number of verified contacts in the system
	CertificatesIssued   int            `json:"certificates_issued"`   // the number of certificates issued by the GDS
	Statuses             map[string]int `json:"statuses"`              // the counts of all statuses in the system
	CertReqs             map[string]int `json:"certreqs"`              // The counts of all certificate request statuses
}

SummaryReply provides aggregate statistics that describe the state of the GDS.

type UpdateVASPReply

type UpdateVASPReply RetrieveVASPReply

UpdateVASPReply is identical to RetrieveVASPReply, simply renamed for clarity.

type UpdateVASPRequest

type UpdateVASPRequest struct {
	// The ID of the VASP (optional - is part of the URL).
	VASP string `json:"vasp,omitempty"`

	// The legal entity IVMS 101 data - this field completely replaces the VASP entity
	// if it is supplied and valid (no partial fields). The JSON data must be marshaled
	// into an ivms101.LegalPerson protocol buffer.
	Entity map[string]interface{} `json:"entity,omitempty"`

	// Common name can be updated only if the certificate has not been issued. It also
	// updates the certificate request to ensure the correct certs are issued. The TRISA
	// endpoint can be changed at any time, but should match the common name.
	CommonName    string `json:"common_name,omitempty"`
	TRISAEndpoint string `json:"trisa_endpoint,omitempty"`

	// Business information can be modified at any time
	Website          string   `json:"website,omitempty"`
	BusinessCategory string   `json:"business_category,omitempty"`
	VASPCategories   []string `json:"vasp_categories,omitempty"`
	EstablishedOn    string   `json:"established_on,omitempty"`

	// TRIXO questionnaire - this field completely replaces the VASP trixo if it is
	// supplied and valid (no partial fields). The JSON data must be marshaled into an
	// gds.models.v1beta1.TRIXQuestionnaire protocol buffer.
	TRIXO map[string]interface{} `json:"trixo,omitempty"`
}

UpdateVASPRequest allows the admin to PATCH a VASP record depending on the state that the VASP is in. For example, if the state is PENDING_REVIEW, the common name of the record can be edited, but once certificates have been issued, it can't be edited. The PATCH method requires fields to be present, e.g. the VASP is only updated if the fields below are non-zero. It is therefore impossible to set any of the fields described in the request to nil or an empty value.

type VASPSnippet

type VASPSnippet struct {
	ID                    string          `json:"id"`
	Name                  string          `json:"name"`
	CommonName            string          `json:"common_name"`
	RegisteredDirectory   string          `json:"registered_directory,omitempty"`
	VerificationStatus    string          `json:"verification_status,omitempty"`
	LastUpdated           string          `json:"last_updated,omitempty"`
	VerifiedOn            string          `json:"verified_on,omitempty"`
	Traveler              bool            `json:"traveler"`
	CertificateSerial     string          `json:"certificate_serial_number,omitempty"`
	CertificateIssued     string          `json:"certificate_issued,omitempty"`
	CertificateExpiration string          `json:"certificate_expiration,omitempty"`
	VerifiedContacts      map[string]bool `json:"verified_contacts"`
}

VASPSnippet provides summary information about a VASP.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL