mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-07 21:27:35 +00:00
feat: Add CreateInstance endpoint (#9452)
This commit is contained in:
15
internal/api/grpc/authn/v2beta/converter.go
Normal file
15
internal/api/grpc/authn/v2beta/converter.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package authn
|
||||
|
||||
import (
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
authn "github.com/zitadel/zitadel/pkg/grpc/authn/v2beta"
|
||||
)
|
||||
|
||||
func KeyTypeToDomain(t authn.KeyType) domain.AuthNKeyType {
|
||||
switch t {
|
||||
case authn.KeyType_KEY_TYPE_JSON:
|
||||
return domain.AuthNKeyTypeJSON
|
||||
default:
|
||||
return domain.AuthNKeyTypeNONE
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,21 @@
|
||||
package instance
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||
"github.com/zitadel/zitadel/cmd/build"
|
||||
authn "github.com/zitadel/zitadel/internal/api/grpc/authn/v2beta"
|
||||
filter "github.com/zitadel/zitadel/internal/api/grpc/filter/v2beta"
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/object/v2"
|
||||
z_oidc "github.com/zitadel/zitadel/internal/api/oidc"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/instance/v2"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func InstancesToPb(instances []*query.Instance) []*instance.Instance {
|
||||
@@ -109,3 +117,126 @@ func instanceQueryToModel(searchQuery *instance.Query) (query.SearchQuery, error
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "INST-3m0se", "List.Query.Invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func CreateInstancePbToSetupInstance(req *instance.CreateInstanceRequest, defaultInstance command.InstanceSetup, externalDomain string) *command.InstanceSetup {
|
||||
instance := defaultInstance
|
||||
if req.InstanceName != "" {
|
||||
instance.InstanceName = req.InstanceName
|
||||
instance.Org.Name = req.InstanceName
|
||||
}
|
||||
if req.CustomDomain != "" {
|
||||
instance.CustomDomain = req.CustomDomain
|
||||
}
|
||||
if req.FirstOrgName != "" {
|
||||
instance.Org.Name = req.FirstOrgName
|
||||
}
|
||||
|
||||
if user := req.GetMachine(); user != nil {
|
||||
defaultMachine := instance.Org.Machine
|
||||
if defaultMachine == nil {
|
||||
defaultMachine = new(command.AddMachine)
|
||||
}
|
||||
|
||||
instance.Org.Machine = createInstancePbToAddMachine(user, *defaultMachine)
|
||||
instance.Org.Human = nil
|
||||
} else if user := req.GetHuman(); user != nil {
|
||||
defaultHuman := instance.Org.Human
|
||||
if instance.Org.Human != nil {
|
||||
defaultHuman = new(command.AddHuman)
|
||||
}
|
||||
|
||||
instance.Org.Human = createInstancePbToAddHuman(user, *defaultHuman, instance.DomainPolicy.UserLoginMustBeDomain, instance.Org.Name, externalDomain)
|
||||
instance.Org.Machine = nil
|
||||
}
|
||||
|
||||
if lang := language.Make(req.DefaultLanguage); !lang.IsRoot() {
|
||||
instance.DefaultLanguage = lang
|
||||
}
|
||||
|
||||
return &instance
|
||||
}
|
||||
|
||||
func createInstancePbToAddHuman(req *instance.CreateInstanceRequest_Human, defaultHuman command.AddHuman, userLoginMustBeDomain bool, org, externalDomain string) *command.AddHuman {
|
||||
user := defaultHuman
|
||||
if req.Email != nil {
|
||||
user.Email.Address = domain.EmailAddress(req.Email.Email)
|
||||
user.Email.Verified = req.Email.IsEmailVerified
|
||||
}
|
||||
if req.Profile != nil {
|
||||
if req.Profile.FirstName != "" {
|
||||
user.FirstName = req.Profile.FirstName
|
||||
}
|
||||
if req.Profile.LastName != "" {
|
||||
user.LastName = req.Profile.LastName
|
||||
}
|
||||
if req.Profile.PreferredLanguage != "" {
|
||||
lang, err := language.Parse(req.Profile.PreferredLanguage)
|
||||
if err == nil {
|
||||
user.PreferredLanguage = lang
|
||||
}
|
||||
}
|
||||
}
|
||||
// check if default username is email style or else append @<orgname>.<custom-domain>
|
||||
// this way we have the same value as before changing `UserLoginMustBeDomain` to false
|
||||
if !userLoginMustBeDomain && !strings.Contains(user.Username, "@") {
|
||||
orgDomain, _ := domain.NewIAMDomainName(org, externalDomain)
|
||||
user.Username = user.Username + "@" + orgDomain
|
||||
}
|
||||
if req.UserName != "" {
|
||||
user.Username = req.UserName
|
||||
}
|
||||
|
||||
if req.Password != nil {
|
||||
user.Password = req.Password.Password
|
||||
user.PasswordChangeRequired = req.Password.PasswordChangeRequired
|
||||
}
|
||||
return &user
|
||||
}
|
||||
|
||||
func createInstancePbToAddMachine(req *instance.CreateInstanceRequest_Machine, defaultMachine command.AddMachine) (machine *command.AddMachine) {
|
||||
machine = new(command.AddMachine)
|
||||
if defaultMachine.Machine != nil {
|
||||
machineCopy := *defaultMachine.Machine
|
||||
machine.Machine = &machineCopy
|
||||
} else {
|
||||
machine.Machine = new(command.Machine)
|
||||
}
|
||||
|
||||
if req.UserName != "" {
|
||||
machine.Machine.Username = req.UserName
|
||||
}
|
||||
if req.Name != "" {
|
||||
machine.Machine.Name = req.Name
|
||||
}
|
||||
|
||||
if defaultMachine.Pat != nil || req.PersonalAccessToken != nil {
|
||||
pat := command.AddPat{
|
||||
// Scopes are currently static and can not be overwritten
|
||||
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile, z_oidc.ScopeUserMetaData, z_oidc.ScopeResourceOwner},
|
||||
}
|
||||
if req.GetPersonalAccessToken().GetExpirationDate().IsValid() {
|
||||
pat.ExpirationDate = req.PersonalAccessToken.ExpirationDate.AsTime()
|
||||
} else if defaultMachine.Pat != nil && !defaultMachine.Pat.ExpirationDate.IsZero() {
|
||||
pat.ExpirationDate = defaultMachine.Pat.ExpirationDate
|
||||
}
|
||||
machine.Pat = &pat
|
||||
}
|
||||
|
||||
if defaultMachine.MachineKey != nil || req.MachineKey != nil {
|
||||
machineKey := command.AddMachineKey{}
|
||||
if defaultMachine.MachineKey != nil {
|
||||
machineKey = *defaultMachine.MachineKey
|
||||
}
|
||||
if req.MachineKey != nil {
|
||||
if req.MachineKey.Type != 0 {
|
||||
machineKey.Type = authn.KeyTypeToDomain(req.MachineKey.Type)
|
||||
}
|
||||
if req.MachineKey.ExpirationDate.IsValid() {
|
||||
machineKey.ExpirationDate = req.MachineKey.ExpirationDate.AsTime()
|
||||
}
|
||||
}
|
||||
machine.MachineKey = &machineKey
|
||||
}
|
||||
|
||||
return machine
|
||||
}
|
||||
|
||||
@@ -9,6 +9,28 @@ import (
|
||||
"github.com/zitadel/zitadel/pkg/grpc/instance/v2"
|
||||
)
|
||||
|
||||
func (s *Server) CreateInstance(ctx context.Context, req *instance.CreateInstanceRequest) (*instance.CreateInstanceResponse, error) {
|
||||
id, pat, key, details, err := s.command.SetUpInstance(ctx, CreateInstancePbToSetupInstance(req, s.defaultInstance, s.externalDomain))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var machineKey []byte
|
||||
if key != nil {
|
||||
machineKey, err = key.Detail()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &instance.CreateInstanceResponse{
|
||||
Pat: pat,
|
||||
MachineKey: machineKey,
|
||||
InstanceId: id,
|
||||
Details: object.DomainToDetailsPb(details),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) DeleteInstance(ctx context.Context, request *instance.DeleteInstanceRequest) (*instance.DeleteInstanceResponse, error) {
|
||||
instanceID := strings.TrimSpace(request.GetInstanceId())
|
||||
if err := validateParam(instanceID, "instance_id"); err != nil {
|
||||
|
||||
@@ -20,6 +20,8 @@ type Server struct {
|
||||
query *query.Queries
|
||||
checkPermission domain.PermissionCheck
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
defaultInstance command.InstanceSetup
|
||||
externalDomain string
|
||||
}
|
||||
|
||||
type Config struct{}
|
||||
@@ -29,12 +31,16 @@ func CreateServer(
|
||||
query *query.Queries,
|
||||
checkPermission domain.PermissionCheck,
|
||||
systemDefaults systemdefaults.SystemDefaults,
|
||||
defaultInstance command.InstanceSetup,
|
||||
externalDomain string,
|
||||
) *Server {
|
||||
return &Server{
|
||||
command: command,
|
||||
query: query,
|
||||
checkPermission: checkPermission,
|
||||
systemDefaults: systemDefaults,
|
||||
defaultInstance: defaultInstance,
|
||||
externalDomain: externalDomain,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user