mirror of
https://github.com/openziti/ziti.git
synced 2026-10-13 23:59:53 +00:00
Merge pull request #892 from openziti/add.updated.at.pq
alters posture query updateAt to also indicate query state changes
This commit is contained in:
@@ -194,6 +194,13 @@ func MapServiceToRestModel(ae *env.AppEnv, rc *response.RequestContext, service
|
||||
timeout := postureCheck.TimeoutSeconds()
|
||||
timeoutRemaining := postureCheck.TimeoutRemainingSeconds(rc.ApiSession.Id, ae.Handlers.PostureResponse.PostureData(rc.Identity.Id))
|
||||
|
||||
//determine if updatedAt is provided by the source posture check or the posture state
|
||||
if lastUpdatedAt := postureCheck.LastUpdatedAt(rc.ApiSession.Id, ae.Handlers.PostureResponse.PostureData(rc.Identity.Id)); lastUpdatedAt != nil {
|
||||
if lastUpdatedAt.After(postureCheck.UpdatedAt) {
|
||||
query.UpdatedAt = DateTimePtrOrNil(lastUpdatedAt)
|
||||
}
|
||||
|
||||
}
|
||||
query.IsPassing = &isCheckPassing
|
||||
query.TimeoutRemaining = &timeoutRemaining
|
||||
query.Timeout = &timeout
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"go.etcd.io/bbolt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PostureCheck struct {
|
||||
@@ -44,6 +45,9 @@ type PostureCheckSubType interface {
|
||||
FailureValues(_ string, pd *PostureData) PostureCheckFailureValues
|
||||
GetTimeoutSeconds() int64
|
||||
GetTimeoutRemainingSeconds(apiSessionId string, pd *PostureData) int64
|
||||
|
||||
// LastUpdatedAt returns the last time the posture state changed or nil if not supported.
|
||||
LastUpdatedAt(id string, pd *PostureData) *time.Time
|
||||
}
|
||||
|
||||
type PostureCheckFailureValues interface {
|
||||
@@ -149,3 +153,9 @@ func (entity *PostureCheck) TimeoutSeconds() int64 {
|
||||
func (entity *PostureCheck) TimeoutRemainingSeconds(apiSessionId string, pd *PostureData) int64 {
|
||||
return entity.SubType.GetTimeoutRemainingSeconds(apiSessionId, pd)
|
||||
}
|
||||
|
||||
// LastUpdatedAt returns the last time posture state changed for a specific posture check.
|
||||
// If the posture state does not report changes, nil is returned.
|
||||
func (entity *PostureCheck) LastUpdatedAt(apiSessionId string, pd *PostureData) *time.Time {
|
||||
return entity.SubType.LastUpdatedAt(apiSessionId, pd)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/openziti/edge/controller/persistence"
|
||||
"go.etcd.io/bbolt"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ PostureCheckSubType = &PostureCheckMacAddresses{}
|
||||
@@ -27,6 +28,11 @@ var _ PostureCheckSubType = &PostureCheckMacAddresses{}
|
||||
type PostureCheckMacAddresses struct {
|
||||
MacAddresses []string
|
||||
}
|
||||
|
||||
func (p *PostureCheckMacAddresses) LastUpdatedAt(apiSessionId string, pd *PostureData) *time.Time {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PostureCheckMacAddresses) GetTimeoutRemainingSeconds(_ string, _ *PostureData) int64 {
|
||||
return PostureCheckNoTimeout
|
||||
}
|
||||
@@ -37,8 +43,8 @@ func (p *PostureCheckMacAddresses) GetTimeoutSeconds() int64 {
|
||||
|
||||
func (p *PostureCheckMacAddresses) FailureValues(_ string, pd *PostureData) PostureCheckFailureValues {
|
||||
return &PostureCheckFailureValuesMac{
|
||||
ActualValue: pd.Mac.Addresses,
|
||||
ExpectedValue: p.MacAddresses,
|
||||
ActualValue: pd.Mac.Addresses,
|
||||
ExpectedValue: p.MacAddresses,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,4 +111,4 @@ func (p PostureCheckFailureValuesMac) Expected() interface{} {
|
||||
|
||||
func (p PostureCheckFailureValuesMac) Actual() interface{} {
|
||||
return p.ActualValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,29 @@ type PostureCheckMfa struct {
|
||||
IgnoreLegacyEndpoints bool
|
||||
}
|
||||
|
||||
func (p *PostureCheckMfa) LastUpdatedAt(apiSessionId string, pd *PostureData) *time.Time {
|
||||
apiSessionData := pd.ApiSessions[apiSessionId]
|
||||
|
||||
//not enough data yet
|
||||
if apiSessionData == nil || apiSessionData.Mfa == nil || apiSessionData.EndpointState == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var ret *time.Time = nil
|
||||
|
||||
if p.PromptOnWake && apiSessionData.EndpointState.WokenAt != nil {
|
||||
ret = apiSessionData.EndpointState.WokenAt
|
||||
}
|
||||
|
||||
if p.PromptOnUnlock && apiSessionData.EndpointState.UnlockedAt != nil {
|
||||
if ret == nil || apiSessionData.EndpointState.UnlockedAt.After(*ret) {
|
||||
ret = apiSessionData.EndpointState.UnlockedAt
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *PostureCheckMfa) IsLegacyClient(apiSessionData *ApiSessionPostureData) bool {
|
||||
if apiSessionData.SdkInfo == nil {
|
||||
return true // don't know what it is
|
||||
@@ -154,7 +177,7 @@ func (p *PostureCheckMfa) FailureValues(apiSessionId string, pd *PostureData) Po
|
||||
}
|
||||
|
||||
ret.Criteria.TimeoutSeconds = p.GetTimeoutSeconds()
|
||||
|
||||
|
||||
if apiSessionData, ok := pd.ApiSessions[apiSessionId]; ok {
|
||||
if apiSessionData.Mfa != nil {
|
||||
ret.ActualValue.TimedOutSeconds = apiSessionData.Mfa.TimedOut
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/openziti/foundation/util/errorz"
|
||||
"go.etcd.io/bbolt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ PostureCheckSubType = &PostureCheckOperatingSystem{}
|
||||
@@ -32,6 +33,10 @@ type PostureCheckOperatingSystem struct {
|
||||
OperatingSystems []OperatingSystem
|
||||
}
|
||||
|
||||
func (p *PostureCheckOperatingSystem) LastUpdatedAt(id string, pd *PostureData) *time.Time {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PostureCheckOperatingSystem) GetTimeoutRemainingSeconds(_ string, _ *PostureData) int64 {
|
||||
return PostureCheckNoTimeout
|
||||
}
|
||||
@@ -42,7 +47,7 @@ func (p *PostureCheckOperatingSystem) GetTimeoutSeconds() int64 {
|
||||
|
||||
func (p *PostureCheckOperatingSystem) FailureValues(_ string, pd *PostureData) PostureCheckFailureValues {
|
||||
return &PostureCheckFailureValuesOperatingSystem{
|
||||
ActualValue: pd.Os,
|
||||
ActualValue: pd.Os,
|
||||
ExpectedValue: p.OperatingSystems,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/openziti/edge/controller/persistence"
|
||||
"go.etcd.io/bbolt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ PostureCheckSubType = &PostureCheckProcess{}
|
||||
@@ -33,6 +34,10 @@ type PostureCheckProcess struct {
|
||||
Fingerprint string
|
||||
}
|
||||
|
||||
func (p *PostureCheckProcess) LastUpdatedAt(id string, pd *PostureData) *time.Time {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PostureCheckProcess) GetTimeoutSeconds() int64 {
|
||||
return PostureCheckNoTimeout
|
||||
}
|
||||
@@ -159,4 +164,4 @@ func (p PostureCheckFailureValuesProcess) Expected() interface{} {
|
||||
|
||||
func (p PostureCheckFailureValuesProcess) Actual() interface{} {
|
||||
return p.ActualValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/michaelquigley/pfxlog"
|
||||
"github.com/openziti/edge/controller/persistence"
|
||||
"go.etcd.io/bbolt"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ PostureCheckSubType = &PostureCheckProcessMulti{}
|
||||
@@ -32,6 +33,10 @@ type PostureCheckProcessMulti struct {
|
||||
Processes []*ProcessMulti
|
||||
}
|
||||
|
||||
func (p *PostureCheckProcessMulti) LastUpdatedAt(id string, pd *PostureData) *time.Time {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PostureCheckProcessMulti) GetTimeoutSeconds() int64 {
|
||||
return PostureCheckNoTimeout
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/openziti/edge/controller/persistence"
|
||||
"go.etcd.io/bbolt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ PostureCheckSubType = &PostureCheckDomains{}
|
||||
@@ -29,6 +30,10 @@ type PostureCheckDomains struct {
|
||||
Domains []string
|
||||
}
|
||||
|
||||
func (p *PostureCheckDomains) LastUpdatedAt(id string, pd *PostureData) *time.Time {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PostureCheckDomains) GetTimeoutSeconds() int64 {
|
||||
return PostureCheckNoTimeout
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const (
|
||||
|
||||
type PostureResponseMfa struct {
|
||||
*PostureResponse
|
||||
ApiSessionId string `json:"-"`
|
||||
ApiSessionId string `json:"-"`
|
||||
PassedMfaAt *time.Time `json:"passedMfaAt"`
|
||||
}
|
||||
|
||||
|
||||
@@ -4293,10 +4293,10 @@ func init() {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"error"
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"error": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/detailMfa"
|
||||
},
|
||||
"meta": {
|
||||
@@ -10006,10 +10006,10 @@ func init() {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"error"
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"error": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/detailMfa"
|
||||
},
|
||||
"meta": {
|
||||
|
||||
@@ -16445,10 +16445,10 @@ func init() {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"error"
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"error": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/detailMfa"
|
||||
},
|
||||
"meta": {
|
||||
@@ -37024,10 +37024,10 @@ func init() {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"error"
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"error": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/detailMfa"
|
||||
},
|
||||
"meta": {
|
||||
|
||||
@@ -43,9 +43,9 @@ import (
|
||||
// swagger:model detailMfaEnvelope
|
||||
type DetailMfaEnvelope struct {
|
||||
|
||||
// error
|
||||
// data
|
||||
// Required: true
|
||||
Error *DetailMfa `json:"error"`
|
||||
Data *DetailMfa `json:"data"`
|
||||
|
||||
// meta
|
||||
// Required: true
|
||||
@@ -56,7 +56,7 @@ type DetailMfaEnvelope struct {
|
||||
func (m *DetailMfaEnvelope) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateError(formats); err != nil {
|
||||
if err := m.validateData(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
@@ -70,18 +70,18 @@ func (m *DetailMfaEnvelope) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *DetailMfaEnvelope) validateError(formats strfmt.Registry) error {
|
||||
func (m *DetailMfaEnvelope) validateData(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("error", "body", m.Error); err != nil {
|
||||
if err := validate.Required("data", "body", m.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Error != nil {
|
||||
if err := m.Error.Validate(formats); err != nil {
|
||||
if m.Data != nil {
|
||||
if err := m.Data.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("error")
|
||||
return ve.ValidateName("data")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("error")
|
||||
return ce.ValidateName("data")
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -114,7 +114,7 @@ func (m *DetailMfaEnvelope) validateMeta(formats strfmt.Registry) error {
|
||||
func (m *DetailMfaEnvelope) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateError(ctx, formats); err != nil {
|
||||
if err := m.contextValidateData(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
@@ -128,14 +128,14 @@ func (m *DetailMfaEnvelope) ContextValidate(ctx context.Context, formats strfmt.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *DetailMfaEnvelope) contextValidateError(ctx context.Context, formats strfmt.Registry) error {
|
||||
func (m *DetailMfaEnvelope) contextValidateData(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Error != nil {
|
||||
if err := m.Error.ContextValidate(ctx, formats); err != nil {
|
||||
if m.Data != nil {
|
||||
if err := m.Data.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("error")
|
||||
return ve.ValidateName("data")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("error")
|
||||
return ce.ValidateName("data")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -44,8 +44,12 @@ import (
|
||||
type DialBind string
|
||||
|
||||
func NewDialBind(value DialBind) *DialBind {
|
||||
v := value
|
||||
return &v
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated DialBind.
|
||||
func (m DialBind) Pointer() *DialBind {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -44,8 +44,12 @@ import (
|
||||
type IdentityType string
|
||||
|
||||
func NewIdentityType(value IdentityType) *IdentityType {
|
||||
v := value
|
||||
return &v
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated IdentityType.
|
||||
func (m IdentityType) Pointer() *IdentityType {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -53,6 +53,11 @@ func (m Links) Validate(formats strfmt.Registry) error {
|
||||
}
|
||||
if val, ok := m[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName(k)
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName(k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,11 @@ func (m ListProtocols) Validate(formats strfmt.Registry) error {
|
||||
}
|
||||
if val, ok := m[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName(k)
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName(k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,12 @@ import (
|
||||
type MfaFormats string
|
||||
|
||||
func NewMfaFormats(value MfaFormats) *MfaFormats {
|
||||
v := value
|
||||
return &v
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated MfaFormats.
|
||||
func (m MfaFormats) Pointer() *MfaFormats {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -44,8 +44,12 @@ import (
|
||||
type MfaProviders string
|
||||
|
||||
func NewMfaProviders(value MfaProviders) *MfaProviders {
|
||||
v := value
|
||||
return &v
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated MfaProviders.
|
||||
func (m MfaProviders) Pointer() *MfaProviders {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -44,8 +44,12 @@ import (
|
||||
type OsType string
|
||||
|
||||
func NewOsType(value OsType) *OsType {
|
||||
v := value
|
||||
return &v
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated OsType.
|
||||
func (m OsType) Pointer() *OsType {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -44,8 +44,12 @@ import (
|
||||
type PostureCheckType string
|
||||
|
||||
func NewPostureCheckType(value PostureCheckType) *PostureCheckType {
|
||||
v := value
|
||||
return &v
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated PostureCheckType.
|
||||
func (m PostureCheckType) Pointer() *PostureCheckType {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -108,6 +108,11 @@ func (m *PostureData) validateAPISessionPostureData(formats strfmt.Registry) err
|
||||
}
|
||||
if val, ok := m.APISessionPostureData[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("apiSessionPostureData" + "." + k)
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("apiSessionPostureData" + "." + k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,12 @@ import (
|
||||
type Semantic string
|
||||
|
||||
func NewSemantic(value Semantic) *Semantic {
|
||||
v := value
|
||||
return &v
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated Semantic.
|
||||
func (m Semantic) Pointer() *Semantic {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -53,6 +53,11 @@ func (m TerminatorCostMap) Validate(formats strfmt.Registry) error {
|
||||
}
|
||||
if val, ok := m[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName(k)
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName(k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,12 @@ import (
|
||||
type TerminatorPrecedence string
|
||||
|
||||
func NewTerminatorPrecedence(value TerminatorPrecedence) *TerminatorPrecedence {
|
||||
v := value
|
||||
return &v
|
||||
return &value
|
||||
}
|
||||
|
||||
// Pointer returns a pointer to a freshly-allocated TerminatorPrecedence.
|
||||
func (m TerminatorPrecedence) Pointer() *TerminatorPrecedence {
|
||||
return &m
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -49,6 +49,11 @@ func (m TerminatorPrecedenceMap) Validate(formats strfmt.Registry) error {
|
||||
|
||||
if val, ok := m[k]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName(k)
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName(k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,11 @@ func (m *Version) validateAPIVersions(formats strfmt.Registry) error {
|
||||
}
|
||||
if val, ok := m.APIVersions[k][kk]; ok {
|
||||
if err := val.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("apiVersions" + "." + k + "." + kk)
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("apiVersions" + "." + k + "." + kk)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -3128,9 +3128,9 @@ definitions:
|
||||
type: object
|
||||
required:
|
||||
- meta
|
||||
- error
|
||||
- data
|
||||
properties:
|
||||
error:
|
||||
data:
|
||||
$ref: '#/definitions/detailMfa'
|
||||
meta:
|
||||
$ref: '#/definitions/meta'
|
||||
|
||||
@@ -11870,9 +11870,9 @@ definitions:
|
||||
type: object
|
||||
required:
|
||||
- meta
|
||||
- error
|
||||
- data
|
||||
properties:
|
||||
error:
|
||||
data:
|
||||
$ref: '#/definitions/detailMfa'
|
||||
meta:
|
||||
$ref: '#/definitions/meta'
|
||||
|
||||
@@ -228,11 +228,11 @@ definitions:
|
||||
type: object
|
||||
required:
|
||||
- meta
|
||||
- error
|
||||
- data
|
||||
properties:
|
||||
meta:
|
||||
$ref: 'standard-responses.yml#/definitions/meta'
|
||||
error:
|
||||
data:
|
||||
$ref: '#/definitions/detailMfa'
|
||||
detailMfa:
|
||||
type: object
|
||||
|
||||
@@ -20,14 +20,13 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/Jeffail/gabs"
|
||||
"github.com/michaelquigley/pfxlog"
|
||||
"github.com/openziti/foundation/util/errorz"
|
||||
"github.com/openziti/foundation/util/stringz"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/Jeffail/gabs"
|
||||
"github.com/michaelquigley/pfxlog"
|
||||
)
|
||||
|
||||
func (ctx *TestContext) setJsonValue(container *gabs.Container, value interface{}, path ...string) {
|
||||
|
||||
+241
-119
@@ -20,9 +20,7 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/Jeffail/gabs"
|
||||
"github.com/google/uuid"
|
||||
"github.com/openziti/edge/eid"
|
||||
"github.com/openziti/edge/rest_model"
|
||||
@@ -72,11 +70,21 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.Req.NoError(err)
|
||||
resp, err := ctx.AdminManagementSession.newAuthenticatedRequest().SetBody(postureCheckJson).Post("/posture-checks")
|
||||
ctx.Req.NoError(err)
|
||||
standardJsonResponseTests(resp, http.StatusCreated, t)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
|
||||
postureCheckId := ctx.getEntityId(resp.Body())
|
||||
ctx.Req.NotEmpty(postureCheckId)
|
||||
|
||||
resp, err = ctx.AdminManagementSession.newAuthenticatedRequest().Get("/posture-checks/" + postureCheckId)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
responseEnvelope := rest_model.DetailPostureCheckEnvelope{}
|
||||
|
||||
err = responseEnvelope.UnmarshalJSON(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
postureCheckDetail := responseEnvelope.Data().(*rest_model.PostureCheckMfaDetail)
|
||||
|
||||
ctx.AdminManagementSession.requireNewServicePolicyWithSemantic("Dial", "AllOf", s("#"+serviceRole), s("#"+identityRole), s("#"+postureCheckRole))
|
||||
|
||||
ctx.AdminManagementSession.requireNewEdgeRouterPolicy(s("#all"), s("#"+identityRole))
|
||||
@@ -94,25 +102,36 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
code, body := enrolledIdentitySession.query("/services/" + service.Id)
|
||||
ctx.Req.Equal(http.StatusOK, code)
|
||||
entityService, err := gabs.ParseJSON(body)
|
||||
|
||||
serviceEnvelope := &rest_model.DetailServiceEnvelope{}
|
||||
err := serviceEnvelope.UnmarshalBinary(body)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
querySet, err := entityService.Path("data.postureQueries").Children()
|
||||
ctx.Req.NoError(err)
|
||||
querySet := serviceEnvelope.Data.PostureQueries
|
||||
ctx.Req.NotNil(querySet)
|
||||
ctx.Req.NotEmpty(querySet)
|
||||
ctx.Req.Len(querySet, 1)
|
||||
|
||||
postureQueries, err := querySet[0].Path("postureQueries").Children()
|
||||
postureQueries := querySet[0].PostureQueries
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Len(postureQueries, 1)
|
||||
|
||||
ctx.Req.Equal(postureCheckId, postureQueries[0].Path("id").Data().(string))
|
||||
ctx.Req.Equal(string(postureCheck.TypeID()), postureQueries[0].Path("queryType").Data().(string))
|
||||
ctx.Req.Equal(postureCheckId, *postureQueries[0].ID)
|
||||
ctx.Req.Equal(postureCheck.TypeID(), *postureQueries[0].QueryType)
|
||||
|
||||
t.Run("query is currently failing", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.False(querySet[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.False(postureQueries[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.Equal(-1, int(postureQueries[0].Path("timeout").Data().(float64)))
|
||||
ctx.Req.False(*querySet[0].IsPassing)
|
||||
ctx.Req.False(*postureQueries[0].IsPassing)
|
||||
ctx.Req.Equal(int64(-1), *postureQueries[0].Timeout)
|
||||
})
|
||||
|
||||
t.Run("updatedAt equals posture check createdAt", func(t *testing.T) {
|
||||
//fix this
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.NotNil(postureCheckDetail)
|
||||
ctx.Req.NotEmpty(postureCheckDetail.CreatedAt())
|
||||
postureCheckDetail.CreatedAt().Equal(*postureQueries[0].CreatedAt)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -130,7 +149,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
listEnvelop := rest_model.FailedServiceRequestEnvelope{}
|
||||
ctx.Req.NoError(json.Unmarshal(resp.Body(), &listEnvelop))
|
||||
ctx.Req.NoError(listEnvelop.UnmarshalBinary(resp.Body()))
|
||||
|
||||
ctx.Req.NotEmpty(listEnvelop.Data)
|
||||
})
|
||||
@@ -147,7 +166,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
resp, err := enrolledIdentitySession.newAuthenticatedRequest().Post("/current-identity/mfa")
|
||||
|
||||
ctx.Req.NoError(err)
|
||||
standardJsonResponseTests(resp, http.StatusCreated, t)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
|
||||
t.Run("does not allow service session creation", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -161,16 +180,20 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
t.Run("by finishing enrollment in MFA", func(t *testing.T) {
|
||||
resp, err := enrolledIdentitySession.newAuthenticatedRequest().Get("/current-identity/mfa")
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
mfaEnvelope := &rest_model.DetailMfaEnvelope{}
|
||||
|
||||
mfa, err := gabs.ParseJSON(resp.Body())
|
||||
err = mfaEnvelope.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(mfaEnvelope)
|
||||
ctx.Req.NotNil(mfaEnvelope.Data)
|
||||
|
||||
rawUrl := mfa.Path("data.provisioningUrl").Data().(string)
|
||||
ctx.Req.NotEmpty(rawUrl)
|
||||
mfa := mfaEnvelope.Data
|
||||
ctx.Req.NotNil(mfa.ID)
|
||||
ctx.Req.NotEmpty(mfa.ProvisioningURL)
|
||||
|
||||
parsedUrl, err := url.Parse(rawUrl)
|
||||
parsedUrl, err := url.Parse(mfa.ProvisioningURL)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
queryParams, err := url.ParseQuery(parsedUrl.RawQuery)
|
||||
@@ -190,7 +213,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
Post("/current-identity/mfa/verify")
|
||||
|
||||
ctx.Req.NoError(err)
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
t.Run("allows service session creation", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -204,25 +227,34 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
code, body := enrolledIdentitySession.query("/services/" + service.Id)
|
||||
ctx.Req.Equal(http.StatusOK, code)
|
||||
entityService, err := gabs.ParseJSON(body)
|
||||
serviceEnvelope := &rest_model.DetailServiceEnvelope{}
|
||||
err = serviceEnvelope.UnmarshalBinary(body)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
querySet, err := entityService.Path("data.postureQueries").Children()
|
||||
ctx.Req.NoError(err)
|
||||
entityService := serviceEnvelope.Data
|
||||
|
||||
querySet := entityService.PostureQueries
|
||||
ctx.Req.Len(querySet, 1)
|
||||
|
||||
postureQueries, err := querySet[0].Path("postureQueries").Children()
|
||||
ctx.Req.NoError(err)
|
||||
postureQueries := querySet[0].PostureQueries
|
||||
ctx.Req.Len(postureQueries, 1)
|
||||
|
||||
ctx.Req.Equal(postureCheckId, postureQueries[0].Path("id").Data().(string))
|
||||
ctx.Req.Equal(string(postureCheck.TypeID()), postureQueries[0].Path("queryType").Data().(string))
|
||||
ctx.Req.Equal(postureCheckId, *postureQueries[0].ID)
|
||||
ctx.Req.Equal(postureCheck.TypeID(), *postureQueries[0].QueryType)
|
||||
|
||||
t.Run("query is currently passing", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.True(querySet[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.True(postureQueries[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.Equal(-1, int(postureQueries[0].Path("timeout").Data().(float64)))
|
||||
ctx.Req.True(*querySet[0].IsPassing)
|
||||
ctx.Req.True(*postureQueries[0].IsPassing)
|
||||
ctx.Req.Equal(int64(-1), *postureQueries[0].Timeout)
|
||||
})
|
||||
|
||||
t.Run("updatedAt equals posture check createdAt", func(t *testing.T) {
|
||||
//fix this
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.NotNil(postureCheckDetail)
|
||||
ctx.Req.NotEmpty(postureCheckDetail.CreatedAt())
|
||||
postureCheckDetail.CreatedAt().Equal(*postureQueries[0].CreatedAt)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -242,12 +274,13 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
|
||||
sessionContainer, err := gabs.ParseJSON(resp.Body())
|
||||
sessionEnvelope := &rest_model.SessionCreateEnvelope{}
|
||||
err = sessionEnvelope.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
ctx.Req.True(sessionContainer.ExistsP("data.id"))
|
||||
sessionId, ok := sessionContainer.Path("data.id").Data().(string)
|
||||
ctx.Req.True(ok)
|
||||
ctx.Req.NotNil(sessionEnvelope.Data.ID)
|
||||
|
||||
sessionId := *sessionEnvelope.Data.ID
|
||||
ctx.Req.NotEmpty(sessionId)
|
||||
|
||||
t.Run("removing MFA while the service requires MFA", func(t *testing.T) {
|
||||
@@ -317,10 +350,20 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
|
||||
resp := ctx.AdminManagementSession.createEntityOfType("posture-checks", postureCheckBody)
|
||||
|
||||
standardJsonResponseTests(resp, http.StatusCreated, t)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
postureCheckId := ctx.getEntityId(resp.Body())
|
||||
ctx.Req.NotEmpty(postureCheckId)
|
||||
|
||||
resp, err = ctx.AdminManagementSession.newAuthenticatedRequest().Get("/posture-checks/" + postureCheckId)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
responseEnvelope := rest_model.DetailPostureCheckEnvelope{}
|
||||
|
||||
err = responseEnvelope.UnmarshalJSON(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
postureCheckDetail := responseEnvelope.Data().(*rest_model.PostureCheckMfaDetail)
|
||||
|
||||
t.Run("identity can see service via policies", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.True(enrolledIdentitySession.isServiceVisibleToUser(service.Id))
|
||||
@@ -330,25 +373,37 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
code, body := enrolledIdentitySession.query("/services/" + service.Id)
|
||||
ctx.Req.Equal(http.StatusOK, code)
|
||||
entityService, err := gabs.ParseJSON(body)
|
||||
|
||||
serviceEnvelope := &rest_model.DetailServiceEnvelope{}
|
||||
err = serviceEnvelope.UnmarshalBinary(body)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
querySet, err := entityService.Path("data.postureQueries").Children()
|
||||
ctx.Req.NoError(err)
|
||||
entityService := serviceEnvelope.Data
|
||||
ctx.Req.NotNil(entityService)
|
||||
ctx.Req.NotNil(entityService.ID)
|
||||
|
||||
querySet := entityService.PostureQueries
|
||||
ctx.Req.Len(querySet, 1)
|
||||
|
||||
postureQueries, err := querySet[0].Path("postureQueries").Children()
|
||||
ctx.Req.NoError(err)
|
||||
postureQueries := querySet[0].PostureQueries
|
||||
ctx.Req.Len(postureQueries, 1)
|
||||
|
||||
ctx.Req.Equal(postureCheckId, postureQueries[0].Path("id").Data().(string))
|
||||
ctx.Req.Equal(string(postureCheck.TypeID()), postureQueries[0].Path("queryType").Data().(string))
|
||||
ctx.Req.Equal(postureCheckId, *postureQueries[0].ID)
|
||||
ctx.Req.Equal(postureCheck.TypeID(), *postureQueries[0].QueryType)
|
||||
|
||||
t.Run("query is currently failing", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.False(querySet[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.False(postureQueries[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.Equal(0, int(postureQueries[0].Path("timeoutRemaining").Data().(float64)))
|
||||
ctx.Req.False(*querySet[0].IsPassing)
|
||||
ctx.Req.False(*postureQueries[0].IsPassing)
|
||||
ctx.Req.Equal(int64(0), *postureQueries[0].TimeoutRemaining)
|
||||
})
|
||||
|
||||
t.Run("updatedAt equals posture check createdAt", func(t *testing.T) {
|
||||
//fix this
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.NotNil(postureCheckDetail)
|
||||
ctx.Req.NotEmpty(postureCheckDetail.CreatedAt())
|
||||
postureCheckDetail.CreatedAt().Equal(*postureQueries[0].CreatedAt)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -365,9 +420,8 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
resp, err := ctx.AdminManagementSession.newAuthenticatedRequest().Get("/identities/" + enrolledIdentitySession.identityId + "/failed-service-requests")
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
listEnvelop := rest_model.FailedServiceRequestEnvelope{}
|
||||
ctx.Req.NoError(json.Unmarshal(resp.Body(), &listEnvelop))
|
||||
|
||||
listEnvelop := &rest_model.FailedServiceRequestEnvelope{}
|
||||
ctx.Req.NoError(listEnvelop.UnmarshalBinary(resp.Body()))
|
||||
ctx.Req.NotEmpty(listEnvelop.Data)
|
||||
})
|
||||
})
|
||||
@@ -383,7 +437,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
resp, err := enrolledIdentitySession.newAuthenticatedRequest().Post("/current-identity/mfa")
|
||||
|
||||
ctx.Req.NoError(err)
|
||||
standardJsonResponseTests(resp, http.StatusCreated, t)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
|
||||
t.Run("does not allow service session creation", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -397,16 +451,19 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
t.Run("by finishing enrollment in MFA", func(t *testing.T) {
|
||||
resp, err := enrolledIdentitySession.newAuthenticatedRequest().Get("/current-identity/mfa")
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
|
||||
mfa, err := gabs.ParseJSON(resp.Body())
|
||||
mfaEnvelope := &rest_model.DetailMfaEnvelope{}
|
||||
err = mfaEnvelope.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(mfaEnvelope)
|
||||
ctx.Req.NotNil(mfaEnvelope.Data)
|
||||
|
||||
rawUrl := mfa.Path("data.provisioningUrl").Data().(string)
|
||||
ctx.Req.NotEmpty(rawUrl)
|
||||
mfa := mfaEnvelope.Data
|
||||
ctx.Req.NotNil(mfa.ID)
|
||||
ctx.Req.NotEmpty(mfa.ProvisioningURL)
|
||||
|
||||
parsedUrl, err := url.Parse(rawUrl)
|
||||
parsedUrl, err := url.Parse(mfa.ProvisioningURL)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
queryParams, err := url.ParseQuery(parsedUrl.RawQuery)
|
||||
@@ -426,7 +483,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
Post("/current-identity/mfa/verify")
|
||||
|
||||
ctx.Req.NoError(err)
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
t.Run("allows service session creation", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -440,25 +497,28 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
code, body := enrolledIdentitySession.query("/services/" + service.Id)
|
||||
ctx.Req.Equal(http.StatusOK, code)
|
||||
entityService, err := gabs.ParseJSON(body)
|
||||
|
||||
serviceEnvelope := &rest_model.DetailServiceEnvelope{}
|
||||
err := serviceEnvelope.UnmarshalBinary(body)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
querySet, err := entityService.Path("data.postureQueries").Children()
|
||||
ctx.Req.NoError(err)
|
||||
querySet := serviceEnvelope.Data.PostureQueries
|
||||
ctx.Req.NotNil(querySet)
|
||||
ctx.Req.NotEmpty(querySet)
|
||||
ctx.Req.Len(querySet, 1)
|
||||
|
||||
postureQueries, err := querySet[0].Path("postureQueries").Children()
|
||||
postureQueries := querySet[0].PostureQueries
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Len(postureQueries, 1)
|
||||
|
||||
ctx.Req.Equal(postureCheckId, postureQueries[0].Path("id").Data().(string))
|
||||
ctx.Req.Equal(string(postureCheck.TypeID()), postureQueries[0].Path("queryType").Data().(string))
|
||||
ctx.Req.Equal(postureCheckId, *postureQueries[0].ID)
|
||||
ctx.Req.Equal(postureCheck.TypeID(), *postureQueries[0].QueryType)
|
||||
|
||||
t.Run("query is currently passing", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.True(querySet[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.True(postureQueries[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.Greater(int(postureQueries[0].Path("timeout").Data().(float64)), 0)
|
||||
ctx.Req.True(*querySet[0].IsPassing)
|
||||
ctx.Req.True(*postureQueries[0].IsPassing)
|
||||
ctx.Req.Greater(*postureQueries[0].Timeout, int64(0))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -473,7 +533,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
resp, err := enrolledIdentitySession.NewRequest().SetBody(wokeState).Post("posture-response")
|
||||
|
||||
ctx.Req.NoError(err)
|
||||
standardJsonResponseTests(resp, http.StatusCreated, t)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
|
||||
t.Run("woke posture response should include service timeout change event", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -496,26 +556,71 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
code, body := enrolledIdentitySession.query("/services/" + service.Id)
|
||||
ctx.Req.Equal(http.StatusOK, code)
|
||||
entityService, err := gabs.ParseJSON(body)
|
||||
|
||||
serviceEnvelope := &rest_model.DetailServiceEnvelope{}
|
||||
err := serviceEnvelope.UnmarshalBinary(body)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
querySet, err := entityService.Path("data.postureQueries").Children()
|
||||
ctx.Req.NoError(err)
|
||||
querySet := serviceEnvelope.Data.PostureQueries
|
||||
ctx.Req.NotNil(querySet)
|
||||
ctx.Req.NotEmpty(querySet)
|
||||
ctx.Req.Len(querySet, 1)
|
||||
|
||||
postureQueries, err := querySet[0].Path("postureQueries").Children()
|
||||
postureQueries := querySet[0].PostureQueries
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Len(postureQueries, 1)
|
||||
|
||||
ctx.Req.Equal(postureCheckId, postureQueries[0].Path("id").Data().(string))
|
||||
ctx.Req.Equal(string(postureCheck.TypeID()), postureQueries[0].Path("queryType").Data().(string))
|
||||
ctx.Req.Equal(postureCheckId, *postureQueries[0].ID)
|
||||
ctx.Req.Equal(postureCheck.TypeID(), *postureQueries[0].QueryType)
|
||||
|
||||
t.Run("query has a lower timeout", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.True(querySet[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.True(postureQueries[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.Greater(int(postureQueries[0].Path("timeoutRemaining").Data().(float64)), 0)
|
||||
ctx.Req.LessOrEqual(int(postureQueries[0].Path("timeoutRemaining").Data().(float64)), 300)
|
||||
ctx.Req.True(*querySet[0].IsPassing)
|
||||
ctx.Req.True(*postureQueries[0].IsPassing)
|
||||
ctx.Req.Greater(*postureQueries[0].TimeoutRemaining, int64(0))
|
||||
ctx.Req.LessOrEqual(*postureQueries[0].TimeoutRemaining, int64(300))
|
||||
})
|
||||
|
||||
t.Run("query has a new updatedAt value", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.True(time.Time(*postureQueries[0].UpdatedAt).After(time.Time(*postureCheckDetail.UpdatedAt())), "posture query updated at [%s] should now be after original time [%s]", postureQueries[0].UpdatedAt.String(), postureCheckDetail.UpdatedAt().String())
|
||||
})
|
||||
|
||||
t.Run("updating the posture check further advances updatedAt", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
|
||||
newTimeout := int64(600)
|
||||
mfaPatch := &rest_model.PostureCheckMfaPatch{}
|
||||
mfaPatch.TimeoutSeconds = &newTimeout
|
||||
|
||||
body, err := mfaPatch.MarshalJSON()
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
resp, err := ctx.AdminManagementSession.newAuthenticatedRequest().SetBody(body).Patch("/posture-checks/" + postureCheckId)
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
resp, err = enrolledIdentitySession.newAuthenticatedRequest().Get("/services/" + service.Id)
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
patchedServiceEnv := &rest_model.DetailServiceEnvelope{}
|
||||
err = patchedServiceEnv.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
patchedQuerySet := patchedServiceEnv.Data.PostureQueries
|
||||
ctx.Req.NotNil(patchedQuerySet)
|
||||
ctx.Req.NotEmpty(patchedQuerySet)
|
||||
ctx.Req.Len(patchedQuerySet, 1)
|
||||
|
||||
patchedPostureQueries := patchedQuerySet[0].PostureQueries
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Len(patchedPostureQueries, 1)
|
||||
|
||||
ctx.Req.Equal(postureCheckId, *patchedPostureQueries[0].ID)
|
||||
ctx.Req.Equal(postureCheck.TypeID(), *patchedPostureQueries[0].QueryType)
|
||||
|
||||
ctx.Req.True(time.Time(*patchedPostureQueries[0].UpdatedAt).After(time.Time(*postureQueries[0].UpdatedAt)), "posture query updated at [%s] should now be after state change time [%s]", patchedPostureQueries[0].UpdatedAt.String(), postureCheckDetail.UpdatedAt().String())
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -536,12 +641,15 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
|
||||
sessionContainer, err := gabs.ParseJSON(resp.Body())
|
||||
serviceEnvelope := &rest_model.DetailServiceEnvelope{}
|
||||
err = serviceEnvelope.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
ctx.Req.True(sessionContainer.ExistsP("data.id"))
|
||||
sessionId, ok := sessionContainer.Path("data.id").Data().(string)
|
||||
ctx.Req.True(ok)
|
||||
entityService := serviceEnvelope.Data
|
||||
ctx.Req.NotNil(entityService)
|
||||
ctx.Req.NotNil(entityService.ID)
|
||||
|
||||
sessionId := *entityService.ID
|
||||
ctx.Req.NotEmpty(sessionId)
|
||||
})
|
||||
|
||||
@@ -640,7 +748,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
|
||||
resp := ctx.AdminManagementSession.createEntityOfType("posture-checks", postureCheckBody)
|
||||
|
||||
standardJsonResponseTests(resp, http.StatusCreated, t)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
postureCheckId := ctx.getEntityId(resp.Body())
|
||||
ctx.Req.NotEmpty(postureCheckId)
|
||||
|
||||
@@ -663,7 +771,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
resp, err := enrolledIdentitySession.newAuthenticatedRequest().Post("/current-identity/mfa")
|
||||
|
||||
ctx.Req.NoError(err)
|
||||
standardJsonResponseTests(resp, http.StatusCreated, t)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
|
||||
t.Run("does not allow service session creation", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -677,16 +785,20 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
t.Run("by finishing enrollment in MFA", func(t *testing.T) {
|
||||
resp, err := enrolledIdentitySession.newAuthenticatedRequest().Get("/current-identity/mfa")
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
mfaEnvelope := &rest_model.DetailMfaEnvelope{}
|
||||
|
||||
mfa, err := gabs.ParseJSON(resp.Body())
|
||||
err = mfaEnvelope.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(mfaEnvelope)
|
||||
ctx.Req.NotNil(mfaEnvelope.Data)
|
||||
|
||||
rawUrl := mfa.Path("data.provisioningUrl").Data().(string)
|
||||
ctx.Req.NotEmpty(rawUrl)
|
||||
mfa := mfaEnvelope.Data
|
||||
ctx.Req.NotNil(mfa.ID)
|
||||
ctx.Req.NotEmpty(mfa.ProvisioningURL)
|
||||
|
||||
parsedUrl, err := url.Parse(rawUrl)
|
||||
parsedUrl, err := url.Parse(mfa.ProvisioningURL)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
queryParams, err := url.ParseQuery(parsedUrl.RawQuery)
|
||||
@@ -706,7 +818,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
Post("/current-identity/mfa/verify")
|
||||
|
||||
ctx.Req.NoError(err)
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
t.Run("allows service session creation", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -720,25 +832,28 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
code, body := enrolledIdentitySession.query("/services/" + service.Id)
|
||||
ctx.Req.Equal(http.StatusOK, code)
|
||||
entityService, err := gabs.ParseJSON(body)
|
||||
|
||||
serviceEnvelope := &rest_model.DetailServiceEnvelope{}
|
||||
err := serviceEnvelope.UnmarshalBinary(body)
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
querySet, err := entityService.Path("data.postureQueries").Children()
|
||||
ctx.Req.NoError(err)
|
||||
querySet := serviceEnvelope.Data.PostureQueries
|
||||
ctx.Req.NotNil(querySet)
|
||||
ctx.Req.NotEmpty(querySet)
|
||||
ctx.Req.Len(querySet, 1)
|
||||
|
||||
postureQueries, err := querySet[0].Path("postureQueries").Children()
|
||||
postureQueries := querySet[0].PostureQueries
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Len(postureQueries, 1)
|
||||
|
||||
ctx.Req.Equal(postureCheckId, postureQueries[0].Path("id").Data().(string))
|
||||
ctx.Req.Equal(string(postureCheck.TypeID()), postureQueries[0].Path("queryType").Data().(string))
|
||||
ctx.Req.Equal(postureCheckId, *postureQueries[0].ID)
|
||||
ctx.Req.Equal(postureCheck.TypeID(), *postureQueries[0].QueryType)
|
||||
|
||||
t.Run("query is currently passing", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
ctx.Req.True(querySet[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.True(postureQueries[0].Path("isPassing").Data().(bool))
|
||||
ctx.Req.Greater(int(postureQueries[0].Path("timeout").Data().(float64)), 0)
|
||||
ctx.Req.True(*querySet[0].IsPassing)
|
||||
ctx.Req.True(*postureQueries[0].IsPassing)
|
||||
ctx.Req.Greater(*postureQueries[0].Timeout, int64(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -759,30 +874,37 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
|
||||
sessionContainer, err := gabs.ParseJSON(resp.Body())
|
||||
sessionCreateEnvelope := &rest_model.SessionCreateEnvelope{}
|
||||
err = sessionCreateEnvelope.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(sessionCreateEnvelope.Data)
|
||||
ctx.Req.NotNil(sessionCreateEnvelope.Data.ID)
|
||||
|
||||
ctx.Req.True(sessionContainer.ExistsP("data.id"))
|
||||
sessionId, ok := sessionContainer.Path("data.id").Data().(string)
|
||||
ctx.Req.True(ok)
|
||||
sessionId := *sessionCreateEnvelope.Data.ID
|
||||
ctx.Req.NotEmpty(sessionId)
|
||||
|
||||
resp, err = ctx.AdminManagementSession.NewRequest().Get("/sessions/" + sessionId)
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
sessionDetailEnvelope := &rest_model.DetailSessionEnvelope{}
|
||||
err = sessionDetailEnvelope.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(sessionDetailEnvelope.Data)
|
||||
ctx.Req.NotNil(sessionDetailEnvelope.Data.ID)
|
||||
|
||||
resp, err = newSession.NewRequest().Get("/current-api-session/service-updates")
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
serviceUpdateContainer, err := gabs.ParseJSON(resp.Body())
|
||||
serviceUpdatesEnvelop := &rest_model.ListCurrentAPISessionServiceUpdatesEnvelope{}
|
||||
err = serviceUpdatesEnvelop.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(serviceUpdatesEnvelop.Data)
|
||||
ctx.Req.NotNil(serviceUpdatesEnvelop.Data.LastChangeAt)
|
||||
ctx.Req.False(time.Time(*serviceUpdatesEnvelop.Data.LastChangeAt).IsZero())
|
||||
|
||||
ctx.Req.True(serviceUpdateContainer.ExistsP("data.lastChangeAt"))
|
||||
|
||||
lastChangeAt, ok := serviceUpdateContainer.Path("data.lastChangeAt").Data().(string)
|
||||
ctx.Req.True(ok)
|
||||
ctx.Req.NotEmpty(lastChangeAt)
|
||||
originalLastChangedAt := *serviceUpdatesEnvelop.Data.LastChangeAt
|
||||
|
||||
t.Run("after the MFA posture check timeout", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -799,16 +921,16 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
serviceUpdateContainer, err := gabs.ParseJSON(resp.Body())
|
||||
serviceUpdatesEnvelop := &rest_model.ListCurrentAPISessionServiceUpdatesEnvelope{}
|
||||
err = serviceUpdatesEnvelop.UnmarshalBinary(resp.Body())
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(serviceUpdatesEnvelop.Data)
|
||||
ctx.Req.NotNil(serviceUpdatesEnvelop.Data.LastChangeAt)
|
||||
ctx.Req.False(time.Time(*serviceUpdatesEnvelop.Data.LastChangeAt).IsZero())
|
||||
|
||||
ctx.Req.True(serviceUpdateContainer.ExistsP("data.lastChangeAt"))
|
||||
newLastChangeAt := *serviceUpdatesEnvelop.Data.LastChangeAt
|
||||
|
||||
newLastChangeAt, ok := serviceUpdateContainer.Path("data.lastChangeAt").Data().(string)
|
||||
ctx.Req.True(ok)
|
||||
ctx.Req.NotEmpty(newLastChangeAt)
|
||||
|
||||
ctx.Req.NotEqual(newLastChangeAt, lastChangeAt)
|
||||
ctx.Req.False(originalLastChangedAt.Equal(newLastChangeAt))
|
||||
})
|
||||
|
||||
t.Run("the existing session was removed", func(t *testing.T) {
|
||||
@@ -860,7 +982,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
|
||||
resp := ctx.AdminManagementSession.createEntityOfType("posture-checks", postureCheckBody)
|
||||
|
||||
standardJsonResponseTests(resp, http.StatusCreated, t)
|
||||
ctx.Req.Equal(http.StatusCreated, resp.StatusCode())
|
||||
id := ctx.getEntityId(resp.Body())
|
||||
ctx.Req.NotEmpty(id)
|
||||
|
||||
@@ -870,7 +992,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
resp, err := ctx.AdminManagementSession.NewRequest().Get("posture-checks/" + id)
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(resp)
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
envelope := rest_model.DetailPostureCheckEnvelope{}
|
||||
|
||||
@@ -915,7 +1037,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
|
||||
ctx.Req.NoError(err)
|
||||
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
t.Run("can be retrieved", func(t *testing.T) {
|
||||
ctx.testContextChanged(t)
|
||||
@@ -923,7 +1045,7 @@ func Test_PostureChecks_MFA(t *testing.T) {
|
||||
resp, err := ctx.AdminManagementSession.NewRequest().Get("posture-checks/" + id)
|
||||
ctx.Req.NoError(err)
|
||||
ctx.Req.NotNil(resp)
|
||||
standardJsonResponseTests(resp, http.StatusOK, t)
|
||||
ctx.Req.Equal(http.StatusOK, resp.StatusCode())
|
||||
|
||||
envelope := rest_model.DetailPostureCheckEnvelope{}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user