oauth

package
v0.0.0-...-820a931 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2024 License: AGPL-3.0 Imports: 47 Imported by: 19

Documentation

Overview

Package oauth declares the OAuth client, and things related to them, from the certification of the flagship app to the creation of the access codes in the OAuth2 flow.

Index

Constants

View Source
const (
	// PlatformFirebase platform using Firebase Cloud Messaging (FCM)
	PlatformFirebase = "firebase"
	// PlatformAPNS platform using APNS/2
	PlatformAPNS = "apns"
	// PlatformHuawei platform using Huawei Push Kit
	PlatformHuawei = "huawei"
)
View Source
const AppleAppAttestRootCert = `` /* 797-byte string literal not displayed */

AppleAppAttestRootCert is the certificate coming from https://www.apple.com/certificateauthority/Apple_App_Attestation_Root_CA.pem

View Source
const ChallengeLen = 24

ChallengeLen is the number of random bytes used for generating a nonce for certifying an android/iOS app.

View Source
const ClientSecretLen = 24

ClientSecretLen is the number of random bytes used for generating the client secret

View Source
const DocTypeVersion = "1"

DocTypeVersion represents the doctype version. Each time this document structure is modified, update this value

View Source
const ScopeLogin = "login"

ScopeLogin is the special scope used by the manager or any other client for login/authentication purposes.

Variables

This section is empty.

Functions

func BuildLinkedAppScope

func BuildLinkedAppScope(slug string) string

BuildLinkedAppScope returns a formatted scope for a linked app

func CheckFlagshipCode

func CheckFlagshipCode(inst *instance.Instance, clientID string, token []byte, code string) bool

CheckFlagshipCode returns true if the code is correct and can be used to set the flagship flag on the given OAuth client.

func CheckOAuthClientsLimitReached

func CheckOAuthClientsLimitReached(i *instance.Instance, limit int) (reached, exceeded bool)

func CheckPlayIntegrityAttestationForTestingPurpose

func CheckPlayIntegrityAttestationForTestingPurpose(req AttestationRequest) error

CheckPlayIntegrityAttestationForTestingPurpose is only used for testing purpose. It is a simplified version of checkPlayIntegrityAttestation. In particular, it doesn't return an error for invalid package name with a test attestation.

func GenerateConfirmCode

func GenerateConfirmCode(inst *instance.Instance, clientID string) ([]byte, string, error)

GenerateConfirmCode generate a 6-digits code and the token to check it. They can be used to manually confirm that an OAuth client is the flagship app.

func GetLinkedAppSlug

func GetLinkedAppSlug(softwareID string) string

GetLinkedAppSlug returns a linked app slug from a softwareID

func IsLinkedApp

func IsLinkedApp(softwareID string) bool

IsLinkedApp checks if an OAuth client has a linked app

func PushClientsLimitAlert

func PushClientsLimitAlert(i *instance.Instance, clientName string, clientsLimit int)

PushClientsLimitAlert can be used to notify when the connected OAuth clients limit (if present) is exceeded.

func RegisterClientsLimitAlertCallback

func RegisterClientsLimitAlertCallback(cb func(i *instance.Instance, clientName string, clientsLimit int))

RegisterClientsLimitAlertCallback allows to register a callback function called when the connected OAuth clients limit (if present) is exceeded.

func SendConfirmFlagshipCode

func SendConfirmFlagshipCode(inst *instance.Instance, clientID string) ([]byte, error)

SendConfirmFlagshipCode sends by mail a code to the owner of the instance. It returns the generated token which can be used to check the code.

func SortClientsByCreatedAtDesc

func SortClientsByCreatedAtDesc(clients []*Client)

func ValidTokenWithSStamp

func ValidTokenWithSStamp(i *instance.Instance, audience, token string) (permission.Claims, bool)

ValidTokenWithSStamp checks that the JWT is valid and returns the associate claims. You should use client.ValidToken if you know the client, as it also checks that the claims are associated to this client.

Types

type AccessCode

type AccessCode struct {
	Code      string `json:"_id,omitempty"`
	CouchRev  string `json:"_rev,omitempty"`
	ClientID  string `json:"client_id"`
	IssuedAt  int64  `json:"issued_at"`
	Scope     string `json:"scope"`
	Challenge string `json:"code_challenge,omitempty"`
}

AccessCode is struct used during the OAuth2 flow. It has to be persisted in CouchDB, not just sent as a JSON Web Token, because it can be used only once (no replay attacks).

func CreateAccessCode

func CreateAccessCode(i *instance.Instance, client *Client, scope, challenge string) (*AccessCode, error)

