feat: add domain verification (#560)

* feat: add domain verification

* add checks

* add and fix tests

* fix go.mod

* regenerate proto
This commit is contained in:
Livio Amstutz
2020-08-06 15:03:03 +02:00
committed by GitHub
parent f80367b49a
commit 7015b226ef
26 changed files with 15815 additions and 14883 deletions

View File

@@ -65,6 +65,26 @@ func (s *Server) AddMyOrgDomain(ctx context.Context, in *management.AddOrgDomain
return orgDomainFromModel(domain), nil
}
func (s *Server) GenerateMyOrgDomainValidation(ctx context.Context, in *management.OrgDomainValidationRequest) (*management.OrgDomainValidationResponse, error) {
token, url, err := s.org.GenerateMyOrgDomainValidation(ctx, orgDomainValidationToModel(in))
if err != nil {
return nil, err
}
return &management.OrgDomainValidationResponse{
Token: token,
Url: url,
}, nil
}
func (s *Server) ValidateMyOrgDomain(ctx context.Context, in *management.ValidateOrgDomainRequest) (*empty.Empty, error) {
err := s.org.ValidateMyOrgDomain(ctx, validateOrgDomainToModel(in))
return &empty.Empty{}, err
}
func (s *Server) SetMyPrimaryOrgDomain(ctx context.Context, in *management.PrimaryOrgDomainRequest) (*empty.Empty, error) {
err := s.org.SetMyPrimaryOrgDomain(ctx, primaryOrgDomainToModel(in))
return &empty.Empty{}, err
}
func (s *Server) RemoveMyOrgDomain(ctx context.Context, in *management.RemoveOrgDomainRequest) (*empty.Empty, error) {
err := s.org.RemoveMyOrgDomain(ctx, in.Domain)
return &empty.Empty{}, err

View File

@@ -68,6 +68,32 @@ func addOrgDomainToModel(domain *management.AddOrgDomainRequest) *org_model.OrgD
return &org_model.OrgDomain{Domain: domain.Domain}
}
func orgDomainValidationToModel(domain *management.OrgDomainValidationRequest) *org_model.OrgDomain {
return &org_model.OrgDomain{
Domain: domain.Domain,
ValidationType: orgDomainValidationTypeToModel(domain.Type),
}
}
func validateOrgDomainToModel(domain *management.ValidateOrgDomainRequest) *org_model.OrgDomain {
return &org_model.OrgDomain{Domain: domain.Domain}
}
func orgDomainValidationTypeToModel(key management.OrgDomainValidationType) org_model.OrgDomainValidationType {
switch key {
case management.OrgDomainValidationType_ORGDOMAINVALIDATIONTYPE_HTTP:
return org_model.OrgDomainValidationTypeHTTP
case management.OrgDomainValidationType_ORGDOMAINVALIDATIONTYPE_DNS:
return org_model.OrgDomainValidationTypeDNS
default:
return org_model.OrgDomainValidationTypeUnspecified
}
}
func primaryOrgDomainToModel(domain *management.PrimaryOrgDomainRequest) *org_model.OrgDomain {
return &org_model.OrgDomain{Domain: domain.Domain}
}
func orgDomainFromModel(domain *org_model.OrgDomain) *management.OrgDomain {
creationDate, err := ptypes.TimestampProto(domain.CreationDate)
logging.Log("GRPC-u8Ksj").OnError(err).Debug("unable to get timestamp from time")

View File

@@ -0,0 +1,83 @@
package http
import (
"fmt"
"io/ioutil"
"net"
"net/http"
"github.com/caos/zitadel/internal/errors"
)
type CheckType int
const (
CheckTypeHTTP CheckType = iota
CheckTypeDNS
HTTPPattern = "https://%s/.well-known/zitadel-challenge/%s"
DNSPattern = "_zitadel-challenge.%s"
)
func ValidateDomain(domain, token, verifier string, checkType CheckType) error {
switch checkType {
case CheckTypeHTTP:
return ValidateDomainHTTP(domain, token, verifier)
case CheckTypeDNS:
return ValidateDomainDNS(domain, verifier)
default:
return errors.ThrowInvalidArgument(nil, "HTTP-Iqd11", "Errors.Internal")
}
}
func ValidateDomainHTTP(domain, token, verifier string) error {
resp, err := http.Get(tokenUrlHTTP(domain, token))
if err != nil {
return errors.ThrowInternal(err, "HTTP-BH42h", "Errors.Internal")
}
if resp.StatusCode != 200 {
return errors.ThrowInternal(err, "HTTP-G2zsw", "Errors.Internal")
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return errors.ThrowInternal(err, "HTTP-HB432", "Errors.Internal")
}
if string(body) == verifier {
return nil
}
return errors.ThrowInvalidArgument(err, "HTTP-GH422", "Errors.Internal")
}
func ValidateDomainDNS(domain, verifier string) error {
txtRecords, err := net.LookupTXT(tokenUrlDNS(domain))
if err != nil {
return errors.ThrowInternal(err, "HTTP-Hwsw2", "Errors.Internal")
}
for _, record := range txtRecords {
if record == verifier {
return nil
}
}
return errors.ThrowInvalidArgument(err, "HTTP-G241f", "Errors.Internal")
}
func TokenUrl(domain, token string, checkType CheckType) (string, error) {
switch checkType {
case CheckTypeHTTP:
return tokenUrlHTTP(domain, token), nil
case CheckTypeDNS:
return tokenUrlDNS(domain), nil
default:
return "", errors.ThrowInvalidArgument(nil, "HTTP-Iqd11", "")
}
}
func tokenUrlHTTP(domain, token string) string {
return fmt.Sprintf(HTTPPattern, domain, token)
}
func tokenUrlDNS(domain string) string {
return fmt.Sprintf(DNSPattern, domain)
}