2021-01-08 10:33:45 +00:00
|
|
|
package domain
|
|
|
|
|
|
|
|
import (
|
2023-07-18 12:42:57 +00:00
|
|
|
"regexp"
|
2021-04-19 14:43:36 +00:00
|
|
|
"strings"
|
|
|
|
|
2022-04-26 23:01:45 +00:00
|
|
|
http_util "github.com/zitadel/zitadel/internal/api/http"
|
|
|
|
"github.com/zitadel/zitadel/internal/crypto"
|
|
|
|
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
2023-12-08 14:30:55 +00:00
|
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
2021-01-08 10:33:45 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type OrgDomain struct {
|
|
|
|
models.ObjectRoot
|
|
|
|
|
|
|
|
Domain string
|
|
|
|
Primary bool
|
|
|
|
Verified bool
|
|
|
|
ValidationType OrgDomainValidationType
|
|
|
|
ValidationCode *crypto.CryptoValue
|
|
|
|
}
|
|
|
|
|
2021-01-18 10:24:15 +00:00
|
|
|
func (domain *OrgDomain) IsValid() bool {
|
2021-03-19 10:12:56 +00:00
|
|
|
return domain.Domain != ""
|
2021-01-18 10:24:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (domain *OrgDomain) GenerateVerificationCode(codeGenerator crypto.Generator) (string, error) {
|
|
|
|
validationCodeCrypto, validationCode, err := crypto.NewCode(codeGenerator)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
domain.ValidationCode = validationCodeCrypto
|
|
|
|
return validationCode, nil
|
|
|
|
}
|
|
|
|
|
2023-10-11 07:55:01 +00:00
|
|
|
func NewIAMDomainName(orgName, iamDomain string) (string, error) {
|
2023-07-18 12:42:57 +00:00
|
|
|
// Reference: label domain requirements https://www.nic.ad.jp/timeline/en/20th/appendix1.html
|
|
|
|
|
|
|
|
// Replaces spaces in org name with hyphens
|
|
|
|
label := strings.ReplaceAll(orgName, " ", "-")
|
|
|
|
|
|
|
|
// The label must only contains alphanumeric characters and hyphens
|
2023-10-11 07:55:01 +00:00
|
|
|
// Invalid characters are replaced with and empty space but as #6471,
|
|
|
|
// as these domains are not used to host ZITADEL, but only for user names,
|
|
|
|
// the characters shouldn't matter that much so we'll accept unicode
|
|
|
|
// characters, accented characters (\p{L}\p{M}), numbers and hyphens.
|
|
|
|
label = string(regexp.MustCompile(`[^\p{L}\p{M}0-9-]`).ReplaceAll([]byte(label), []byte("")))
|
2023-07-18 12:42:57 +00:00
|
|
|
|
|
|
|
// The label cannot exceed 63 characters
|
|
|
|
if len(label) > 63 {
|
|
|
|
label = label[:63]
|
|
|
|
}
|
|
|
|
|
|
|
|
// The total length of the resulting domain can't exceed 253 characters
|
|
|
|
domain := label + "." + iamDomain
|
|
|
|
if len(domain) > 253 {
|
|
|
|
truncateNChars := len(domain) - 253
|
|
|
|
label = label[:len(label)-truncateNChars]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Label (maybe truncated) can't start with a hyphen
|
|
|
|
if len(label) > 0 && label[0:1] == "-" {
|
|
|
|
label = label[1:]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Label (maybe truncated) can't end with a hyphen
|
|
|
|
if len(label) > 0 && label[len(label)-1:] == "-" {
|
|
|
|
label = label[:len(label)-1]
|
|
|
|
}
|
|
|
|
|
2023-10-11 07:55:01 +00:00
|
|
|
// Empty string should be invalid
|
|
|
|
if len(label) > 0 {
|
|
|
|
return strings.ToLower(label + "." + iamDomain), nil
|
|
|
|
}
|
|
|
|
|
2023-12-08 14:30:55 +00:00
|
|
|
return "", zerrors.ThrowInvalidArgument(nil, "ORG-RrfXY", "Errors.Org.Domain.EmptyString")
|
2021-04-19 14:43:36 +00:00
|
|
|
}
|
|
|
|
|
2021-01-08 10:33:45 +00:00
|
|
|
type OrgDomainValidationType int32
|
|
|
|
|
|
|
|
const (
|
|
|
|
OrgDomainValidationTypeUnspecified OrgDomainValidationType = iota
|
|
|
|
OrgDomainValidationTypeHTTP
|
|
|
|
OrgDomainValidationTypeDNS
|
|
|
|
)
|
|
|
|
|
2021-01-18 10:24:15 +00:00
|
|
|
func (t OrgDomainValidationType) CheckType() (http_util.CheckType, bool) {
|
|
|
|
switch t {
|
|
|
|
case OrgDomainValidationTypeHTTP:
|
|
|
|
return http_util.CheckTypeHTTP, true
|
|
|
|
case OrgDomainValidationTypeDNS:
|
|
|
|
return http_util.CheckTypeDNS, true
|
|
|
|
default:
|
|
|
|
return -1, false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-08 10:33:45 +00:00
|
|
|
type OrgDomainState int32
|
|
|
|
|
|
|
|
const (
|
|
|
|
OrgDomainStateUnspecified OrgDomainState = iota
|
|
|
|
OrgDomainStateActive
|
|
|
|
OrgDomainStateRemoved
|
|
|
|
|
|
|
|
orgDomainStateCount
|
|
|
|
)
|
|
|
|
|
|
|
|
func (f OrgDomainState) Valid() bool {
|
|
|
|
return f >= 0 && f < orgDomainStateCount
|
|
|
|
}
|