CreateAccessCode an access code for the given clientID, persisted in CouchDB

func (*AccessCode) Clone

func (ac *AccessCode) Clone() couchdb.Doc

Clone implements couchdb.Doc

func (*AccessCode) DocType

func (ac *AccessCode) DocType() string

DocType returns the access code document type

func (*AccessCode) ID

func (ac *AccessCode) ID() string

ID returns the access code qualified identifier

func (*AccessCode) Rev

func (ac *AccessCode) Rev() string

Rev returns the access code revision

func (*AccessCode) SetID

func (ac *AccessCode) SetID(id string)

SetID changes the access code qualified identifier

func (*AccessCode) SetRev

func (ac *AccessCode) SetRev(rev string)

SetRev changes the access code revision

type AttestationRequest

type AttestationRequest struct {
	Platform    string `json:"platform"`
	Issuer      string `json:"issuer"`
	Challenge   string `json:"challenge"`
	Attestation string `json:"attestation"`
	KeyID       []byte `json:"keyId"`
}

AttestationRequest is what an OAuth client can send to attest that it is the flagship app.

type CleanMessage

type CleanMessage struct {
	ClientID string `json:"client_id"`
}

CleanMessage is used for messages to the clean-clients worker.

type Client

type Client struct {
	CouchID  string `json:"_id,omitempty"`  // Generated by CouchDB
	CouchRev string `json:"_rev,omitempty"` // Generated by CouchDB

	ClientID          string `json:"client_id,omitempty"`                 // Same as CouchID
	ClientSecret      string `json:"client_secret,omitempty"`             // Generated by the server
	SecretExpiresAt   int    `json:"client_secret_expires_at"`            // Forced by the server to 0 (no expiration)
	RegistrationToken string `json:"registration_access_token,omitempty"` // Generated by the server
	AllowLoginScope   bool   `json:"allow_login_scope,omitempty"`         // Allow to generate token for a "login" scope (no permissions)
	Pending           bool   `json:"pending,omitempty"`                   // True until a token is generated

	RedirectURIs    []string `json:"redirect_uris"`              // Declared by the client (mandatory)
	GrantTypes      []string `json:"grant_types"`                // Forced by the server to ["authorization_code", "refresh_token"]
	ResponseTypes   []string `json:"response_types"`             // Forced by the server to ["code"]
	ClientName      string   `json:"client_name"`                // Declared by the client (mandatory)
	ClientKind      string   `json:"client_kind,omitempty"`      // Declared by the client (optional, can be "desktop", "mobile", "browser", etc.)
	ClientURI       string   `json:"client_uri,omitempty"`       // Declared by the client (optional)
	LogoURI         string   `json:"logo_uri,omitempty"`         // Declared by the client (optional)
	PolicyURI       string   `json:"policy_uri,omitempty"`       // Declared by the client (optional)
	SoftwareID      string   `json:"software_id"`                // Declared by the client (mandatory)
	SoftwareVersion string   `json:"software_version,omitempty"` // Declared by the client (optional)
	ClientOS        string   `json:"client_os,omitempty"`        // Inferred by the server from the user-agent

	// Notifications parameters
	Notifications map[string]notification.Properties `json:"notifications,omitempty"`

	NotificationPlatform    string `json:"notification_platform,omitempty"`     // Declared by the client (optional)
	NotificationDeviceToken string `json:"notification_device_token,omitempty"` // Declared by the client (optional)

	// XXX omitempty does not work for time.Time, thus the interface{} type
	SynchronizedAt  interface{} `json:"synchronized_at,omitempty"`   // Date of the last synchronization, updated by /settings/synchronized
	LastRefreshedAt interface{} `json:"last_refreshed_at,omitempty"` // Date of the last refresh of the OAuth token

	Flagship            bool `json:"flagship,omitempty"`
	CertifiedFromStore  bool `json:"certified_from_store,omitempty"`
	CreatedAtOnboarding bool `json:"created_at_onboarding,omitempty"`

	Metadata *metadata.CozyMetadata `json:"cozyMetadata,omitempty"`
}

Client is a struct for OAuth2 client. Most of the fields are described in the OAuth 2.0 Dynamic Client Registration Protocol. The exception is `client_kind`, and it is an optional field. See https://tools.ietf.org/html/rfc7591

CouchID and ClientID are the same. They are just two ways to serialize to JSON, one for CouchDB and the other for the Dynamic Client Registration Protocol.

func FindClient

func FindClient(i *instance.Instance, id string) (*Client, error)

FindClient loads a client from the database

func FindClientByOnBoardingSecret

