mirror of
https://github.com/openziti/ziti.git
synced 2026-09-10 08:45:41 +00:00
aff1038519
- withholds an enrollment's token and jwt from a non-admin caller when the owning identity is an admin, in the identity detail mapper and the enrollment mapper - scopes the identity enrollments subresource so a non-admin does not see enrollments of admin identities, matching the top level /enrollments list - threads the request context into MapIdentityToRestModel and MapEnrollmentToRestModel so the mappers can see the caller's permissions - adds an integration test over the identity detail, identity list, and identity enrollments routes for every enrollment method - adds the advisory to the 2.1.0 changelog
918 lines
30 KiB
Go
918 lines
30 KiB
Go
package tests
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/go-openapi/strfmt"
|
|
"github.com/google/uuid"
|
|
"github.com/openziti/edge-api/rest_management_api_client/auth_policy"
|
|
managementAuthenticator "github.com/openziti/edge-api/rest_management_api_client/authenticator"
|
|
"github.com/openziti/edge-api/rest_management_api_client/certificate_authority"
|
|
managementConfig "github.com/openziti/edge-api/rest_management_api_client/config"
|
|
managementCurrentApiSession "github.com/openziti/edge-api/rest_management_api_client/current_api_session"
|
|
managementCurrentIdentity "github.com/openziti/edge-api/rest_management_api_client/current_identity"
|
|
managementEdgeRouter "github.com/openziti/edge-api/rest_management_api_client/edge_router"
|
|
managementEnrollment "github.com/openziti/edge-api/rest_management_api_client/enrollment"
|
|
"github.com/openziti/edge-api/rest_management_api_client/external_jwt_signer"
|
|
managementIdentity "github.com/openziti/edge-api/rest_management_api_client/identity"
|
|
managementInformational "github.com/openziti/edge-api/rest_management_api_client/informational"
|
|
managementPostureChecks "github.com/openziti/edge-api/rest_management_api_client/posture_checks"
|
|
managementRevocation "github.com/openziti/edge-api/rest_management_api_client/revocation"
|
|
"github.com/openziti/edge-api/rest_model"
|
|
"github.com/openziti/edge-api/rest_util"
|
|
edgeApis "github.com/openziti/sdk-golang/v2/edge-apis"
|
|
"github.com/openziti/ziti/v2/common"
|
|
"github.com/openziti/ziti/v2/common/eid"
|
|
"github.com/openziti/ziti/v2/ziti/util"
|
|
)
|
|
|
|
type ManagementHelperClient struct {
|
|
*edgeApis.ManagementApiClient
|
|
testCtx *TestContext
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetVersion() (*rest_model.Version, error) {
|
|
resp, err := helper.GetVersionResponse()
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetVersionResponse() (*managementInformational.ListVersionOK, error) {
|
|
getVersionParams := managementInformational.NewListVersionParams()
|
|
|
|
resp, err := helper.API.Informational.ListVersion(getVersionParams)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to retrieve version information: %w", rest_util.WrapErr(err))
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateAndEnrollOttIdentity(isAdmin bool, roleAttributes ...string) (*rest_model.IdentityDetail, *edgeApis.CertCredentials, error) {
|
|
return helper.CreateAndEnrollOttIdentityWithPermissions(isAdmin, nil, roleAttributes...)
|
|
}
|
|
|
|
// CreateAndEnrollOttIdentityWithPermissions creates an identity carrying the given management
|
|
// permissions, such as "identity.read" or "enrollment", completes its ott enrollment, and returns
|
|
// the identity along with the certificate credentials it enrolled with.
|
|
func (helper *ManagementHelperClient) CreateAndEnrollOttIdentityWithPermissions(isAdmin bool, permissions []string, roleAttributes ...string) (*rest_model.IdentityDetail, *edgeApis.CertCredentials, error) {
|
|
idLoc, err := helper.CreateIdentityWithPermissions(uuid.NewString(), isAdmin, permissions, roleAttributes...)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("failed to create identity: %w", err)
|
|
}
|
|
expiresAt := time.Now().Add(1 * time.Hour)
|
|
|
|
ottEnrollLoc, err := helper.CreateEnrollmentOtt(&idLoc.ID, &expiresAt)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("failed to create ott enrollment: %w", err)
|
|
}
|
|
|
|
ottEnrollment, err := helper.GetEnrollment(ottEnrollLoc.ID)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("failed to get enrollment: %w", err)
|
|
}
|
|
|
|
clientClient := helper.testCtx.NewEdgeClientApi(nil)
|
|
ottCreds, err := clientClient.CompleteOttEnrollment(*ottEnrollment.Token)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("failed to complete ott enrollment: %w", err)
|
|
}
|
|
|
|
identityDetail, err := helper.GetIdentity(idLoc.ID)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("failed to get identity: %w", err)
|
|
}
|
|
|
|
return identityDetail, ottCreds, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateIdentity(name string, isAdmin bool, roleAttributes ...string) (*rest_model.CreateLocation, error) {
|
|
return helper.CreateIdentityWithPermissions(name, isAdmin, nil, roleAttributes...)
|
|
}
|
|
|
|
// CreateIdentityWithPermissions creates an identity carrying the given management permissions, such
|
|
// as "identity.read" or "enrollment". A nil or empty slice leaves the identity with none.
|
|
func (helper *ManagementHelperClient) CreateIdentityWithPermissions(name string, isAdmin bool, permissions []string, roleAttributes ...string) (*rest_model.CreateLocation, error) {
|
|
newIdentity := &rest_model.IdentityCreate{
|
|
Name: ToPtr(name),
|
|
Type: ToPtr(rest_model.IdentityTypeDefault),
|
|
IsAdmin: ToPtr(isAdmin),
|
|
RoleAttributes: ToPtr(rest_model.Attributes(roleAttributes)),
|
|
Permissions: ToPtr(rest_model.Permissions(permissions)),
|
|
}
|
|
|
|
newIdentityParams := &managementIdentity.CreateIdentityParams{
|
|
Identity: newIdentity,
|
|
}
|
|
|
|
resp, err := helper.API.Identity.CreateIdentity(newIdentityParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// CreateConfigType creates a config type with a generated name and the given target.
|
|
func (helper *ManagementHelperClient) CreateConfigType(target *string) (*rest_model.CreateLocation, error) {
|
|
params := &managementConfig.CreateConfigTypeParams{
|
|
ConfigType: &rest_model.ConfigTypeCreate{
|
|
Name: ToPtr(eid.New()),
|
|
Target: target,
|
|
},
|
|
}
|
|
|
|
resp, err := helper.API.Config.CreateConfigType(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// CreateConfig creates a config with a generated name for the given config type.
|
|
func (helper *ManagementHelperClient) CreateConfig(configTypeId string, data interface{}) (*rest_model.CreateLocation, error) {
|
|
params := &managementConfig.CreateConfigParams{
|
|
Config: &rest_model.ConfigCreate{
|
|
Name: ToPtr(eid.New()),
|
|
ConfigTypeID: &configTypeId,
|
|
Data: data,
|
|
},
|
|
}
|
|
|
|
resp, err := helper.API.Config.CreateConfig(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// ListEnumeratedRouterCapabilities returns every router capability the controller advertises via
|
|
// the enumerated-router-capabilities endpoint.
|
|
func (helper *ManagementHelperClient) ListEnumeratedRouterCapabilities() ([]rest_model.RouterCapabilities, error) {
|
|
resp, err := helper.API.Informational.ListEnumeratedRouterCapabilities(managementInformational.NewListEnumeratedRouterCapabilitiesParams(), nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// GetEdgeRouter returns the management-API detail for the edge router with the given id.
|
|
func (helper *ManagementHelperClient) GetEdgeRouter(edgeRouterId string) (*rest_model.EdgeRouterDetail, error) {
|
|
resp, err := helper.API.EdgeRouter.DetailEdgeRouter(&managementEdgeRouter.DetailEdgeRouterParams{
|
|
ID: edgeRouterId,
|
|
}, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetIdentity(identityId string) (*rest_model.IdentityDetail, error) {
|
|
getParams := &managementIdentity.DetailIdentityParams{
|
|
ID: identityId,
|
|
}
|
|
|
|
resp, err := helper.API.Identity.DetailIdentity(getParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// ListIdentitiesByFilter returns all identities matching the supplied ziti filter expression.
|
|
func (helper *ManagementHelperClient) ListIdentitiesByFilter(filter string) ([]*rest_model.IdentityDetail, error) {
|
|
resp, err := helper.API.Identity.ListIdentities(&managementIdentity.ListIdentitiesParams{
|
|
Filter: &filter,
|
|
}, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// RequireIdentitySdkInfoUpdated polls until the identity reports appId as its SDK app id, returning the
|
|
// identity as read and failing the test if it does not appear within 10 seconds. The controller applies
|
|
// sdk/env info updates on a background queue, so they are not guaranteed to be visible by the time
|
|
// authentication returns.
|
|
func (helper *ManagementHelperClient) RequireIdentitySdkInfoUpdated(identityId string, appId string) *rest_model.IdentityDetail {
|
|
var identityDetail *rest_model.IdentityDetail
|
|
helper.testCtx.Req.Eventually(func() bool {
|
|
var err error
|
|
identityDetail, err = helper.GetIdentity(identityId)
|
|
return err == nil && identityDetail.SdkInfo != nil && identityDetail.SdkInfo.AppID == appId
|
|
}, 10*time.Second, 50*time.Millisecond, "identity %s sdk info was not updated", identityId)
|
|
|
|
return identityDetail
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateEnrollmentOtt(identityId *string, expiresAt *time.Time) (*rest_model.CreateLocation, error) {
|
|
var expAt *strfmt.DateTime
|
|
|
|
if expiresAt != nil {
|
|
expAt = ToPtr(strfmt.DateTime(*expiresAt))
|
|
}
|
|
|
|
createParams := &managementEnrollment.CreateEnrollmentParams{
|
|
Enrollment: &rest_model.EnrollmentCreate{
|
|
IdentityID: identityId,
|
|
ExpiresAt: expAt,
|
|
Method: ToPtr(rest_model.EnrollmentCreateMethodOtt),
|
|
},
|
|
}
|
|
|
|
resp, err := helper.API.Enrollment.CreateEnrollment(createParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetEnrollment(enrollmentId string) (*rest_model.EnrollmentDetail, error) {
|
|
getParams := &managementEnrollment.DetailEnrollmentParams{
|
|
ID: enrollmentId,
|
|
}
|
|
|
|
resp, err := helper.API.Enrollment.DetailEnrollment(getParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// ListIdentityEnrollments returns the outstanding enrollments of an identity, as the
|
|
// /identities/{id}/enrollments subresource renders them for the calling session.
|
|
func (helper *ManagementHelperClient) ListIdentityEnrollments(identityId string) ([]*rest_model.EnrollmentDetail, error) {
|
|
resp, err := helper.API.Identity.GetIdentityEnrollments(&managementIdentity.GetIdentityEnrollmentsParams{
|
|
ID: identityId,
|
|
}, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// CreateOttCaEnabledCa creates a third-party CA with ott-ca enrollment enabled, generating its
|
|
// certificate, so that ott-ca enrollments can be created against it.
|
|
func (helper *ManagementHelperClient) CreateOttCaEnabledCa(name string) (*rest_model.CreateLocation, error) {
|
|
_, _, caPem := newTestCaCert()
|
|
|
|
resp, err := helper.API.CertificateAuthority.CreateCa(&certificate_authority.CreateCaParams{
|
|
Ca: &rest_model.CaCreate{
|
|
CertPem: ToPtr(caPem.String()),
|
|
IdentityRoles: rest_model.Roles{},
|
|
IsAuthEnabled: ToPtr(true),
|
|
IsAutoCaEnrollmentEnabled: ToPtr(true),
|
|
IsOttCaEnrollmentEnabled: ToPtr(true),
|
|
Name: ToPtr(name),
|
|
},
|
|
}, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateCa(testCa *ca) (*rest_model.CreateLocation, error) {
|
|
caCreate := &rest_model.CaCreate{
|
|
CertPem: &testCa.certPem,
|
|
IdentityNameFormat: testCa.identityNameFormat,
|
|
IdentityRoles: testCa.identityRoles,
|
|
IsAuthEnabled: &testCa.isAuthEnabled,
|
|
IsAutoCaEnrollmentEnabled: &testCa.isAutoCaEnrollmentEnabled,
|
|
IsOttCaEnrollmentEnabled: &testCa.isOttCaEnrollmentEnabled,
|
|
Name: &testCa.name,
|
|
}
|
|
|
|
createParams := &certificate_authority.CreateCaParams{
|
|
Ca: caCreate,
|
|
}
|
|
|
|
resp, err := helper.API.CertificateAuthority.CreateCa(createParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateEnrollmentOttCa(identityId *string, caId *string, expiresAt *time.Time) (*rest_model.CreateLocation, error) {
|
|
var expAt *strfmt.DateTime
|
|
|
|
if expiresAt != nil {
|
|
expAt = ToPtr(strfmt.DateTime(*expiresAt))
|
|
}
|
|
|
|
createParams := &managementEnrollment.CreateEnrollmentParams{
|
|
Enrollment: &rest_model.EnrollmentCreate{
|
|
IdentityID: identityId,
|
|
ExpiresAt: expAt,
|
|
CaID: caId,
|
|
Method: ToPtr(rest_model.EnrollmentCreateMethodOttca),
|
|
},
|
|
}
|
|
|
|
resp, err := helper.API.Enrollment.CreateEnrollment(createParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetCa(caId string) (*rest_model.CaDetail, error) {
|
|
getParams := &certificate_authority.DetailCaParams{
|
|
ID: caId,
|
|
}
|
|
|
|
resp, err := helper.API.CertificateAuthority.DetailCa(getParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) VerifyCa(id string, token string, cert *x509.Certificate, key crypto.Signer) error {
|
|
verifyCert, _, err := generateCaSignedClientCert(cert, key, token)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("could not generate verification certificate: %w", err)
|
|
}
|
|
|
|
verificationBlock := &pem.Block{
|
|
Type: "CERTIFICATE",
|
|
Bytes: verifyCert.Raw,
|
|
}
|
|
verifyPem := pem.EncodeToMemory(verificationBlock)
|
|
|
|
verifyParams := &certificate_authority.VerifyCaParams{
|
|
Certificate: string(verifyPem),
|
|
ID: id,
|
|
}
|
|
|
|
_, err = helper.API.CertificateAuthority.VerifyCa(verifyParams, nil)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("could not verify certificate: %w", rest_util.WrapErr(err))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateEnrollmentUpdb(identityId *string, username *string, expiresAt *time.Time) (*rest_model.CreateLocation, error) {
|
|
var expAt *strfmt.DateTime
|
|
|
|
if expiresAt != nil {
|
|
expAt = ToPtr(strfmt.DateTime(*expiresAt))
|
|
}
|
|
|
|
createParams := &managementEnrollment.CreateEnrollmentParams{
|
|
Enrollment: &rest_model.EnrollmentCreate{
|
|
IdentityID: identityId,
|
|
ExpiresAt: expAt,
|
|
Username: username,
|
|
Method: ToPtr(rest_model.EnrollmentCreateMethodUpdb),
|
|
},
|
|
}
|
|
|
|
resp, err := helper.API.Enrollment.CreateEnrollment(createParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetIdentityAuthenticators(identityId string) ([]*rest_model.AuthenticatorDetail, error) {
|
|
getIdAuthenticatorsParams := managementIdentity.NewGetIdentityAuthenticatorsParams()
|
|
getIdAuthenticatorsParams.ID = identityId
|
|
resp, err := helper.API.Identity.GetIdentityAuthenticators(getIdAuthenticatorsParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to retrieve identity authenticators: %w", rest_util.WrapErr(err))
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) RefreshEnrollmentJwt(id string) (*rest_model.EnrollmentDetail, error) {
|
|
refreshParams := &managementEnrollment.RefreshEnrollmentParams{
|
|
ID: id,
|
|
Refresh: &rest_model.EnrollmentRefresh{
|
|
ExpiresAt: ToPtr(strfmt.DateTime(time.Now().Add(time.Hour * 24))),
|
|
},
|
|
}
|
|
_, err := helper.API.Enrollment.RefreshEnrollment(refreshParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
detail, err := helper.GetEnrollment(id)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return detail, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetTotpMfa() (*rest_model.DetailMfa, error) {
|
|
params := &managementCurrentIdentity.DetailMfaParams{}
|
|
|
|
resp, err := helper.API.CurrentIdentity.DetailMfa(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get totp mfa: %w", util.WrapIfApiError(err))
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateTotpMfaEnrollment() (*rest_model.DetailMfa, error) {
|
|
params := &managementCurrentIdentity.EnrollMfaParams{}
|
|
|
|
_, err := helper.API.CurrentIdentity.EnrollMfa(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not create totp mfa enrollment: %w", util.WrapIfApiError(err))
|
|
}
|
|
|
|
return helper.GetTotpMfa()
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) VerifyTotpMfaEnrollment(code string) (*rest_model.DetailMfa, error) {
|
|
params := &managementCurrentIdentity.VerifyMfaParams{
|
|
MfaValidation: &rest_model.MfaCode{
|
|
Code: ToPtr(code),
|
|
},
|
|
}
|
|
|
|
_, err := helper.API.CurrentIdentity.VerifyMfa(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not verify totp mfa enrollment: %w", util.WrapIfApiError(err))
|
|
}
|
|
|
|
return helper.GetTotpMfa()
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) EnrollTotpMfa() (*TotpProvider, *rest_model.DetailMfa, error) {
|
|
totpMfaEnrollment, err := helper.CreateTotpMfaEnrollment()
|
|
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("could not create totp mfa enrollment: %w", err)
|
|
}
|
|
|
|
totpProvider := &TotpProvider{}
|
|
err = totpProvider.ApplyProvisioningUrl(totpMfaEnrollment.ProvisioningURL)
|
|
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("could not apply provisioning url: %w", err)
|
|
}
|
|
|
|
curCode := totpProvider.Code()
|
|
|
|
totpMfaEnrollment, err = helper.VerifyTotpMfaEnrollment(curCode)
|
|
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("could not verify totp mfa enrollment: %w", err)
|
|
}
|
|
|
|
return totpProvider, totpMfaEnrollment, err
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetTotpToken(code string) (*rest_model.TotpToken, error) {
|
|
params := managementCurrentApiSession.CreateTotpTokenParams{
|
|
MfaValidation: &rest_model.MfaCode{
|
|
Code: ToPtr(code),
|
|
},
|
|
}
|
|
|
|
resp, err := helper.API.CurrentAPISession.CreateTotpToken(¶ms, nil)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get totp token: %w", util.WrapIfApiError(err))
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetPostureCheck(id string) (rest_model.PostureCheckDetail, error) {
|
|
detailParams := managementPostureChecks.NewDetailPostureCheckParams()
|
|
detailParams.ID = id
|
|
|
|
detailResp, err := helper.API.PostureChecks.DetailPostureCheck(detailParams, nil)
|
|
if err != nil {
|
|
return nil, util.WrapIfApiError(err)
|
|
}
|
|
|
|
return detailResp.Payload.Data(), nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreatePostureCheck(check rest_model.PostureCheckCreate) (rest_model.PostureCheckDetail, error) {
|
|
createParams := managementPostureChecks.NewCreatePostureCheckParams()
|
|
createParams.PostureCheck = check
|
|
|
|
createResp, err := helper.API.PostureChecks.CreatePostureCheck(createParams, nil)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not create posture check: %w", util.WrapIfApiError(err))
|
|
}
|
|
|
|
postureCheckDetail, err := helper.GetPostureCheck(createResp.Payload.Data.ID)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get posture check detail: %w", util.WrapIfApiError(err))
|
|
}
|
|
|
|
return postureCheckDetail, nil
|
|
}
|
|
|
|
// PatchPostureCheck applies a partial update to a posture check by id.
|
|
func (helper *ManagementHelperClient) PatchPostureCheck(id string, patch rest_model.PostureCheckPatch) error {
|
|
patchParams := managementPostureChecks.NewPatchPostureCheckParams()
|
|
patchParams.ID = id
|
|
patchParams.PostureCheck = patch
|
|
|
|
if _, err := helper.API.PostureChecks.PatchPostureCheck(patchParams, nil); err != nil {
|
|
return fmt.Errorf("could not patch posture check: %w", util.WrapIfApiError(err))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreatePostureCheckOs(operatingSystems []*rest_model.OperatingSystem, attributes []string) (*rest_model.PostureCheckOperatingSystemDetail, error) {
|
|
newCheck := &rest_model.PostureCheckOperatingSystemCreate{
|
|
OperatingSystems: operatingSystems,
|
|
}
|
|
|
|
attrs := rest_model.Attributes(attributes)
|
|
newCheck.SetRoleAttributes(&attrs)
|
|
newCheck.SetName(ToPtr(eid.New()))
|
|
|
|
postureCheckDetail, err := helper.CreatePostureCheck(newCheck)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
checkDetail, ok := postureCheckDetail.(*rest_model.PostureCheckOperatingSystemDetail)
|
|
|
|
if !ok {
|
|
return nil, fmt.Errorf("posture check detail is not the right type, expected %T, got %T", checkDetail, postureCheckDetail)
|
|
}
|
|
|
|
return checkDetail, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreatePostureCheckMac(addresses []string, attributes []string) (*rest_model.PostureCheckMacAddressDetail, error) {
|
|
newCheck := &rest_model.PostureCheckMacAddressCreate{
|
|
MacAddresses: addresses,
|
|
}
|
|
|
|
attrs := rest_model.Attributes(attributes)
|
|
newCheck.SetRoleAttributes(&attrs)
|
|
newCheck.SetName(ToPtr(eid.New()))
|
|
|
|
postureCheckDetail, err := helper.CreatePostureCheck(newCheck)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
checkDetail, ok := postureCheckDetail.(*rest_model.PostureCheckMacAddressDetail)
|
|
|
|
if !ok {
|
|
return nil, fmt.Errorf("posture check detail is not the right type, expected %T, got %T", checkDetail, postureCheckDetail)
|
|
}
|
|
|
|
return checkDetail, nil
|
|
}
|
|
|
|
// CreatePostureCheckMfa creates an MFA posture check with the given timeout (-1 for no timeout)
|
|
// and wake/unlock prompt configuration, assigned the given role attributes.
|
|
func (helper *ManagementHelperClient) CreatePostureCheckMfa(timeoutSeconds int64, promptOnWake, promptOnUnlock bool, attributes []string) (*rest_model.PostureCheckMfaDetail, error) {
|
|
newCheck := &rest_model.PostureCheckMfaCreate{
|
|
PostureCheckMfaProperties: rest_model.PostureCheckMfaProperties{
|
|
TimeoutSeconds: timeoutSeconds,
|
|
PromptOnWake: promptOnWake,
|
|
PromptOnUnlock: promptOnUnlock,
|
|
},
|
|
}
|
|
|
|
attrs := rest_model.Attributes(attributes)
|
|
newCheck.SetRoleAttributes(&attrs)
|
|
newCheck.SetName(ToPtr(eid.New()))
|
|
|
|
postureCheckDetail, err := helper.CreatePostureCheck(newCheck)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
checkDetail, ok := postureCheckDetail.(*rest_model.PostureCheckMfaDetail)
|
|
|
|
if !ok {
|
|
return nil, fmt.Errorf("posture check detail is not the right type, expected %T, got %T", checkDetail, postureCheckDetail)
|
|
}
|
|
|
|
return checkDetail, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreatePostureCheckProcessMulti(processes []*rest_model.ProcessMulti, semantic rest_model.Semantic, attributes []string) (*rest_model.PostureCheckProcessMultiDetail, error) {
|
|
newCheck := &rest_model.PostureCheckProcessMultiCreate{
|
|
Processes: processes,
|
|
Semantic: &semantic,
|
|
}
|
|
|
|
attrs := rest_model.Attributes(attributes)
|
|
newCheck.SetRoleAttributes(&attrs)
|
|
newCheck.SetName(ToPtr(eid.New()))
|
|
|
|
postureCheckDetail, err := helper.CreatePostureCheck(newCheck)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
checkDetail, ok := postureCheckDetail.(*rest_model.PostureCheckProcessMultiDetail)
|
|
|
|
if !ok {
|
|
return nil, fmt.Errorf("posture check detail is not the right type, expected %T, got %T", checkDetail, postureCheckDetail)
|
|
}
|
|
|
|
return checkDetail, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreatePostureCheckProcess(process *rest_model.Process, attributes []string) (*rest_model.PostureCheckProcessDetail, error) {
|
|
newCheck := &rest_model.PostureCheckProcessCreate{
|
|
Process: process,
|
|
}
|
|
|
|
attrs := rest_model.Attributes(attributes)
|
|
newCheck.SetRoleAttributes(&attrs)
|
|
newCheck.SetName(ToPtr(eid.New()))
|
|
|
|
postureCheckDetail, err := helper.CreatePostureCheck(newCheck)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
checkDetail, ok := postureCheckDetail.(*rest_model.PostureCheckProcessDetail)
|
|
|
|
if !ok {
|
|
return nil, fmt.Errorf("posture check detail is not the right type, expected %T, got %T", checkDetail, postureCheckDetail)
|
|
}
|
|
|
|
return checkDetail, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateExtJwtSigner(extJwtSigner *rest_model.ExternalJWTSignerCreate) (*rest_model.ExternalJWTSignerDetail, error) {
|
|
params := external_jwt_signer.NewCreateExternalJWTSignerParams()
|
|
|
|
params.ExternalJWTSigner = extJwtSigner
|
|
|
|
resp, err := helper.API.ExternalJWTSigner.CreateExternalJWTSigner(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return helper.GetExtJwtSigner(resp.Payload.Data.ID)
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetExtJwtSigner(id string) (*rest_model.ExternalJWTSignerDetail, error) {
|
|
params := external_jwt_signer.NewDetailExternalJWTSignerParams()
|
|
|
|
params.ID = id
|
|
|
|
resp, err := helper.API.ExternalJWTSigner.DetailExternalJWTSigner(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateAuthPolicy(authPolicy *rest_model.AuthPolicyCreate) (*rest_model.AuthPolicyDetail, error) {
|
|
params := auth_policy.NewCreateAuthPolicyParams()
|
|
params.AuthPolicy = authPolicy
|
|
|
|
resp, err := helper.API.AuthPolicy.CreateAuthPolicy(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return helper.GetAuthPolicy(resp.Payload.Data.ID)
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetAuthPolicy(id string) (*rest_model.AuthPolicyDetail, error) {
|
|
params := auth_policy.NewDetailAuthPolicyParams()
|
|
params.ID = id
|
|
|
|
resp, err := helper.API.AuthPolicy.DetailAuthPolicy(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) PatchExtJwtSigner(id string, patch *rest_model.AuthPolicyPatch) (*rest_model.AuthPolicyDetail, error) {
|
|
params := auth_policy.NewPatchAuthPolicyParams()
|
|
params.ID = id
|
|
params.AuthPolicy = patch
|
|
|
|
_, err := helper.API.AuthPolicy.PatchAuthPolicy(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return helper.GetAuthPolicy(id)
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) PatchIdentity(id string, patch *rest_model.IdentityPatch) (*rest_model.IdentityDetail, error) {
|
|
params := managementIdentity.NewPatchIdentityParams()
|
|
params.ID = id
|
|
params.Identity = patch
|
|
|
|
_, err := helper.API.Identity.PatchIdentity(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return helper.GetIdentity(id)
|
|
}
|
|
|
|
// AuthenticateOidc sets the client to use OIDC, authenticates with the given
|
|
// credentials, and returns the OIDC API session. Returns an error if
|
|
// authentication fails or the session is not an OIDC session.
|
|
func (helper *ManagementHelperClient) AuthenticateOidc(creds edgeApis.Credentials) (*edgeApis.ApiSessionOidc, error) {
|
|
helper.SetUseOidc(true)
|
|
apiSession, err := helper.Authenticate(creds, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
oidcSession, ok := apiSession.(*edgeApis.ApiSessionOidc)
|
|
if !ok {
|
|
return nil, fmt.Errorf("expected *edge_apis.ApiSessionOidc, got %T", apiSession)
|
|
}
|
|
return oidcSession, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetCurrentApiSessionDetail() (*rest_model.CurrentAPISessionDetail, error) {
|
|
resp, err := helper.GetCurrentApiSessionDetailResponse()
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) GetCurrentApiSessionDetailResponse() (*managementCurrentApiSession.GetCurrentAPISessionOK, error) {
|
|
params := &managementCurrentApiSession.GetCurrentAPISessionParams{}
|
|
|
|
resp, err := helper.API.CurrentAPISession.GetCurrentAPISession(params, nil)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get current api session detail: %w", rest_util.WrapErr(err))
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
func (helper *ManagementHelperClient) CreateUpdbIdentityWithAuthPolicy(authPolicyId string) (*edgeApis.UpdbCredentials, error) {
|
|
username := eid.New()
|
|
password := eid.New()
|
|
|
|
createIdentityParams := managementIdentity.NewCreateIdentityParams()
|
|
createIdentityParams.Identity = &rest_model.IdentityCreate{
|
|
AuthPolicyID: ToPtr(authPolicyId),
|
|
IsAdmin: ToPtr(false),
|
|
Name: ToPtr(username),
|
|
Type: ToPtr(rest_model.IdentityTypeDefault),
|
|
}
|
|
createIdentityResp, err := helper.API.Identity.CreateIdentity(createIdentityParams, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not create identity: %w", rest_util.WrapErr(err))
|
|
}
|
|
|
|
createAuthenticatorParams := managementAuthenticator.NewCreateAuthenticatorParams()
|
|
createAuthenticatorParams.Authenticator = &rest_model.AuthenticatorCreate{
|
|
IdentityID: ToPtr(createIdentityResp.Payload.Data.ID),
|
|
Method: ToPtr("updb"),
|
|
Password: password,
|
|
Username: username,
|
|
}
|
|
_, err = helper.API.Authenticator.CreateAuthenticator(createAuthenticatorParams, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not create updb authenticator: %w", rest_util.WrapErr(err))
|
|
}
|
|
|
|
return edgeApis.NewUpdbCredentials(username, password), nil
|
|
}
|
|
|
|
// CreateRevocation creates a new revocation entry for the given id and type via the Management API.
|
|
func (helper *ManagementHelperClient) CreateRevocation(id string, revocationType rest_model.RevocationTypeEnum) (*rest_model.CreateLocation, error) {
|
|
params := managementRevocation.NewCreateRevocationParams()
|
|
params.Revocation = &rest_model.RevocationCreate{
|
|
ID: &id,
|
|
Type: &revocationType,
|
|
}
|
|
|
|
resp, err := helper.API.Revocation.CreateRevocation(params, nil)
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// ListRevocations retrieves all revocation entries via the Management API.
|
|
func (helper *ManagementHelperClient) ListRevocations() (rest_model.RevocationList, error) {
|
|
params := managementRevocation.NewListRevocationsParams()
|
|
|
|
resp, err := helper.API.Revocation.ListRevocations(params, nil)
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// GetRevocation retrieves a single revocation entry by its id via the Management API.
|
|
func (helper *ManagementHelperClient) GetRevocation(id string) (*rest_model.RevocationDetail, error) {
|
|
params := managementRevocation.NewDetailRevocationParams()
|
|
params.ID = id
|
|
|
|
resp, err := helper.API.Revocation.DetailRevocation(params, nil)
|
|
if err != nil {
|
|
return nil, rest_util.WrapErr(err)
|
|
}
|
|
|
|
return resp.Payload.Data, nil
|
|
}
|
|
|
|
// GetOidcAccessToken extracts the access token and its parsed claims from the
|
|
// client's current OIDC session. Returns an error if the session is not OIDC.
|
|
func (helper *ManagementHelperClient) GetOidcAccessToken() (string, *common.AccessClaims, error) {
|
|
currentSession := helper.GetCurrentApiSession()
|
|
oidcSess, ok := currentSession.(*edgeApis.ApiSessionOidc)
|
|
if !ok {
|
|
return "", nil, fmt.Errorf("expected OIDC session, got %T", currentSession)
|
|
}
|
|
return parseAccessToken(oidcSess.OidcTokens.AccessToken)
|
|
}
|
|
|
|
// NewEdgeManagementApiWithStaticToken creates a ManagementHelperClient that sends
|
|
// the given OIDC access token on every request. No refresh token is stored, so the
|
|
// token cannot be silently refreshed.
|
|
func (ctx *TestContext) NewEdgeManagementApiWithStaticToken(accessToken string) *ManagementHelperClient {
|
|
c := ctx.NewEdgeManagementApi(nil)
|
|
session := edgeApis.NewApiSessionOidc(accessToken, "")
|
|
var apiSession edgeApis.ApiSession = session
|
|
c.ApiSession.Store(&apiSession)
|
|
return c
|
|
}
|