Documentation
¶
Overview ¶
Package iam is ai's INTERNAL IAM client: the small, clean OIDC+REST surface ai needs to talk to Hanzo IAM (hanzo.id), decoupled from the retired Casdoor SDK module github.com/hanzoai/iam-v1.
It is NOT a published SDK. It exists so ai links only against standard OIDC (JWKS token verification) and the IAM server's JSON REST API (/v1/iam/...), instead of pulling in the whole Casdoor server module (beego, xorm, ldap, aliyun/aws SDKs, …) that iam-v1 dragged into ai's build for code ai never ran.
The wire types (User, Claims, Permission, Resource, …) mirror the IAM server's JSON models so requests round-trip losslessly — in particular the full User field set with its json tags is reproduced verbatim, because object/redact.go reflects over every User field by json tag as a fail-secure secret-redaction control. Slimming User would silently weaken that control and break its test, so fidelity is required, not optional.
Endpoint resolution: callers configure a Client explicitly via InitConfig / NewClient (ai's account bootstrap does), and the package-level helpers fall back to a lazily-built client from IAM_ENDPOINT / IAM_ISSUER (default https://hanzo.id) so a read never nil-panics when InitConfig was skipped.
Index ¶
- func AddPermission(permission *Permission) (bool, error)
- func DeletePermission(permission *Permission) (bool, error)
- func DeleteResourceWithTag(resource *Resource, tag string) (bool, error)
- func GetOAuthToken(code, state string, opts ...OAuthOption) (*oauth2.Token, error)
- func InitConfig(endpoint, clientId, clientSecret, certificate, organizationName, ... string)
- func SendEmail(title, content, sender string, receivers ...string) error
- func SetHttpClient(httpClient HttpClient)
- func UpdatePermission(permission *Permission) (bool, error)
- func UpdateUserForColumns(user *User, columns []string) (bool, error)
- func UploadResource(user, tag, parent, fullFilePath string, fileBytes []byte) (string, string, error)
- type Address
- type Application
- type AuthConfig
- type Cert
- type Claims
- type Client
- func (c *Client) AddPermission(permission *Permission) (bool, error)
- func (c *Client) DeletePermission(permission *Permission) (bool, error)
- func (c *Client) DeleteResourceWithTag(resource *Resource, tag string) (bool, error)
- func (c *Client) DoGetBytes(url string) ([]byte, error)
- func (c *Client) DoGetResponse(url string) (*Response, error)
- func (c *Client) DoPost(action string, queryMap map[string]string, postBytes []byte, ...) (*Response, error)
- func (c *Client) GetApplication(name string) (*Application, error)
- func (c *Client) GetCert(name string) (*Cert, error)
- func (c *Client) GetId(name string) string
- func (c *Client) GetOAuthToken(code, state string, opts ...OAuthOption) (*oauth2.Token, error)
- func (c *Client) GetOrganization(name string) (*Organization, error)
- func (c *Client) GetPermission(name string) (*Permission, error)
- func (c *Client) GetPermissions() ([]*Permission, error)
- func (c *Client) GetProviders() ([]*Provider, error)
- func (c *Client) GetResources(owner, user, field, value, sortField, sortOrder string) ([]*Resource, error)
- func (c *Client) GetUrl(action string, queryMap map[string]string) string
- func (c *Client) GetUser(name string) (*User, error)
- func (c *Client) GetUsers() ([]*User, error)
- func (c *Client) ParseJwtToken(token string) (*Claims, error)
- func (c *Client) SendEmail(title, content, sender string, receivers ...string) error
- func (c *Client) UpdatePermission(permission *Permission) (bool, error)
- func (c *Client) UpdateUserForColumns(user *User, columns []string) (bool, error)
- func (c *Client) UploadResource(user, tag, parent, fullFilePath string, fileBytes []byte) (string, string, error)
- type FaceId
- type HttpClient
- type ManagedAccount
- type MfaAccount
- type MfaItem
- type MfaProps
- type OAuthOption
- type OrgRef
- type Organization
- type Permission
- type ProductInfo
- type Provider
- type Resource
- type Response
- type Role
- type User
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddPermission ¶
func AddPermission(permission *Permission) (bool, error)
func DeletePermission ¶
func DeletePermission(permission *Permission) (bool, error)
func DeleteResourceWithTag ¶
func GetOAuthToken ¶
func GetOAuthToken(code, state string, opts ...OAuthOption) (*oauth2.Token, error)
GetOAuthToken exchanges a code using the configured (or env-derived) client.
func InitConfig ¶
func InitConfig(endpoint, clientId, clientSecret, certificate, organizationName, applicationName string)
InitConfig sets the package-global Client used by the package-level helpers (GetUser, ParseJwtToken, …). ai's account bootstrap calls this with the deployed IAM endpoint and app credentials.
func SetHttpClient ¶
func SetHttpClient(httpClient HttpClient)
SetHttpClient overrides the shared http client (tests).
func UpdatePermission ¶
func UpdatePermission(permission *Permission) (bool, error)
Types ¶
type Address ¶
type Address struct {
Tag string `json:"tag"`
Line1 string `json:"line1"`
Line2 string `json:"line2"`
City string `json:"city"`
State string `json:"state"`
ZipCode string `json:"zipCode"`
Region string `json:"region"`
}
Address is one postal address on a User.
type Application ¶
type Application struct {
Owner string `json:"owner"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Cert string `json:"cert"`
RedirectUris []string `json:"redirectUris"`
}
Application is the subset of the IAM Application model ai reads: DisplayName, the signing cert name, and the OAuth redirect allowlist. Read-only response (GetApplication), so a projection is correct.
func GetApplication ¶
func GetApplication(name string) (*Application, error)
GetApplication uses the configured (or env-derived) client.
type AuthConfig ¶
type AuthConfig struct {
Endpoint string
ClientId string
ClientSecret string
Certificate string
OrganizationName string
ApplicationName string
}
AuthConfig is the connection config for a Client: the IAM server endpoint and the app credentials/context requests are made under.
type Cert ¶
type Cert struct {
Owner string `json:"owner"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Scope string `json:"scope"`
Type string `json:"type"`
CryptoAlgorithm string `json:"cryptoAlgorithm"`
Certificate string `json:"certificate"`
}
Cert is the subset of the IAM Cert model ai reads. ai consumes the PEM in Certificate (to verify token signatures when JWKS is unavailable).
type Claims ¶
type Claims struct {
User
AccessToken string `json:"accessToken"`
jwt.RegisteredClaims
TokenType string `json:"tokenType"`
RefreshTokenType string `json:"TokenType"`
SigninMethod string `json:"signinMethod"`
Orgs []OrgRef `json:"orgs,omitempty"`
// BillingAccount is the signed `billing_account` claim: WHO PAYS for this
// credential, stated by IAM at mint time. Wire is "<kind>:<subject>"
// (e.g. "org:acme"). Empty when IAM could not attribute; a reader must fall
// back rather than bill a guess.
BillingAccount string `json:"billing_account,omitempty"`
}
Claims is the verified access-token claim set. It embeds the User (so a token carries the subject's profile) plus the standard registered claims and the Hanzo-specific token/org/billing claims. Shape matches the IAM server so the /get-account response promotes every field identically.
func ParseJwtToken ¶
ParseJwtToken verifies a JWT's signature against the IAM server's published JWKS (proper OIDC) and returns its claims. RS256/RS512/ES256/ES512 only.
type Client ¶
type Client struct {
AuthConfig
CustomHeaders map[string]string
}
Client talks to a Hanzo IAM server over its /v1/iam/ JSON REST API and verifies its tokens via published JWKS. It is the one place the endpoint and app credentials live.
func NewClient ¶
func NewClient(endpoint, clientId, clientSecret, certificate, organizationName, applicationName string) *Client
NewClient builds a Client for an explicit endpoint + app context.
func NewClientWithConf ¶
func NewClientWithConf(config *AuthConfig) *Client
NewClientWithConf builds a Client from an AuthConfig.
func (*Client) AddPermission ¶
func (c *Client) AddPermission(permission *Permission) (bool, error)
func (*Client) DeletePermission ¶
func (c *Client) DeletePermission(permission *Permission) (bool, error)
func (*Client) DeleteResourceWithTag ¶
DeleteResourceWithTag deletes a resource, defaulting its owner to the client's organization.
func (*Client) DoGetBytes ¶
DoGetBytes GETs url and returns the envelope's data field re-marshaled to JSON bytes, ready to unmarshal into a typed value.
func (*Client) DoGetResponse ¶
DoGetResponse GETs url and returns the decoded IAM envelope, erroring on a non-"ok" status.
func (*Client) DoPost ¶
func (c *Client) DoPost(action string, queryMap map[string]string, postBytes []byte, isForm, isFile bool) (*Response, error)
DoPost posts to /v1/iam/<action>. isForm/isFile select multipart file upload, multipart form fields, or a raw text/plain body.
func (*Client) GetApplication ¶
func (c *Client) GetApplication(name string) (*Application, error)
GetApplication fetches an application by name (owned by admin).
func (*Client) GetOAuthToken ¶
GetOAuthToken exchanges an authorization code for a token against the IAM server's OAuth endpoints.
func (*Client) GetOrganization ¶
func (c *Client) GetOrganization(name string) (*Organization, error)
GetOrganization fetches an organization by name.
func (*Client) GetPermission ¶
func (c *Client) GetPermission(name string) (*Permission, error)
GetPermission fetches a permission by name within the client's organization.
func (*Client) GetPermissions ¶
func (c *Client) GetPermissions() ([]*Permission, error)
GetPermissions lists all permissions in the client's organization.
func (*Client) GetProviders ¶
GetProviders lists all providers in the client's organization.
func (*Client) GetResources ¶
func (c *Client) GetResources(owner, user, field, value, sortField, sortOrder string) ([]*Resource, error)
GetResources lists stored resources matching the given filter.
func (*Client) GetUrl ¶
GetUrl builds a /v1/iam/<action> URL with the given query params. Hanzo IAM serves its JSON API under /v1/iam/ only (the Casdoor /api/ prefix is retired).
func (*Client) ParseJwtToken ¶
ParseJwtToken verifies token against this client's IAM endpoint JWKS, falling back to a configured certificate PEM only when JWKS is unreachable.
func (*Client) SendEmail ¶
SendEmail sends an email via IAM's configured mail provider (/v1/iam/send-email). This proxies mail through IAM exactly as ai did via the old SDK; it is not identity, but keeping the REST call preserves behavior with no new coupling.
func (*Client) UpdatePermission ¶
func (c *Client) UpdatePermission(permission *Permission) (bool, error)
func (*Client) UpdateUserForColumns ¶
UpdateUserForColumns updates only the named columns of user.
type FaceId ¶
type FaceId struct {
Name string `json:"name"`
FaceIdData []float64 `json:"faceIdData"`
ImageUrl string `json:"ImageUrl"`
}
FaceId is enrolled biometric face data.
type HttpClient ¶
HttpClient is the minimal http doer a Client uses; *http.Client satisfies it.
type ManagedAccount ¶
type ManagedAccount struct {
Application string `json:"application"`
Username string `json:"username"`
Password string `json:"password"`
SigninUrl string `json:"signinUrl"`
}
ManagedAccount is a linked downstream account (carries a password).
type MfaAccount ¶
type MfaAccount struct {
AccountName string `json:"accountName"`
Issuer string `json:"issuer"`
SecretKey string `json:"secretKey"`
Origin string `json:"origin"`
}
MfaAccount is a TOTP account entry (carries a secret key).
type MfaProps ¶
type MfaProps struct {
Enabled bool `json:"enabled"`
IsPreferred bool `json:"isPreferred"`
MfaType string `json:"mfaType"`
Secret string `json:"secret,omitempty"`
CountryCode string `json:"countryCode,omitempty"`
URL string `json:"url,omitempty"`
RecoveryCodes []string `json:"recoveryCodes,omitempty"`
}
MfaProps is one enrolled multi-factor method. Secret/RecoveryCodes are credentials and are cleared by object/redact.go before a user is returned.
type OAuthOption ¶
type OAuthOption func(*oauthOptions)
OAuthOption configures an OAuth request.
func WithHTTPClient ¶
func WithHTTPClient(httpClient *http.Client) OAuthOption
WithHTTPClient sets a custom http client for the OAuth exchange.
type OrgRef ¶
OrgRef is one entry of the signed `orgs` membership-set claim: an org the subject may act in, plus a coarse role there.
type Organization ¶
type Organization struct {
Owner string `json:"owner"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
}
Organization is the subset of the IAM Organization model ai reads. It is a read-only response (GetOrganization), so a projection is correct: json unmarshal ignores the fields ai does not consume.
func GetOrganization ¶
func GetOrganization(name string) (*Organization, error)
GetOrganization uses the configured (or env-derived) client.
type Permission ¶
type Permission struct {
Owner string `json:"owner"`
Name string `json:"name"`
CreatedTime string `json:"createdTime"`
DisplayName string `json:"displayName"`
Description string `json:"description"`
Users []string `json:"users"`
Groups []string `json:"groups"`
Roles []string `json:"roles"`
Domains []string `json:"domains"`
Model string `json:"model"`
Adapter string `json:"adapter"`
ResourceType string `json:"resourceType"`
Resources []string `json:"resources"`
Actions []string `json:"actions"`
Effect string `json:"effect"`
IsEnabled bool `json:"isEnabled"`
Submitter string `json:"submitter"`
Approver string `json:"approver"`
ApproveTime string `json:"approveTime"`
State string `json:"state"`
}
Permission mirrors the IAM server's Permission JSON model. ai marshals a client-supplied permission into this type and posts it back on add/update/delete, so the full field set is kept for a lossless round-trip (a slim struct would drop unknown fields and corrupt the stored permission).
func GetPermission ¶
func GetPermission(name string) (*Permission, error)
func GetPermissions ¶
func GetPermissions() ([]*Permission, error)
type ProductInfo ¶
type ProductInfo struct {
Owner string `json:"owner"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Image string `json:"image,omitempty"`
Detail string `json:"detail,omitempty"`
Price float64 `json:"price"`
Currency string `json:"currency,omitempty"`
IsRecharge bool `json:"isRecharge,omitempty"`
Quantity int `json:"quantity,omitempty"`
PricingName string `json:"pricingName,omitempty"`
PlanName string `json:"planName,omitempty"`
}
ProductInfo is one line item on a User's cart.
type Provider ¶
type Provider struct {
Owner string `json:"owner"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Category string `json:"category"`
Type string `json:"type"`
}
Provider is the subset of the IAM Provider model ai reads. ai filters the provider list by Category (e.g. "Storage"). Read-only response (GetProviders), so a projection is correct.
func GetProviders ¶
GetProviders uses the configured (or env-derived) client.
type Resource ¶
type Resource struct {
Owner string `json:"owner"`
Name string `json:"name"`
CreatedTime string `json:"createdTime"`
User string `json:"user"`
Provider string `json:"provider"`
Application string `json:"application"`
Tag string `json:"tag"`
Parent string `json:"parent"`
FileName string `json:"fileName"`
FileType string `json:"fileType"`
FileFormat string `json:"fileFormat"`
FileSize int `json:"fileSize"`
Url string `json:"url"`
Description string `json:"description"`
}
Resource mirrors the IAM Resource JSON model (a stored file record). ai constructs one client-side to delete by tag, and reads Name/CreatedTime/ FileSize/Url off the list response, so the full field set is kept.
NOTE: these resource calls proxy file storage through IAM's /v1/iam/ upload/list/delete endpoints — the same behavior ai had via the old SDK. Re-homing file storage to S3 directly is a possible future cleanup, but is out of scope for decoupling from the retired iam-v1 module: keeping the REST calls preserves behavior exactly.
func GetResources ¶
type Response ¶
type Response struct {
Status string `json:"status"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
Data2 interface{} `json:"data2"`
}
Response is the IAM JSON envelope: {status, msg, data, data2}.
type Role ¶
type Role struct {
Owner string `json:"owner"`
Name string `json:"name"`
CreatedTime string `json:"createdTime"`
DisplayName string `json:"displayName"`
Description string `json:"description"`
Users []string `json:"users"`
Groups []string `json:"groups"`
Roles []string `json:"roles"`
Domains []string `json:"domains"`
IsEnabled bool `json:"isEnabled"`
}
Role is an IAM role reference.
type User ¶
type User struct {
Owner string `json:"owner"`
Name string `json:"name"`
CreatedTime string `json:"createdTime"`
UpdatedTime string `json:"updatedTime"`
DeletedTime string `json:"deletedTime"`
Id string `json:"id"`
ExternalId string `json:"externalId"`
Type string `json:"type"`
Password string `json:"password"`
PasswordSalt string `json:"passwordSalt"`
PasswordType string `json:"passwordType"`
DisplayName string `json:"displayName"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Avatar string `json:"avatar"`
AvatarType string `json:"avatarType"`
PermanentAvatar string `json:"permanentAvatar"`
Email string `json:"email"`
EmailVerified bool `json:"emailVerified"`
Phone string `json:"phone"`
CountryCode string `json:"countryCode"`
Region string `json:"region"`
Location string `json:"location"`
Address []string `json:"address"`
Addresses []*Address `json:"addresses"`
Affiliation string `json:"affiliation"`
Title string `json:"title"`
IdCardType string `json:"idCardType"`
IdCard string `json:"idCard"`
RealName string `json:"realName"`
IsVerified bool `json:"isVerified"`
Homepage string `json:"homepage"`
Bio string `json:"bio"`
Tag string `json:"tag"`
Language string `json:"language"`
Gender string `json:"gender"`
Birthday string `json:"birthday"`
Education string `json:"education"`
Score int `json:"score"`
Karma int `json:"karma"`
Ranking int `json:"ranking"`
Balance float64 `json:"balance"`
BalanceCredit float64 `json:"balanceCredit"`
Currency string `json:"currency"`
BalanceCurrency string `json:"balanceCurrency"`
IsDefaultAvatar bool `json:"isDefaultAvatar"`
IsOnline bool `json:"isOnline"`
IsAdmin bool `json:"isAdmin"`
IsForbidden bool `json:"isForbidden"`
IsDeleted bool `json:"isDeleted"`
SignupApplication string `json:"signupApplication"`
Hash string `json:"hash"`
PreHash string `json:"preHash"`
RegisterType string `json:"registerType"`
RegisterSource string `json:"registerSource"`
AccessKey string `json:"accessKey"`
AccessSecret string `json:"accessSecret"`
AccessToken string `json:"accessToken"`
OriginalToken string `json:"originalToken"`
OriginalRefreshToken string `json:"originalRefreshToken"`
CreatedIp string `json:"createdIp"`
LastSigninTime string `json:"lastSigninTime"`
LastSigninIp string `json:"lastSigninIp"`
GitHub string `json:"github"`
Google string `json:"google"`
QQ string `json:"qq"`
WeChat string `json:"wechat"`
Facebook string `json:"facebook"`
DingTalk string `json:"dingtalk"`
Weibo string `json:"weibo"`
Gitee string `json:"gitee"`
LinkedIn string `json:"linkedin"`
Wecom string `json:"wecom"`
Lark string `json:"lark"`
Gitlab string `json:"gitlab"`
Adfs string `json:"adfs"`
Baidu string `json:"baidu"`
Alipay string `json:"alipay"`
Infoflow string `json:"infoflow"`
Apple string `json:"apple"`
AzureAD string `json:"azuread"`
AzureADB2c string `json:"azureadb2c"`
Slack string `json:"slack"`
Steam string `json:"steam"`
Bilibili string `json:"bilibili"`
Okta string `json:"okta"`
Douyin string `json:"douyin"`
Kwai string `json:"kwai"`
Line string `json:"line"`
Amazon string `json:"amazon"`
Auth0 string `json:"auth0"`
BattleNet string `json:"battlenet"`
Bitbucket string `json:"bitbucket"`
Box string `json:"box"`
CloudFoundry string `json:"cloudfoundry"`
Dailymotion string `json:"dailymotion"`
Deezer string `json:"deezer"`
DigitalOcean string `json:"digitalocean"`
Discord string `json:"discord"`
Dropbox string `json:"dropbox"`
EveOnline string `json:"eveonline"`
Fitbit string `json:"fitbit"`
Gitea string `json:"gitea"`
Heroku string `json:"heroku"`
InfluxCloud string `json:"influxcloud"`
Instagram string `json:"instagram"`
Intercom string `json:"intercom"`
Kakao string `json:"kakao"`
Lastfm string `json:"lastfm"`
Mailru string `json:"mailru"`
Meetup string `json:"meetup"`
MicrosoftOnline string `json:"microsoftonline"`
Nextcloud string `json:"nextcloud"`
OneDrive string `json:"onedrive"`
Oura string `json:"oura"`
Patreon string `json:"patreon"`
Paypal string `json:"paypal"`
SalesForce string `json:"salesforce"`
Shopify string `json:"shopify"`
Soundcloud string `json:"soundcloud"`
Spotify string `json:"spotify"`
Strava string `json:"strava"`
Stripe string `json:"stripe"`
TikTok string `json:"tiktok"`
Tumblr string `json:"tumblr"`
Twitch string `json:"twitch"`
Twitter string `json:"twitter"`
Typetalk string `json:"typetalk"`
Uber string `json:"uber"`
VK string `json:"vk"`
Wepay string `json:"wepay"`
Xero string `json:"xero"`
Yahoo string `json:"yahoo"`
Yammer string `json:"yammer"`
Yandex string `json:"yandex"`
Zoom string `json:"zoom"`
Custom string `json:"custom"`
Custom2 string `json:"custom2"`
Custom3 string `json:"custom3"`
Custom4 string `json:"custom4"`
Custom5 string `json:"custom5"`
Custom6 string `json:"custom6"`
Custom7 string `json:"custom7"`
Custom8 string `json:"custom8"`
Custom9 string `json:"custom9"`
Custom10 string `json:"custom10"`
PreferredMfaType string `json:"preferredMfaType"`
RecoveryCodes []string `json:"recoveryCodes"`
TotpSecret string `json:"totpSecret"`
MfaPhoneEnabled bool `json:"mfaPhoneEnabled"`
MfaEmailEnabled bool `json:"mfaEmailEnabled"`
MfaRadiusEnabled bool `json:"mfaRadiusEnabled"`
MfaRadiusUsername string `json:"mfaRadiusUsername"`
MfaRadiusProvider string `json:"mfaRadiusProvider"`
MfaPushEnabled bool `json:"mfaPushEnabled"`
MfaPushReceiver string `json:"mfaPushReceiver"`
MfaPushProvider string `json:"mfaPushProvider"`
MultiFactorAuths []*MfaProps `json:"multiFactorAuths,omitempty"`
Invitation string `json:"invitation"`
InvitationCode string `json:"invitationCode"`
FaceIds []*FaceId `json:"faceIds"`
Cart []ProductInfo `json:"cart"`
Ldap string `json:"ldap"`
Properties map[string]string `json:"properties"`
Roles []*Role `json:"roles"`
Permissions []*Permission `json:"permissions"`
Groups []string `json:"groups"`
LastChangePasswordTime string `json:"lastChangePasswordTime"`
LastSigninWrongTime string `json:"lastSigninWrongTime"`
SigninWrongTimes int `json:"signinWrongTimes"`
ManagedAccounts []ManagedAccount `json:"managedAccounts"`
MfaAccounts []MfaAccount `json:"mfaAccounts"`
MfaItems []*MfaItem `json:"mfaItems"`
MfaRememberDeadline string `json:"mfaRememberDeadline"`
NeedUpdatePassword bool `json:"needUpdatePassword"`
IpWhitelist string `json:"ipWhitelist"`
}
User mirrors the Hanzo IAM server's User JSON model. The FULL field set is reproduced deliberately (not a slim projection): object/redact.go reflects over every field by its json tag as a fail-secure secret-redaction control, and it must see every credential field (password*, *Secret, *Token, totp, social-login ids, custom1..10, …) to zero it before a user is returned to a client. A slim User would silently narrow that control and break its test. The json tags are therefore load-bearing and match the server verbatim; the Casdoor xorm/db tags are dropped (ai has no ORM).