vouch-proxy/pkg/structs/structs.go

243 lines
6.2 KiB
Go

/*
Copyright 2020 The Vouch Proxy Authors.
Use of this source code is governed by The MIT License (MIT) that
can be found in the LICENSE file. Software distributed under The
MIT License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
OR CONDITIONS OF ANY KIND, either express or implied.
*/
package structs
import "strconv"
// CustomClaims Temporary struct storing custom claims until JWT creation.
type CustomClaims struct {
Claims map[string]interface{}
}
// UserI each *User struct must prepare the data for being placed in the JWT
type UserI interface {
PrepareUserData()
}
// User is inherited.
type User struct {
// TODO: set Provider here so that we can pass it to db
// populated by db (via mapstructure) or from provider (via json)
// Provider string `json:"provider",mapstructure:"provider"`
Username string `json:"username" mapstructure:"username"`
Name string `json:"name" mapstructure:"name"`
Email string `json:"email" mapstructure:"email"`
CreatedOn int64 `json:"createdon"`
LastUpdate int64 `json:"lastupdate"`
// don't populate ID from json https://github.com/vouch/vouch-proxy/issues/185
ID int `json:"-" mapstructure:"id"`
// jwt.StandardClaims
TeamMemberships []string
}
// PrepareUserData implement PersonalData interface
func (u *User) PrepareUserData() {
if u.Username == "" {
u.Username = u.Email
}
}
// AzureUser is a retrieved and authenticated user from Azure AD
type AzureUser struct {
User
Sub string `json:"sub"`
UPN string `json:"upn"`
PreferredUsername string `json:"preferred_username"`
}
// PrepareUserData implement PersonalData interface
func (u *AzureUser) PrepareUserData() {
// AzureAD uses the 'upn' (UserPrincipleName) field to store the email address of the user
// See https://docs.microsoft.com/en-us/azure/active-directory/hybrid/plan-connect-userprincipalname
if u.Username == "" {
u.Username = u.UPN
}
if u.Username == "" {
u.Username = u.PreferredUsername
}
if u.Email == "" {
u.Email = u.UPN
}
}
// GoogleUser is a retrieved and authentiacted user from Google.
// unused!
// TODO: see if these should be pointers to the *User object as per
// https://golang.org/doc/effective_go.html#embedding
type GoogleUser struct {
User
Sub string `json:"sub"`
GivenName string `json:"given_name"`
FamilyName string `json:"family_name"`
Profile string `json:"profile"`
Picture string `json:"picture"`
EmailVerified bool `json:"email_verified"`
Gender string `json:"gender"`
HostDomain string `json:"hd"`
// jwt.StandardClaims
}
// PrepareUserData implement PersonalData interface
func (u *GoogleUser) PrepareUserData() {
u.Username = u.Email
}
// ADFSUser Active Directory user record
type ADFSUser struct {
User
Sub string `json:"sub"`
UPN string `json:"upn"`
// UniqueName string `json:"unique_name"`
// PwdExp string `json:"pwd_exp"`
// SID string `json:"sid"`
// Groups string `json:"groups"`
// jwt.StandardClaims
}
// PrepareUserData implement PersonalData interface
func (u *ADFSUser) PrepareUserData() {
u.Username = u.UPN
}
// GitHubUser is a retrieved and authentiacted user from GitHub.
type GitHubUser struct {
User
Login string `json:"login"`
Picture string `json:"avatar_url"`
// jwt.StandardClaims
}
// GitHubTeamMembershipState for GitHub team api call
type GitHubTeamMembershipState struct {
State string `json:"state"`
}
// PrepareUserData implement PersonalData interface
func (u *GitHubUser) PrepareUserData() {
// always use the u.Login as the u.Username
u.Username = u.Login
}
// IndieAuthUser see indieauth.net
type IndieAuthUser struct {
User
URL string `json:"me"`
}
// PrepareUserData implement PersonalData interface
func (u *IndieAuthUser) PrepareUserData() {
u.Username = u.URL
}
// Contact used for OpenStaxUser
type Contact struct {
Type string `json:"type"`
Value string `json:"value"`
Verified bool `json:"is_verified"`
}
//OpenStaxUser is a retrieved and authenticated user from OpenStax Accounts
type OpenStaxUser struct {
User
Contacts []Contact `json:"contact_infos"`
}
// PrepareUserData implement PersonalData interface
func (u *OpenStaxUser) PrepareUserData() {
if u.Email == "" {
// assuming first contact of type "EmailAddress"
for _, c := range u.Contacts {
if c.Type == "EmailAddress" && c.Verified {
u.Email = c.Value
break
}
}
}
}
// Ocs used for NextcloudUser
type Ocs struct {
Data struct {
UserID string `json:"id"`
Email string `json:"email"`
} `json:"data"`
}
// NextcloudUser User of Nextcloud retreived from ocs endpoint
type NextcloudUser struct {
User
Ocs Ocs `json:"ocs"`
}
// PrepareUserData NextcloudUser
func (u *NextcloudUser) PrepareUserData() {
if u.Username == "" {
u.Username = u.Ocs.Data.UserID
u.Email = u.Ocs.Data.Email
}
}
// AlibabaUser Aliyun
type AlibabaUser struct {
User
Data AliData `json:"data"`
// jwt.StandardClaims
}
// PrepareUserData implement PersonalData interface
func (u *AlibabaUser) PrepareUserData() {
u.Username = u.Data.Username
u.Name = u.Data.Nickname
u.Email = u.Data.Email
id, _ := strconv.Atoi(u.Data.ID)
u.ID = id
}
// AliData `data` subobject of Alibaba User response
// https://github.com/vouch/vouch-proxy/issues/344
type AliData struct {
Sub string `json:"sub"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Email string `json:"email"`
ID string `json:"ou_id"`
Phone string `json:"phone_number"`
OuName string `json:"ou_name"`
}
// Team has members and provides acess to sites
type Team struct {
Name string `json:"name" mapstructure:"name"`
Members []string `json:"members" mapstructure:"members"` // just the emails
Sites []string `json:"sites" mapstructure:"sites"` // just the domains
CreatedOn int64 `json:"createdon" mapstructure:"createdon"`
LastUpdate int64 `json:"lastupdate" mapstructure:"lastupdate"`
ID int `json:"id" mapstructure:"id"`
}
// Site is the basic unit of auth
type Site struct {
Domain string `json:"domain"`
CreatedOn int64 `json:"createdon"`
LastUpdate int64 `json:"lastupdate"`
ID int `json:"id" mapstructure:"id"`
}
// PTokens provider tokens (from the IdP)
type PTokens struct {
PAccessToken string
PIdToken string
}