func FindClientByOnBoardingSecret(i *instance.Instance, onboardingSecret string) (*Client, error)

FindClientByOnBoardingSecret loads a client from the database with an OnboardingSecret

func FindClientBySoftwareID

func FindClientBySoftwareID(i *instance.Instance, softwareID string) (*Client, error)

FindClientBySoftwareID loads a client from the database

func FindOnboardingClient

func FindOnboardingClient(i *instance.Instance) (*Client, error)

FindOnboardingClient loads a client from the database with an OnboardingSecret

func GetAll

func GetAll(inst *instance.Instance, limit int, bookmark string) ([]*Client, string, error)

GetAll loads all the clients from the database, without the secret

func GetConnectedUserClients

func GetConnectedUserClients(i *instance.Instance, limit int, bookmark string) ([]*Client, string, error)

func GetNotifiables

func GetNotifiables(i *instance.Instance) ([]*Client, error)

GetNotifiables loads all the clients from the database containing a non-empty `notification_plaform` field.

func (*Client) AcceptRedirectURI

func (c *Client) AcceptRedirectURI(u string) bool

AcceptRedirectURI returns true if the given URI matches the registered redirect_uris

func (*Client) Attest

func (c *Client) Attest(inst *instance.Instance, req AttestationRequest) error

Attest can be used to check an attestation for certifying the app.

func (*Client) CheckSoftwareID

func (c *Client) CheckSoftwareID(instance *instance.Instance) *ClientRegistrationError

CheckSoftwareID checks if a SoftwareID is valid

func (*Client) Clone

func (c *Client) Clone() couchdb.Doc

Clone implements couchdb.Doc

func (*Client) Create

Create is a function that sets some fields, and then save it in Couch.

func (*Client) CreateChallenge

func (c *Client) CreateChallenge(inst *instance.Instance) (string, error)

CreateChallenge can be used to generate a challenge for certifying the app.

func (*Client) CreateJWT

func (c *Client) CreateJWT(i *instance.Instance, audience, scope string) (string, error)

CreateJWT returns a new JSON Web Token for the given instance and audience

func (*Client) Delete

Delete is a function that unregister a client

func (*Client) DocType

func (c *Client) DocType() string

DocType returns the client document type

func (*Client) ID

func (c *Client) ID() string

ID returns the client qualified identifier

func (*Client) Rev

func (c *Client) Rev() string

Rev returns the client revision

func (*Client) SetCreatedAtOnboarding

func (c *Client) SetCreatedAtOnboarding(inst *instance.Instance) error

SetCreatedAtOnboarding updates the client in CouchDB with created_at_onboarding set to true.

func (*Client) SetFlagship

func (c *Client) SetFlagship(inst *instance.Instance) error

SetFlagship updates the client in CouchDB with flagship set to true.

func (*Client) SetID

func (c *Client) SetID(id string)

SetID changes the client qualified identifier

func (*Client) SetRev

func (c *Client) SetRev(rev string)

SetRev changes the client revision

func (*Client) TransformIDAndRev

func (c *Client) TransformIDAndRev()

TransformIDAndRev makes the translation from the JSON of CouchDB to the one used in the dynamic client registration protocol

func (*Client) Update

func (c *Client) Update(i *instance.Instance, old *Client) *ClientRegistrationError

Update will update the client metadata

func (*Client) ValidToken

func (c *Client) ValidToken(i *instance.Instance, audience, token string) (permission.Claims, bool)

ValidToken checks that the JWT is valid and returns the associate claims. It is expected to be used for registration token and refresh token, and it doesn't check when they were issued as they don't expire.

type ClientRegistrationError

type ClientRegistrationError struct {
	Code        int    `json:"-"`
	Error       string `json:"error"`
	Description string `json:"error_description,omitempty"`
}

ClientRegistrationError is a Client Registration Error Response, as described in the Client Dynamic Registration Protocol See https://tools.ietf.org/html/rfc7591#section-3.2.2 for errors

type CreateOptions

type CreateOptions int

CreateOptions can be used to give options when creating an OAuth client

const (
	// NotPending option won't set the pending flag, and will avoid creating a
	// trigger to check if the client should be cleaned. It is used for
	// sharings by example, as a token is created just after the client
	// creation.
	NotPending CreateOptions = iota + 1
)

type Store

type Store interface {
	SaveChallenge(db prefixer.Prefixer, clientID, nonce string) error
	CheckAndClearChallenge(db prefixer.Prefixer, clientID, nonce string) bool
}

Store is an object to store and retrieve session codes.

func GetStore

func GetStore() Store

GetStore returns the store for temporary move objects.

Jump to

Keyboard shortcuts

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