From 930ed1003f6c88d23f18012067966965d55a030e Mon Sep 17 00:00:00 2001 From: Nick Cabatoff Date: Wed, 22 Jan 2020 16:53:47 -0500 Subject: [PATCH] go mod tidy and vendor --- go.mod | 5 +- go.sum | 7 + .../chrismalek/oktasdk-go/LICENSE.txt | 21 + .../chrismalek/oktasdk-go/okta/apps.go | 315 +++++++++ .../chrismalek/oktasdk-go/okta/factors.go | 8 + .../chrismalek/oktasdk-go/okta/groups.go | 359 ++++++++++ .../chrismalek/oktasdk-go/okta/sdk.go | 523 +++++++++++++++ .../chrismalek/oktasdk-go/okta/users.go | 625 ++++++++++++++++++ .../okta/okta-sdk-golang/okta/config.go | 47 +- .../okta/okta-sdk-golang/okta/okta.go | 39 +- .../okta-sdk-golang/okta/requestExecutor.go | 103 +-- .../okta/okta-sdk-golang/okta/validator.go | 10 +- vendor/modules.txt | 506 +++++++------- 13 files changed, 2160 insertions(+), 408 deletions(-) create mode 100644 vendor/github.com/chrismalek/oktasdk-go/LICENSE.txt create mode 100644 vendor/github.com/chrismalek/oktasdk-go/okta/apps.go create mode 100644 vendor/github.com/chrismalek/oktasdk-go/okta/factors.go create mode 100644 vendor/github.com/chrismalek/oktasdk-go/okta/groups.go create mode 100644 vendor/github.com/chrismalek/oktasdk-go/okta/sdk.go create mode 100644 vendor/github.com/chrismalek/oktasdk-go/okta/users.go diff --git a/go.mod b/go.mod index 9151376ef5eeb..547d94ec26ec2 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( github.com/cockroachdb/apd v1.1.0 // indirect github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c github.com/coreos/go-semver v0.2.0 + github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d // indirect github.com/denisenkom/go-mssqldb v0.0.0-20190412130859-3b1d194e553a github.com/dnaeon/go-vcr v1.0.1 // indirect github.com/dsnet/compress v0.0.1 // indirect @@ -47,6 +48,7 @@ require ( github.com/golang/protobuf v1.3.2 github.com/google/go-github v17.0.0+incompatible github.com/google/go-metrics-stackdriver v0.0.0-20190816035513-b52628e82e2a + github.com/google/go-querystring v1.0.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.8.5 // indirect github.com/hashicorp/consul-template v0.22.0 github.com/hashicorp/consul/api v1.1.0 @@ -95,6 +97,7 @@ require ( github.com/joyent/triton-go v0.0.0-20190112182421-51ffac552869 github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f github.com/kr/pretty v0.1.0 + github.com/kr/pty v1.1.3 // indirect github.com/kr/text v0.1.0 github.com/lib/pq v1.2.0 github.com/mattn/go-colorable v0.1.4 @@ -109,8 +112,8 @@ require ( github.com/ncw/swift v1.0.47 github.com/nwaples/rardecode v1.0.0 // indirect github.com/oklog/run v1.0.0 - github.com/oracle/oci-go-sdk v12.5.0+incompatible github.com/okta/okta-sdk-golang v1.0.1 + github.com/oracle/oci-go-sdk v12.5.0+incompatible github.com/ory/dockertest v3.3.5+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.8.1 diff --git a/go.sum b/go.sum index c680772f4c0b4..beacd9df4af00 100644 --- a/go.sum +++ b/go.sum @@ -206,6 +206,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df h1:fwXmhM0OqixzJDOGgTSyNH9eEDij9uGTXwsyWXvyR0A= github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -438,6 +440,8 @@ github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVY github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= +github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f h1:Gsc9mVHLRqBjMgdQCghN9NObCcRncDqxJvBvEaIIQEo= github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -515,6 +519,8 @@ github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMB github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/okta/okta-sdk-golang v1.0.1 h1:1DGm5+h2JvfdHz07yVVM7+LgUVSwxnk+6RoLUOB6CwI= +github.com/okta/okta-sdk-golang v1.0.1/go.mod h1:8k//sN2mFTq8Ayo90DqGbcumCkSmYjF0+2zkIbZysec= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -545,6 +551,7 @@ github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOTh github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= diff --git a/vendor/github.com/chrismalek/oktasdk-go/LICENSE.txt b/vendor/github.com/chrismalek/oktasdk-go/LICENSE.txt new file mode 100644 index 0000000000000..63b4b681cb65b --- /dev/null +++ b/vendor/github.com/chrismalek/oktasdk-go/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/chrismalek/oktasdk-go/okta/apps.go b/vendor/github.com/chrismalek/oktasdk-go/okta/apps.go new file mode 100644 index 0000000000000..1fe8007bca8f1 --- /dev/null +++ b/vendor/github.com/chrismalek/oktasdk-go/okta/apps.go @@ -0,0 +1,315 @@ +package okta + +import ( + "fmt" + "net/url" + "time" +) + +// AppsService is a service to retreives applications from OKTA. +type AppsService service + +// AppFilterOptions is used to generate a "Filter" to search for different Apps +// The values here coorelate to API Search paramgters on the group API +type AppFilterOptions struct { + NextURL *url.URL `url:"-"` + GetAllPages bool `url:"-"` + NumberOfPages int `url:"-"` + Limit int `url:"limit,omitempty"` +} + +// App is the Model for an OKTA Application +type App struct { + ID string `json:"id"` + Name string `json:"name"` + Label string `json:"label"` + Status string `json:"status"` + LastUpdated time.Time `json:"lastUpdated"` + Created time.Time `json:"created"` + Accessibility struct { + SelfService bool `json:"selfService"` + ErrorRedirectURL interface{} `json:"errorRedirectUrl"` + LoginRedirectURL interface{} `json:"loginRedirectUrl"` + } `json:"accessibility"` + Visibility struct { + AutoSubmitToolbar bool `json:"autoSubmitToolbar"` + Hide struct { + IOS bool `json:"iOS"` + Web bool `json:"web"` + } `json:"hide"` + AppLinks struct { + TestorgoneCustomsaml20App1Link bool `json:"testorgone_customsaml20app_1_link"` + } `json:"appLinks"` + } `json:"visibility"` + Features []interface{} `json:"features"` + SignOnMode string `json:"signOnMode"` + Credentials struct { + UserNameTemplate struct { + Template string `json:"template"` + Type string `json:"type"` + } `json:"userNameTemplate"` + Signing struct { + } `json:"signing"` + } `json:"credentials"` + Settings struct { + App struct { + } `json:"app"` + Notifications struct { + Vpn struct { + Network struct { + Connection string `json:"connection"` + } `json:"network"` + Message interface{} `json:"message"` + HelpURL interface{} `json:"helpUrl"` + } `json:"vpn"` + } `json:"notifications"` + SignOn struct { + DefaultRelayState string `json:"defaultRelayState"` + SsoAcsURL string `json:"ssoAcsUrl"` + IdpIssuer string `json:"idpIssuer"` + Audience string `json:"audience"` + Recipient string `json:"recipient"` + Destination string `json:"destination"` + SubjectNameIDTemplate string `json:"subjectNameIdTemplate"` + SubjectNameIDFormat string `json:"subjectNameIdFormat"` + ResponseSigned bool `json:"responseSigned"` + AssertionSigned bool `json:"assertionSigned"` + SignatureAlgorithm string `json:"signatureAlgorithm"` + DigestAlgorithm string `json:"digestAlgorithm"` + HonorForceAuthn bool `json:"honorForceAuthn"` + AuthnContextClassRef string `json:"authnContextClassRef"` + SpIssuer interface{} `json:"spIssuer"` + RequestCompressed bool `json:"requestCompressed"` + AttributeStatements []interface{} `json:"attributeStatements"` + } `json:"signOn"` + } `json:"settings"` + Links struct { + Logo []struct { + Name string `json:"name"` + Href string `json:"href"` + Type string `json:"type"` + } `json:"logo"` + AppLinks []struct { + Name string `json:"name"` + Href string `json:"href"` + Type string `json:"type"` + } `json:"appLinks"` + Help struct { + Href string `json:"href"` + Type string `json:"type"` + } `json:"help"` + Users struct { + Href string `json:"href"` + } `json:"users"` + Deactivate struct { + Href string `json:"href"` + } `json:"deactivate"` + Groups struct { + Href string `json:"href"` + } `json:"groups"` + Metadata struct { + Href string `json:"href"` + Type string `json:"type"` + } `json:"metadata"` + } `json:"_links"` +} + +func (a App) String() string { + // return Stringify(g) + return fmt.Sprintf("App:(ID: {%v} - Name: {%v})\n", a.ID, a.Name) +} + +// GetByID gets a group from OKTA by the Gropu ID. An error is returned if the group is not found +func (a *AppsService) GetByID(appID string) (*App, *Response, error) { + + u := fmt.Sprintf("apps/%v", appID) + req, err := a.client.NewRequest("GET", u, nil) + + if err != nil { + return nil, nil, err + } + + app := new(App) + + resp, err := a.client.Do(req, app) + + if err != nil { + return nil, resp, err + } + + return app, resp, err +} + +// AppUser is the model for a user of an OKTA App +type AppUser struct { + ID string `json:"id"` + ExternalID string `json:"externalId"` + Created time.Time `json:"created"` + LastUpdated time.Time `json:"lastUpdated"` + Scope string `json:"scope"` + Status string `json:"status"` + StatusChanged *time.Time `json:"statusChanged"` + PasswordChanged *time.Time `json:"passwordChanged"` + SyncState string `json:"syncState"` + LastSync *time.Time `json:"lastSync"` + Credentials struct { + UserName string `json:"userName"` + Password struct { + } `json:"password"` + } `json:"credentials"` + Profile struct { + SecondEmail interface{} `json:"secondEmail"` + LastName string `json:"lastName"` + MobilePhone interface{} `json:"mobilePhone"` + Email string `json:"email"` + SalesforceGroups []string `json:"salesforceGroups"` + Role string `json:"role"` + FirstName string `json:"firstName"` + Profile string `json:"profile"` + } `json:"profile"` + Links struct { + App struct { + Href string `json:"href"` + } `json:"app"` + User struct { + Href string `json:"href"` + } `json:"user"` + } `json:"_links"` +} + +// GetUsers returns the members in an App +// Pass in an optional AppFilterOptions struct to filter the results +// The Users in the app are returned +func (a *AppsService) GetUsers(appID string, opt *AppFilterOptions) (appUsers []AppUser, resp *Response, err error) { + + pagesRetreived := 0 + var u string + if opt.NextURL != nil { + u = opt.NextURL.String() + } else { + u = fmt.Sprintf("apps/%v/users", appID) + + if opt.Limit == 0 { + opt.Limit = defaultLimit + } + + u, _ = addOptions(u, opt) + } + + req, err := a.client.NewRequest("GET", u, nil) + + if err != nil { + // fmt.Printf("____ERROR HERE\n") + return nil, nil, err + } + resp, err = a.client.Do(req, &appUsers) + + if err != nil { + // fmt.Printf("____ERROR HERE 2\n") + return nil, resp, err + } + + pagesRetreived++ + + if (opt.NumberOfPages > 0 && pagesRetreived < opt.NumberOfPages) || opt.GetAllPages { + + for { + + if pagesRetreived == opt.NumberOfPages { + break + } + if resp.NextURL != nil { + + var userPage []AppUser + pageOpts := new(AppFilterOptions) + pageOpts.NextURL = resp.NextURL + pageOpts.Limit = opt.Limit + pageOpts.NumberOfPages = 1 + + userPage, resp, err = a.GetUsers(appID, pageOpts) + + if err != nil { + return appUsers, resp, err + } + appUsers = append(appUsers, userPage...) + pagesRetreived++ + } else { + break + } + + } + } + + return appUsers, resp, err +} + +// AppGroups - Groups assigned to Application +type AppGroups struct { + ID string `json:"id"` + LastUpdated time.Time `json:"lastUpdated"` + Priority int `json:"priority"` + Links struct { + User struct { + Href string `json:"href"` + } `json:"user"` + } `json:"_links"` +} + +// GetGroups returns groups assigned to the application - Input appID is the Application GUID +func (a *AppsService) GetGroups(appID string) (appGroups []AppGroups, resp *Response, err error) { + + var u string + u = fmt.Sprintf("apps/%v/groups", appID) + + req, err := a.client.NewRequest("GET", u, nil) + + if err != nil { + return nil, nil, err + } + resp, err = a.client.Do(req, &appGroups) + + if err != nil { + return nil, resp, err + } + + for { + + if resp.NextURL != nil { + + var appGroupPage []AppGroups + + appGroupPage, resp, err = a.GetGroups(appID) + + if err != nil { + return appGroups, resp, err + } else { + appGroups = append(appGroups, appGroupPage...) + + } + } else { + break + } + + } + + return appGroups, resp, err +} + +// GetUser returns the AppUser model for one app users +func (a *AppsService) GetUser(appID string, userID string) (appUser AppUser, resp *Response, err error) { + + var u string + u = fmt.Sprintf("apps/%v/users/%v", appID, userID) + + req, err := a.client.NewRequest("GET", u, nil) + + if err != nil { + return appUser, nil, err + } + resp, err = a.client.Do(req, &appUser) + + if err != nil { + return appUser, resp, err + } + return appUser, resp, nil +} diff --git a/vendor/github.com/chrismalek/oktasdk-go/okta/factors.go b/vendor/github.com/chrismalek/oktasdk-go/okta/factors.go new file mode 100644 index 0000000000000..fc926f91aa387 --- /dev/null +++ b/vendor/github.com/chrismalek/oktasdk-go/okta/factors.go @@ -0,0 +1,8 @@ +package okta + +const ( + // MFAStatusActive is a constant to represent OKTA User State returned by the API + MFAStatusActive = "ACTIVE" + // MFAStatusPending is a user MFA Status of NOT Active + MFAStatusPending = "PENDING_ACTIVATION" +) diff --git a/vendor/github.com/chrismalek/oktasdk-go/okta/groups.go b/vendor/github.com/chrismalek/oktasdk-go/okta/groups.go new file mode 100644 index 0000000000000..34584d6eb69ee --- /dev/null +++ b/vendor/github.com/chrismalek/oktasdk-go/okta/groups.go @@ -0,0 +1,359 @@ +package okta + +import ( + "errors" + "fmt" + "net/url" + "time" +) + +const ( + // GroupTypeOKTA - group type constant for an OKTA Mastered Group + GroupTypeOKTA = "OKTA_GROUP" + // GroupTypeBuiltIn - group type constant for a Built in OKTA groups + GroupTypeBuiltIn = "BUILT_IN" + // GroupTypeApp -- group type constant for app mastered group + GroupTypeApp = "APP_GROUP" + + groupTypeFilter = "type" + groupNameFilter = "q" + groupLastMembershipUpdatedFilter = "lastMembershipUpdated" + groupLastUpdatedFilter = "lastUpdated" +) + +// GroupsService handles communication with the Groups data related +// methods of the OKTA API. +type GroupsService service + +// Group represents the Group Object from the OKTA API +type Group struct { + ID string `json:"id"` + Created time.Time `json:"created"` + LastUpdated time.Time `json:"lastUpdated"` + LastMembershipUpdated time.Time `json:"lastMembershipUpdated"` + ObjectClass []string `json:"objectClass"` + Type string `json:"type"` + Profile struct { + Name string `json:"name"` + Description string `json:"description"` + SamAccountName string `json:"samAccountName"` + Dn string `json:"dn"` + WindowsDomainQualifiedName string `json:"windowsDomainQualifiedName"` + ExternalID string `json:"externalId"` + } `json:"profile"` + Links struct { + Logo []struct { + Name string `json:"name"` + Href string `json:"href"` + Type string `json:"type"` + } `json:"logo"` + Users struct { + Href string `json:"href"` + } `json:"users"` + Apps struct { + Href string `json:"href"` + } `json:"apps"` + } `json:"_links"` +} + +// GroupFilterOptions is used to generate a "Filter" to search for different groups +// The values here coorelate to API Search paramgters on the group API +type GroupFilterOptions struct { + // This will be built by internal - may not need to export + FilterString string `url:"filter,omitempty"` + NextURL *url.URL `url:"-"` + GetAllPages bool `url:"-"` + NumberOfPages int `url:"-"` + Limit int `url:"limit,omitempty"` + + NameStartsWith string `url:"q,omitempty"` + GroupTypeEqual string `url:"-"` + + LastUpdated dateFilter `url:"-"` + LastMembershipUpdated dateFilter `url:"-"` +} + +func (g Group) String() string { + // return Stringify(g) + return fmt.Sprintf("Group:(ID: {%v} - Type: {%v} - Group Name: {%v})\n", g.ID, g.Type, g.Profile.Name) +} + +// ListWithFilter - Method to list groups with different filter options. +// Pass in a GroupFilterOptions to specify filters. Values in that struct will turn into Query parameters +func (g *GroupsService) ListWithFilter(opt *GroupFilterOptions) ([]Group, *Response, error) { + + var u string + var err error + + pagesRetreived := 0 + if opt.NextURL != nil { + u = opt.NextURL.String() + } else { + if opt.GroupTypeEqual != "" { + opt.FilterString = appendToFilterString(opt.FilterString, groupTypeFilter, FilterEqualOperator, opt.GroupTypeEqual) + } + + // if opt.NameStartsWith != "" { + // opt.FilterString = appendToFilterString(opt.FilterString, groupNameFilter, filterEqualOperator, opt.NameStartsWith) + // } + if (!opt.LastMembershipUpdated.Value.IsZero()) && (opt.LastMembershipUpdated.Operator != "") { + opt.FilterString = appendToFilterString(opt.FilterString, groupLastMembershipUpdatedFilter, opt.LastMembershipUpdated.Operator, opt.LastMembershipUpdated.Value.UTC().Format(oktaFilterTimeFormat)) + } + + if (!opt.LastUpdated.Value.IsZero()) && (opt.LastUpdated.Operator != "") { + opt.FilterString = appendToFilterString(opt.FilterString, groupLastUpdatedFilter, opt.LastUpdated.Operator, opt.LastUpdated.Value.UTC().Format(oktaFilterTimeFormat)) + } + + if opt.Limit == 0 { + opt.Limit = defaultLimit + } + u, err = addOptions("groups", opt) + if err != nil { + return nil, nil, err + } + } + + req, err := g.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + groups := make([]Group, 1) + resp, err := g.client.Do(req, &groups) + if err != nil { + return nil, resp, err + } + pagesRetreived++ + + if (opt.NumberOfPages > 0 && pagesRetreived < opt.NumberOfPages) || opt.GetAllPages { + + for { + + if pagesRetreived == opt.NumberOfPages { + break + } + if resp.NextURL != nil { + var groupPage []Group + pageOption := new(GroupFilterOptions) + pageOption.NextURL = resp.NextURL + pageOption.NumberOfPages = 1 + pageOption.Limit = opt.Limit + + groupPage, resp, err = g.ListWithFilter(pageOption) + if err != nil { + return groups, resp, err + } + groups = append(groups, groupPage...) + pagesRetreived++ + + } else { + break + } + } + } + return groups, resp, err +} + +// GetByID gets a group from OKTA by the Gropu ID. An error is returned if the group is not found +func (g *GroupsService) GetByID(groupID string) (*Group, *Response, error) { + + u := fmt.Sprintf("groups/%v", groupID) + req, err := g.client.NewRequest("GET", u, nil) + + if err != nil { + return nil, nil, err + } + + group := new(Group) + + resp, err := g.client.Do(req, group) + + if err != nil { + return nil, resp, err + } + + return group, resp, err +} + +// GetUsers returns the members in a group +// Pass in an optional GroupFilterOptions struct to filter the results +// The Users in the group are returned +func (g *GroupsService) GetUsers(groupID string, opt *GroupUserFilterOptions) (users []User, resp *Response, err error) { + pagesRetreived := 0 + var u string + if opt.NextURL != nil { + u = opt.NextURL.String() + } else { + u = fmt.Sprintf("groups/%v/users", groupID) + + if opt.Limit == 0 { + opt.Limit = defaultLimit + } + + u, _ = addOptions(u, opt) + } + + req, err := g.client.NewRequest("GET", u, nil) + + if err != nil { + return nil, nil, err + } + resp, err = g.client.Do(req, &users) + + if err != nil { + return nil, resp, err + } + + pagesRetreived++ + if (opt.NumberOfPages > 0 && pagesRetreived < opt.NumberOfPages) || opt.GetAllPages { + + for { + + if pagesRetreived == opt.NumberOfPages { + break + } + if resp.NextURL != nil { + + var userPage []User + pageOpts := new(GroupUserFilterOptions) + pageOpts.NextURL = resp.NextURL + pageOpts.Limit = opt.Limit + pageOpts.NumberOfPages = 1 + + userPage, resp, err = g.GetUsers(groupID, pageOpts) + if err != nil { + return users, resp, err + } + users = append(users, userPage...) + pagesRetreived++ + } else { + break + } + + } + } + + return users, resp, err +} + +// Add - Adds an OKTA Mastered Group with name and description. GroupName is required. +func (g *GroupsService) Add(groupName string, groupDescription string) (*Group, *Response, error) { + + if groupName == "" { + return nil, nil, errors.New("groupName parameter is required for ADD") + } + + newGroup := newGroup{} + newGroup.Profile.Name = groupName + newGroup.Profile.Description = groupDescription + + u := fmt.Sprintf("groups") + + req, err := g.client.NewRequest("POST", u, newGroup) + + if err != nil { + return nil, nil, err + } + + group := new(Group) + + resp, err := g.client.Do(req, group) + + if err != nil { + return nil, resp, err + } + + return group, resp, err +} + +// Delete - Deletes an OKTA Mastered Group with ID +func (g *GroupsService) Delete(groupID string) (*Response, error) { + + if groupID == "" { + return nil, errors.New("groupID parameter is required for Delete") + } + u := fmt.Sprintf("groups/%v", groupID) + + req, err := g.client.NewRequest("DELETE", u, nil) + + if err != nil { + return nil, err + } + + resp, err := g.client.Do(req, nil) + + if err != nil { + return resp, err + } + + return resp, err +} + +// AddUserToGroup - Adds a user to a group. +func (g *GroupsService) AddUserToGroup(groupID string, userID string) (*Response, error) { + + if groupID == "" { + return nil, errors.New("groupID parameter is required for Delete") + } + if userID == "" { + return nil, errors.New("groupID parameter is required for Delete") + } + + u := fmt.Sprintf("groups/%v/users/%v", groupID, userID) + + req, err := g.client.NewRequest("PUT", u, nil) + + if err != nil { + return nil, err + } + + resp, err := g.client.Do(req, nil) + + if err != nil { + return resp, err + } + + return resp, err +} + +// RemoveUserFromGroup - Removes a user to a group. +func (g *GroupsService) RemoveUserFromGroup(groupID string, userID string) (*Response, error) { + + if groupID == "" { + return nil, errors.New("groupID parameter is required for Delete") + } + if userID == "" { + return nil, errors.New("groupID parameter is required for Delete") + } + + u := fmt.Sprintf("groups/%v/users/%v", groupID, userID) + + req, err := g.client.NewRequest("DELETE", u, nil) + + if err != nil { + return nil, err + } + + resp, err := g.client.Do(req, nil) + + if err != nil { + return resp, err + } + + return resp, err +} + +// GroupUserFilterOptions is a struct that you populate which will limit or control group fetches and searches +// The values here will coorelate to the search filtering allowed in the OKTA API. These values are turned into Query Parameters +type GroupUserFilterOptions struct { + Limit int `url:"limit,omitempty"` + NextURL *url.URL `url:"-"` + GetAllPages bool `url:"-"` + NumberOfPages int `url:"-"` +} + +type newGroup struct { + Profile struct { + Name string `json:"name"` + Description string `json:"description"` + } `json:"profile"` +} diff --git a/vendor/github.com/chrismalek/oktasdk-go/okta/sdk.go b/vendor/github.com/chrismalek/oktasdk-go/okta/sdk.go new file mode 100644 index 0000000000000..ddfc250669b09 --- /dev/null +++ b/vendor/github.com/chrismalek/oktasdk-go/okta/sdk.go @@ -0,0 +1,523 @@ +package okta + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "regexp" + "strconv" + "sync" + "time" + + "github.com/google/go-querystring/query" + + "reflect" +) + +const ( + libraryVersion = "1" + userAgent = "oktasdk-go/" + libraryVersion + productionDomain = "okta.com" + previewDomain = "oktapreview.com" + urlFormat = "https://%s.%s/api/v1/" + headerRateLimit = "X-Rate-Limit-Limit" + headerRateRemaining = "X-Rate-Limit-Remaining" + headerRateReset = "X-Rate-Limit-Reset" + headerOKTARequestID = "X-Okta-Request-Id" + headerAuthorization = "Authorization" + headerAuthorizationFormat = "SSWS %v" + mediaTypeJSON = "application/json" + defaultLimit = 50 + // FilterEqualOperator Filter Operatorid for "equal" + FilterEqualOperator = "eq" + // FilterStartsWithOperator - filter operator for "starts with" + FilterStartsWithOperator = "sw" + // FilterGreaterThanOperator - filter operator for "greater than" + FilterGreaterThanOperator = "gt" + // FilterLessThanOperator - filter operator for "less than" + FilterLessThanOperator = "lt" + + // If the API returns a "X-Rate-Limit-Remaining" header less than this the SDK will either pause + // Or throw RateLimitError depending on the client.PauseOnRateLimit value + defaultRateRemainingFloor = 100 +) + +// A Client manages communication with the API. +type Client struct { + clientMu sync.Mutex // clientMu protects the client during calls that modify the CheckRedirect func. + client *http.Client // HTTP client used to communicate with the API. + + // Base URL for API requests. + // This will be built automatically based on inputs to NewClient + // If needed you can override this if needed (your URL is not *.okta.com or *.oktapreview.com) + BaseURL *url.URL + + // User agent used when communicating with the GitHub API. + UserAgent string + + apiKey string + authorizationHeaderValue string + PauseOnRateLimit bool + + // RateRemainingFloor - If the API returns a "X-Rate-Limit-Remaining" header less than this the SDK will either pause + // Or throw RateLimitError depending on the client.PauseOnRateLimit value. It defaults to 30 + // One client doing too much work can lock out all API Access for every other client + // We are trying to be a "good API User Citizen" + RateRemainingFloor int + + rateMu sync.Mutex + mostRecentRate Rate + + Limit int + // mostRecent rateLimitCategory + + common service // Reuse a single struct instead of allocating one for each service on the heap. + + // Services used for talking to different parts of the API. + // Service for Working with Users + Users *UsersService + + // Service for Working with Groups + Groups *GroupsService + + // Service for Working with Apps + Apps *AppsService +} + +type service struct { + client *Client +} + +// NewClient returns a new OKTA API client. If a nil httpClient is +// provided, http.DefaultClient will be used. +func NewClient(httpClient *http.Client, orgName string, apiToken string, isProduction bool) *Client { + var baseDomain string + if isProduction { + baseDomain = productionDomain + } else { + baseDomain = previewDomain + } + client, _ := NewClientWithDomain(httpClient, orgName, baseDomain, apiToken) + return client +} + +// NewClientWithDomain creates a client based on the organziation name and +// base domain for requests (okta.com, okta-emea.com, oktapreview.com, etc). +func NewClientWithDomain(httpClient *http.Client, orgName string, domain string, apiToken string) (*Client, error) { + baseURL, err := url.Parse(fmt.Sprintf(urlFormat, orgName, domain)) + if err != nil { + return nil, err + } + return NewClientWithBaseURL(httpClient, baseURL, apiToken), nil +} + +// NewClientWithBaseURL creates a client based on the full base URL and api +// token +func NewClientWithBaseURL(httpClient *http.Client, baseURL *url.URL, apiToken string) *Client { + if httpClient == nil { + httpClient = http.DefaultClient + } + + c := &Client{ + client: httpClient, + BaseURL: baseURL, + UserAgent: userAgent, + } + c.PauseOnRateLimit = true // If rate limit found it will block until that time. If false then Error will be returned + c.authorizationHeaderValue = fmt.Sprintf(headerAuthorizationFormat, apiToken) + c.apiKey = apiToken + c.Limit = defaultLimit + c.RateRemainingFloor = defaultRateRemainingFloor + c.common.client = c + + c.Users = (*UsersService)(&c.common) + c.Groups = (*GroupsService)(&c.common) + c.Apps = (*AppsService)(&c.common) + return c +} + +// Rate represents the rate limit for the current client. +type Rate struct { + // The number of requests per minute the client is currently limited to. + RatePerMinuteLimit int + + // The number of remaining requests the client can make this minute + Remaining int + + // The time at which the current rate limit will reset. + ResetTime time.Time +} + +// Response is a OKTA API response. This wraps the standard http.Response +// returned from OKTA and provides convenient access to things like +// pagination links. +type Response struct { + *http.Response + + // These fields provide the page values for paginating through a set of + // results. + + NextURL *url.URL + // PrevURL *url.URL + SelfURL *url.URL + OKTARequestID string + Rate +} + +// newResponse creates a new Response for the provided http.Response. +func newResponse(r *http.Response) *Response { + response := &Response{Response: r} + + response.OKTARequestID = r.Header.Get(headerOKTARequestID) + + response.populatePaginationURLS() + response.Rate = parseRate(r) + return response +} + +// populatePageValues parses the HTTP Link response headers and populates the +// various pagination link values in the Response. + +// OKTA LINK Header takes this form: +// Link: ; rel="next", +// ; rel="self" + +func (r *Response) populatePaginationURLS() { + + for k, v := range r.Header { + + if k == "Link" { + nextRegex := regexp.MustCompile(`<(.*?)>; rel="next"`) + // prevRegex := regexp.MustCompile(`<(.*?)>; rel="prev"`) + selfRegex := regexp.MustCompile(`<(.*?)>; rel="self"`) + + for _, linkValue := range v { + nextLinkMatch := nextRegex.FindStringSubmatch(linkValue) + if len(nextLinkMatch) != 0 { + r.NextURL, _ = url.Parse(nextLinkMatch[1]) + } + selfLinkMatch := selfRegex.FindStringSubmatch(linkValue) + if len(selfLinkMatch) != 0 { + r.SelfURL, _ = url.Parse(selfLinkMatch[1]) + } + // prevLinkMatch := prevRegex.FindStringSubmatch(linkValue) + // if len(prevLinkMatch) != 0 { + // r.PrevURL, _ = url.Parse(prevLinkMatch[1]) + // } + } + } + } + +} + +// parseRate parses the rate related headers. +func parseRate(r *http.Response) Rate { + var rate Rate + + if limit := r.Header.Get(headerRateLimit); limit != "" { + rate.RatePerMinuteLimit, _ = strconv.Atoi(limit) + } + if remaining := r.Header.Get(headerRateRemaining); remaining != "" { + rate.Remaining, _ = strconv.Atoi(remaining) + } + if reset := r.Header.Get(headerRateReset); reset != "" { + if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 { + rate.ResetTime = time.Unix(v, 0) + } + } + return rate +} + +// Do sends an API request and returns the API response. The API response is +// JSON decoded and stored in the value pointed to by v, or returned as an +// error if an API error has occurred. If v implements the io.Writer +// interface, the raw response body will be written to v, without attempting to +// first decode it. If rate limit is exceeded and reset time is in the future, +// Do returns rate immediately without making a network API call. +func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) { + + // If we've hit rate limit, don't make further requests before Reset time. + if err := c.checkRateLimitBeforeDo(req); err != nil { + return nil, err + } + + resp, err := c.client.Do(req) + if err != nil { + return nil, err + } + + defer func() { + // Drain up to 512 bytes and close the body to let the Transport reuse the connection + io.CopyN(ioutil.Discard, resp.Body, 512) + resp.Body.Close() + }() + + response := newResponse(resp) + + c.rateMu.Lock() + c.mostRecentRate.RatePerMinuteLimit = response.Rate.RatePerMinuteLimit + c.mostRecentRate.Remaining = response.Rate.Remaining + c.mostRecentRate.ResetTime = response.Rate.ResetTime + c.rateMu.Unlock() + + err = CheckResponse(resp) + if err != nil { + // even though there was an error, we still return the response + // in case the caller wants to inspect it further + // fmt.Printf("Error after sdk.Do return\n") + + return response, err + } + + if v != nil { + if w, ok := v.(io.Writer); ok { + io.Copy(w, resp.Body) + } else { + err = json.NewDecoder(resp.Body).Decode(v) + if err == io.EOF { + err = nil // ignore EOF errors caused by empty response body + } + } + } + + return response, err +} + +// checkRateLimitBeforeDo does not make any network calls, but uses existing knowledge from +// current client state in order to quickly check if *RateLimitError can be immediately returned +// from Client.Do, and if so, returns it so that Client.Do can skip making a network API call unnecessarily. +// Otherwise it returns nil, and Client.Do should proceed normally. +// http://developer.okta.com/docs/api/getting_started/design_principles.html#rate-limiting +func (c *Client) checkRateLimitBeforeDo(req *http.Request) error { + + c.rateMu.Lock() + mostRecentRate := c.mostRecentRate + c.rateMu.Unlock() + // fmt.Printf("checkRateLimitBeforeDo: \t Remaining = %d, \t ResetTime = %s\n", mostRecentRate.Remaining, mostRecentRate.ResetTime.String()) + if !mostRecentRate.ResetTime.IsZero() && mostRecentRate.Remaining < c.RateRemainingFloor && time.Now().Before(mostRecentRate.ResetTime) { + + if c.PauseOnRateLimit { + // If rate limit is hitting threshold then pause until the rate limit resets + // This behavior is controlled by the client PauseOnRateLimit value + // fmt.Printf("checkRateLimitBeforeDo: \t ***pause**** \t Time Now = %s \tPause After = %s\n", time.Now().String(), mostRecentRate.ResetTime.Sub(time.Now().Add(2*time.Second)).String()) + <-time.After(mostRecentRate.ResetTime.Sub(time.Now().Add(2 * time.Second))) + } else { + // fmt.Printf("checkRateLimitBeforeDo: \t ***error****\n") + + return &RateLimitError{ + Rate: mostRecentRate, + } + } + + } + + return nil +} + +// CheckResponse checks the API response for errors, and returns them if +// present. A response is considered an error if it has a status code outside +// the 200 range. API error responses are expected to have either no response +// body, or a JSON response body that maps to ErrorResponse. Any other +// response body will be silently ignored. +// +// The error type will be *RateLimitError for rate limit exceeded errors, +// and *TwoFactorAuthError for two-factor authentication errors. +// TODO - check un-authorized +func CheckResponse(r *http.Response) error { + if c := r.StatusCode; 200 <= c && c <= 299 { + return nil + } + + errorResp := &errorResponse{Response: r} + data, err := ioutil.ReadAll(r.Body) + if err == nil && data != nil { + json.Unmarshal(data, &errorResp.ErrorDetail) + } + switch { + case r.StatusCode == http.StatusTooManyRequests: + + return &RateLimitError{ + Rate: parseRate(r), + Response: r, + ErrorDetail: errorResp.ErrorDetail} + + default: + return errorResp + } + +} + +type apiError struct { + ErrorCode string `json:"errorCode"` + ErrorSummary string `json:"errorSummary"` + ErrorLink string `json:"errorLink"` + ErrorID string `json:"errorId"` + ErrorCauses []struct { + ErrorSummary string `json:"errorSummary"` + } `json:"errorCauses"` +} + +type errorResponse struct { + Response *http.Response // + ErrorDetail apiError +} + +func (r *errorResponse) Error() string { + return fmt.Sprintf("HTTP Method: %v - URL: %v: - HTTP Status Code: %d, OKTA Error Code: %v, OKTA Error Summary: %v, OKTA Error Causes: %v", + r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, r.ErrorDetail.ErrorCode, r.ErrorDetail.ErrorSummary, r.ErrorDetail.ErrorCauses) +} + +// RateLimitError occurs when OKTA returns 429 "Too Many Requests" response with a rate limit +// remaining value of 0, and error message starts with "API rate limit exceeded for ". +type RateLimitError struct { + Rate Rate // Rate specifies last known rate limit for the client + ErrorDetail apiError + Response *http.Response // +} + +func (r *RateLimitError) Error() string { + + return fmt.Sprintf("rate reset in %v", r.Rate.ResetTime.Sub(time.Now())) + +} + +// Code stolen from Github api libary +// Stringify attempts to create a reasonable string representation of types in +// the library. It does things like resolve pointers to their values +// and omits struct fields with nil values. +func stringify(message interface{}) string { + var buf bytes.Buffer + v := reflect.ValueOf(message) + stringifyValue(&buf, v) + return buf.String() +} + +// stringifyValue was heavily inspired by the goprotobuf library. + +func stringifyValue(w io.Writer, val reflect.Value) { + if val.Kind() == reflect.Ptr && val.IsNil() { + w.Write([]byte("")) + return + } + + v := reflect.Indirect(val) + + switch v.Kind() { + case reflect.String: + fmt.Fprintf(w, `"%s"`, v) + case reflect.Slice: + w.Write([]byte{'['}) + for i := 0; i < v.Len(); i++ { + if i > 0 { + w.Write([]byte{' '}) + } + + stringifyValue(w, v.Index(i)) + } + + w.Write([]byte{']'}) + return + case reflect.Struct: + if v.Type().Name() != "" { + w.Write([]byte(v.Type().String())) + } + w.Write([]byte{'{'}) + + var sep bool + for i := 0; i < v.NumField(); i++ { + fv := v.Field(i) + if fv.Kind() == reflect.Ptr && fv.IsNil() { + continue + } + if fv.Kind() == reflect.Slice && fv.IsNil() { + continue + } + + if sep { + w.Write([]byte(", ")) + } else { + sep = true + } + + w.Write([]byte(v.Type().Field(i).Name)) + w.Write([]byte{':'}) + stringifyValue(w, fv) + } + + w.Write([]byte{'}'}) + default: + if v.CanInterface() { + fmt.Fprint(w, v.Interface()) + } + } +} + +// NewRequest creates an API request. A relative URL can be provided in urlStr, +// in which case it is resolved relative to the BaseURL of the Client. +// Relative URLs should always be specified without a preceding slash. If +// specified, the value pointed to by body is JSON encoded and included as the +// request body. +func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) { + rel, err := url.Parse(urlStr) + if err != nil { + return nil, err + } + + u := c.BaseURL.ResolveReference(rel) + + var buf io.ReadWriter + if body != nil { + buf = new(bytes.Buffer) + err := json.NewEncoder(buf).Encode(body) + if err != nil { + return nil, err + } + } + + req, err := http.NewRequest(method, u.String(), buf) + if err != nil { + return nil, err + } + if c.apiKey != "" { + req.Header.Set(headerAuthorization, fmt.Sprintf(headerAuthorizationFormat, c.apiKey)) + } + if body != nil { + req.Header.Set("Content-Type", mediaTypeJSON) + } + + if c.UserAgent != "" { + req.Header.Set("User-Agent", c.UserAgent) + } + return req, nil +} + +// addOptions adds the parameters in opt as URL query parameters to s. opt +// must be a struct whose fields may contain "url" tags. +func addOptions(s string, opt interface{}) (string, error) { + v := reflect.ValueOf(opt) + if v.Kind() == reflect.Ptr && v.IsNil() { + return s, nil + } + + u, err := url.Parse(s) + if err != nil { + return s, err + } + + qs, err := query.Values(opt) + if err != nil { + return s, err + } + + u.RawQuery = qs.Encode() + return u.String(), nil +} + +type dateFilter struct { + Value time.Time + Operator string +} diff --git a/vendor/github.com/chrismalek/oktasdk-go/okta/users.go b/vendor/github.com/chrismalek/oktasdk-go/okta/users.go new file mode 100644 index 0000000000000..8102a819eece8 --- /dev/null +++ b/vendor/github.com/chrismalek/oktasdk-go/okta/users.go @@ -0,0 +1,625 @@ +package okta + +import ( + "errors" + "fmt" + "net/url" + "time" +) + +const ( + profileEmailFilter = "profile.email" + profileLoginFilter = "profile.login" + profileStatusFilter = "status" + profileIDFilter = "id" + profileFirstNameFilter = "profile.firstName" + profileLastNameFilter = "profile.lastName" + profileLastUpdatedFilter = "lastUpdated" + // UserStatusActive is a constant to represent OKTA User State returned by the API + UserStatusActive = "ACTIVE" + // UserStatusStaged is a constant to represent OKTA User State returned by the API + UserStatusStaged = "STAGED" + // UserStatusProvisioned is a constant to represent OKTA User State returned by the API + UserStatusProvisioned = "PROVISIONED" + // UserStatusRecovery is a constant to represent OKTA User State returned by the API + UserStatusRecovery = "RECOVERY" + // UserStatusLockedOut is a constant to represent OKTA User State returned by the API + UserStatusLockedOut = "LOCKED_OUT" + // UserStatusPasswordExpired is a constant to represent OKTA User State returned by the API + UserStatusPasswordExpired = "PASSWORD_EXPIRED" + // UserStatusSuspended is a constant to represent OKTA User State returned by the API + UserStatusSuspended = "SUSPENDED" + // UserStatusDeprovisioned is a constant to represent OKTA User State returned by the API + UserStatusDeprovisioned = "DEPROVISIONED" + + oktaFilterTimeFormat = "2006-01-02T15:05:05.000Z" +) + +// UsersService handles communication with the User data related +// methods of the OKTA API. +type UsersService service + +// ActivationResponse - Response coming back from a user activation +type ActivationResponse struct { + ActivationURL string `json:"activationUrl"` +} + +type provider struct { + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` +} + +type recoveryQuestion struct { + Question string `json:"question,omitempty"` + Answer string `json:"answer,omitempty"` +} + +type passwordValue struct { + Value string `json:"value,omitempty"` +} +type credentials struct { + Password *passwordValue `json:"password,omitempty"` + Provider *provider `json:"provider,omitempty"` + RecoveryQuestion *recoveryQuestion `json:"recovery_question,omitempty"` +} + +type userProfile struct { + Email string `json:"email"` + FirstName string `json:"firstName"` + LastName string `json:"lastName"` + Login string `json:"login"` + MobilePhone string `json:"mobilePhone,omitempty"` + SecondEmail string `json:"secondEmail,omitempty"` + PsEmplid string `json:"psEmplid,omitempty"` + NickName string `json:"nickname,omitempty"` + DisplayName string `json:"displayName,omitempty"` + + ProfileURL string `json:"profileUrl,omitempty"` + PreferredLanguage string `json:"preferredLanguage,omitempty"` + UserType string `json:"userType,omitempty"` + Organization string `json:"organization,omitempty"` + Title string `json:"title,omitempty"` + Division string `json:"division,omitempty"` + Department string `json:"department,omitempty"` + CostCenter string `json:"costCenter,omitempty"` + EmployeeNumber string `json:"employeeNumber,omitempty"` + PrimaryPhone string `json:"primaryPhone,omitempty"` + StreetAddress string `json:"streetAddress,omitempty"` + City string `json:"city,omitempty"` + State string `json:"state,omitempty"` + ZipCode string `json:"zipCode,omitempty"` + CountryCode string `json:"countryCode,omitempty"` +} + +type userLinks struct { + ChangePassword struct { + Href string `json:"href"` + } `json:"changePassword"` + ChangeRecoveryQuestion struct { + Href string `json:"href"` + } `json:"changeRecoveryQuestion"` + Deactivate struct { + Href string `json:"href"` + } `json:"deactivate"` + ExpirePassword struct { + Href string `json:"href"` + } `json:"expirePassword"` + ForgotPassword struct { + Href string `json:"href"` + } `json:"forgotPassword"` + ResetFactors struct { + Href string `json:"href"` + } `json:"resetFactors"` + ResetPassword struct { + Href string `json:"href"` + } `json:"resetPassword"` +} + +// User is a struct that represents a user object from OKTA. +type User struct { + Activated string `json:"activated,omitempty"` + Created string `json:"created,omitempty"` + Credentials credentials `json:"credentials,omitempty"` + ID string `json:"id,omitempty"` + LastLogin string `json:"lastLogin,omitempty"` + LastUpdated string `json:"lastUpdated,omitempty"` + PasswordChanged string `json:"passwordChanged,omitempty"` + Profile userProfile `json:"profile"` + Status string `json:"status,omitempty"` + StatusChanged string `json:"statusChanged,omitempty"` + Links userLinks `json:"_links,omitempty"` + MFAFactors []userMFAFactor `json:"-,"` + Groups []Group `json:"-"` +} + +type userMFAFactor struct { + ID string `json:"id,omitempty"` + FactorType string `json:"factorType,omitempty"` + Provider string `json:"provider,omitempty"` + VendorName string `json:"vendorName,omitempty"` + Status string `json:"status,omitempty"` + Created time.Time `json:"created,omitempty"` + LastUpdated time.Time `json:"lastUpdated,omitempty"` + Profile struct { + CredentialID string `json:"credentialId,omitempty"` + } `json:"profile,omitempty"` +} + +// NewUser object to create user objects in OKTA +type NewUser struct { + Profile userProfile `json:"profile"` + Credentials *credentials `json:"credentials,omitempty"` +} + +type newPasswordSet struct { + Credentials credentials `json:"credentials"` +} + +// ResetPasswordResponse struct that returns data about the password reset +type ResetPasswordResponse struct { + ResetPasswordURL string `json:"resetPasswordUrl"` +} + +// NewUser - Returns a new user object. This is used to create users in OKTA. It only has the properties that +// OKTA will take as input. The "User" object has more feilds that are OKTA returned like the ID, etc +func (s *UsersService) NewUser() NewUser { + return NewUser{} +} + +// SetPassword Adds a specified password to the new User +func (u *NewUser) SetPassword(passwordIn string) { + + if passwordIn != "" { + + pass := new(passwordValue) + pass.Value = passwordIn + + var cred *credentials + if u.Credentials == nil { + cred = new(credentials) + } else { + cred = u.Credentials + } + + cred.Password = pass + u.Credentials = cred + + } +} + +// SetRecoveryQuestion - Sets a custom security question and answer on a user object +func (u *NewUser) SetRecoveryQuestion(questionIn string, answerIn string) { + + if questionIn != "" && answerIn != "" { + recovery := new(recoveryQuestion) + + recovery.Question = questionIn + recovery.Answer = answerIn + + var cred *credentials + if u.Credentials == nil { + cred = new(credentials) + } else { + cred = u.Credentials + } + cred.RecoveryQuestion = recovery + u.Credentials = cred + + } +} + +func (u User) String() string { + return stringify(u) + // return fmt.Sprintf("ID: %v \tLogin: %v", u.ID, u.Profile.Login) +} + +// GetByID returns a user object for a specific OKTA ID. +// Generally the id input string is the cryptic OKTA key value from User.ID. However, the OKTA API may accept other values like "me", or login shortname +func (s *UsersService) GetByID(id string) (*User, *Response, error) { + u := fmt.Sprintf("users/%v", id) + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + user := new(User) + resp, err := s.client.Do(req, user) + if err != nil { + return nil, resp, err + } + + return user, resp, err +} + +// UserListFilterOptions is a struct that you can populate which will "filter" user searches +// the exported struct fields should allow you to do different filters based on what is allowed in the OKTA API. +// The filter OKTA API is limited in the fields it can search +// NOTE: In the current form you can't add parenthesis and ordering +// OKTA API Supports only a limited number of properties: +// status, lastUpdated, id, profile.login, profile.email, profile.firstName, and profile.lastName. +// http://developer.okta.com/docs/api/resources/users.html#list-users-with-a-filter +type UserListFilterOptions struct { + Limit int `url:"limit,omitempty"` + EmailEqualTo string `url:"-"` + LoginEqualTo string `url:"-"` + StatusEqualTo string `url:"-"` + IDEqualTo string `url:"-"` + + FirstNameEqualTo string `url:"-"` + LastNameEqualTo string `url:"-"` + // API documenation says you can search with "starts with" but these don't work + + // FirstNameStartsWith string `url:"-"` + // LastNameStartsWith string `url:"-"` + + // This will be built by internal - may not need to export + FilterString string `url:"filter,omitempty"` + NextURL *url.URL `url:"-"` + GetAllPages bool `url:"-"` + NumberOfPages int `url:"-"` + LastUpdated dateFilter `url:"-"` +} + +// PopulateGroups will populate the groups a user is a member of. You pass in a pointer to an existing users +func (s *UsersService) PopulateGroups(user *User) (*Response, error) { + u := fmt.Sprintf("users/%v/groups", user.ID) + req, err := s.client.NewRequest("GET", u, nil) + + if err != nil { + return nil, err + } + // Get first page of users. + resp, err := s.client.Do(req, &user.Groups) + if err != nil { + return resp, err + } + // Look for any remaining user group pages. + var nextURL string + if resp.NextURL != nil { + nextURL = resp.NextURL.String() + } + for { + + if nextURL != "" { + req, err := s.client.NewRequest("GET", nextURL, nil) + userGroupsPages := []Group{} + + resp, err := s.client.Do(req, &userGroupsPages) + nextURL = "" + if err != nil { + return resp, err + } + user.Groups = append(user.Groups, userGroupsPages...) + if resp.NextURL != nil { + nextURL = resp.NextURL.String() + } + + } else { + return resp, err + } + + } + +} + +// PopulateEnrolledFactors will populate the Enrolled MFA Factors a user is a member of. +// You pass in a pointer to an existing users +// http://developer.okta.com/docs/api/resources/factors.html#list-enrolled-factors +func (s *UsersService) PopulateEnrolledFactors(user *User) (*Response, error) { + u := fmt.Sprintf("users/%v/factors", user.ID) + req, err := s.client.NewRequest("GET", u, nil) + + if err != nil { + return nil, err + } + // TODO: If user has more than 200 groups this will only return those first 200 + resp, err := s.client.Do(req, &user.MFAFactors) + if err != nil { + return resp, err + } + + return resp, err +} + +// List users with status of LOCKED_OUT +// filter=status eq "LOCKED_OUT" +// List users updated after 06/01/2013 but before 01/01/2014 +// filter=lastUpdated gt "2013-06-01T00:00:00.000Z" and lastUpdated lt "2014-01-01T00:00:00.000Z" +// List users updated after 06/01/2013 but before 01/01/2014 with a status of ACTIVE +// filter=lastUpdated gt "2013-06-01T00:00:00.000Z" and lastUpdated lt "2014-01-01T00:00:00.000Z" and status eq "ACTIVE" +// TODO - Currently no way to do parenthesis +// List users updated after 06/01/2013 but with a status of LOCKED_OUT or RECOVERY +// filter=lastUpdated gt "2013-06-01T00:00:00.000Z" and (status eq "LOCKED_OUT" or status eq "RECOVERY") + +// OTKA API docs: http://developer.okta.com/docs/api/resources/users.html#list-users-with-a-filter + +func appendToFilterString(currFilterString string, appendFilterKey string, appendFilterOperator string, appendFilterValue string) (rs string) { + if currFilterString != "" { + rs = fmt.Sprintf("%v and %v %v \"%v\"", currFilterString, appendFilterKey, appendFilterOperator, appendFilterValue) + } else { + rs = fmt.Sprintf("%v %v \"%v\"", appendFilterKey, appendFilterOperator, appendFilterValue) + } + + return rs +} + +// ListWithFilter will use the input UserListFilterOptions to find users and return a paged result set +func (s *UsersService) ListWithFilter(opt *UserListFilterOptions) ([]User, *Response, error) { + var u string + var err error + + pagesRetreived := 0 + + if opt.NextURL != nil { + u = opt.NextURL.String() + } else { + if opt.EmailEqualTo != "" { + opt.FilterString = appendToFilterString(opt.FilterString, profileEmailFilter, FilterEqualOperator, opt.EmailEqualTo) + } + if opt.LoginEqualTo != "" { + opt.FilterString = appendToFilterString(opt.FilterString, profileLoginFilter, FilterEqualOperator, opt.LoginEqualTo) + } + + if opt.StatusEqualTo != "" { + opt.FilterString = appendToFilterString(opt.FilterString, profileStatusFilter, FilterEqualOperator, opt.StatusEqualTo) + } + + if opt.IDEqualTo != "" { + opt.FilterString = appendToFilterString(opt.FilterString, profileIDFilter, FilterEqualOperator, opt.IDEqualTo) + } + + if opt.FirstNameEqualTo != "" { + opt.FilterString = appendToFilterString(opt.FilterString, profileFirstNameFilter, FilterEqualOperator, opt.FirstNameEqualTo) + } + + if opt.LastNameEqualTo != "" { + opt.FilterString = appendToFilterString(opt.FilterString, profileLastNameFilter, FilterEqualOperator, opt.LastNameEqualTo) + } + + // API documenation says you can search with "starts with" but these don't work + // if opt.FirstNameStartsWith != "" { + // opt.FilterString = appendToFilterString(opt.FilterString, profileFirstNameFilter, filterStartsWithOperator, opt.FirstNameStartsWith) + // } + + // if opt.LastNameStartsWith != "" { + // opt.FilterString = appendToFilterString(opt.FilterString, profileLastNameFilter, filterStartsWithOperator, opt.LastNameStartsWith) + // } + + if !opt.LastUpdated.Value.IsZero() { + opt.FilterString = appendToFilterString(opt.FilterString, profileLastUpdatedFilter, opt.LastUpdated.Operator, opt.LastUpdated.Value.UTC().Format(oktaFilterTimeFormat)) + } + + if opt.Limit == 0 { + opt.Limit = defaultLimit + } + + u, err = addOptions("users", opt) + + } + + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + users := make([]User, 1) + resp, err := s.client.Do(req, &users) + if err != nil { + return nil, resp, err + } + + pagesRetreived++ + + if (opt.NumberOfPages > 0 && pagesRetreived < opt.NumberOfPages) || opt.GetAllPages { + + for { + + if pagesRetreived == opt.NumberOfPages { + break + } + if resp.NextURL != nil { + var userPage []User + pageOption := new(UserListFilterOptions) + pageOption.NextURL = resp.NextURL + pageOption.NumberOfPages = 1 + pageOption.Limit = opt.Limit + + userPage, resp, err = s.ListWithFilter(pageOption) + if err != nil { + return users, resp, err + } + users = append(users, userPage...) + pagesRetreived++ + } else { + break + } + } + } + return users, resp, err +} + +// Create - Creates a new user. You must pass in a "newUser" object created from Users.NewUser() +// There are many differnt reasons that OKTA may reject the request so you have to check the error messages +func (s *UsersService) Create(userIn NewUser, createAsActive bool) (*User, *Response, error) { + + u := fmt.Sprintf("users?activate=%v", createAsActive) + + req, err := s.client.NewRequest("POST", u, userIn) + + if err != nil { + return nil, nil, err + } + + newUser := new(User) + resp, err := s.client.Do(req, newUser) + if err != nil { + return nil, resp, err + } + + return newUser, resp, err +} + +// Activate Activates a user. You can have OKTA send an email by including a "sendEmail=true" +// If you pass in sendEmail=false, then activationResponse.ActivationURL will have a string URL that +// can be sent to the end user. You can discard response if sendEmail=true +func (s *UsersService) Activate(id string, sendEmail bool) (*ActivationResponse, *Response, error) { + u := fmt.Sprintf("users/%v/lifecycle/activate?sendEmail=%v", id, sendEmail) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + + activationInfo := new(ActivationResponse) + resp, err := s.client.Do(req, activationInfo) + + if err != nil { + return nil, resp, err + } + + return activationInfo, resp, err +} + +// Deactivate - Deactivates a user +func (s *UsersService) Deactivate(id string) (*Response, error) { + u := fmt.Sprintf("users/%v/lifecycle/deactivate", id) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, err + } + resp, err := s.client.Do(req, nil) + + if err != nil { + return resp, err + } + + return resp, err +} + +// Suspend - Suspends a user - If user is NOT active an Error will come back based on OKTA API: +// http://developer.okta.com/docs/api/resources/users.html#suspend-user +func (s *UsersService) Suspend(id string) (*Response, error) { + u := fmt.Sprintf("users/%v/lifecycle/suspend", id) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, err + } + resp, err := s.client.Do(req, nil) + + if err != nil { + return resp, err + } + + return resp, err +} + +// Unsuspend - Unsuspends a user - If user is NOT SUSPENDED, an Error will come back based on OKTA API: +// http://developer.okta.com/docs/api/resources/users.html#unsuspend-user +func (s *UsersService) Unsuspend(id string) (*Response, error) { + u := fmt.Sprintf("users/%v/lifecycle/unsuspend", id) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, err + } + resp, err := s.client.Do(req, nil) + + if err != nil { + return resp, err + } + + return resp, err +} + +// Unlock - Unlocks a user - Per docs, only for OKTA Mastered Account +// http://developer.okta.com/docs/api/resources/users.html#unlock-user +func (s *UsersService) Unlock(id string) (*Response, error) { + u := fmt.Sprintf("users/%v/lifecycle/unlock", id) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, err + } + resp, err := s.client.Do(req, nil) + + if err != nil { + return resp, err + } + + return resp, err +} + +// SetPassword - Sets a user password to an Admin provided String +func (s *UsersService) SetPassword(id string, newPassword string) (*User, *Response, error) { + + if id == "" || newPassword == "" { + return nil, nil, errors.New("please provide a User ID and Password") + } + + passwordUpdate := new(newPasswordSet) + + pass := new(passwordValue) + pass.Value = newPassword + + passwordUpdate.Credentials.Password = pass + + u := fmt.Sprintf("users/%v", id) + req, err := s.client.NewRequest("POST", u, passwordUpdate) + if err != nil { + return nil, nil, err + } + + user := new(User) + resp, err := s.client.Do(req, user) + if err != nil { + return nil, resp, err + } + + return user, resp, err +} + +// ResetPassword - Generates a one-time token (OTT) that can be used to reset a user’s password. +// The OTT link can be automatically emailed to the user or returned to the API caller and distributed using a custom flow. +// http://developer.okta.com/docs/api/resources/users.html#reset-password +// If you pass in sendEmail=false, then resetPasswordResponse.resetPasswordUrl will have a string URL that +// can be sent to the end user. You can discard response if sendEmail=true +func (s *UsersService) ResetPassword(id string, sendEmail bool) (*ResetPasswordResponse, *Response, error) { + u := fmt.Sprintf("users/%v/lifecycle/reset_password?sendEmail=%v", id, sendEmail) + + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, nil, err + } + + resetInfo := new(ResetPasswordResponse) + resp, err := s.client.Do(req, resetInfo) + + if err != nil { + return nil, resp, err + } + + return resetInfo, resp, err +} + +// PopulateMFAFactors will populate the MFA Factors a user is a member of. You pass in a pointer to an existing users +func (s *UsersService) PopulateMFAFactors(user *User) (*Response, error) { + u := fmt.Sprintf("users/%v/factors", user.ID) + + req, err := s.client.NewRequest("GET", u, nil) + + if err != nil { + return nil, err + } + + resp, err := s.client.Do(req, &user.MFAFactors) + if err != nil { + return resp, err + } + + return resp, err +} diff --git a/vendor/github.com/okta/okta-sdk-golang/okta/config.go b/vendor/github.com/okta/okta-sdk-golang/okta/config.go index e0d8c0e06f226..e25e3d2b063ff 100644 --- a/vendor/github.com/okta/okta-sdk-golang/okta/config.go +++ b/vendor/github.com/okta/okta-sdk-golang/okta/config.go @@ -36,13 +36,9 @@ type config struct { Username string `yaml:"username" envconfig:"OKTA_CLIENT_PROXY_USERNAME"` Password string `yaml:"password" envconfig:"OKTA_CLIENT_PROXY_PASSWORD"` } `yaml:"proxy"` - ConnectionTimeout int32 `yaml:"connectionTimeout" envconfig:"OKTA_CLIENT_CONNECTION_TIMEOUT"` - RequestTimeout int32 `yaml:"requestTimeout" envconfig:"OKTA_CLIENT_REQUEST_TIMEOUT"` - RateLimit struct { - MaxRetries int32 `yaml:"maxRetries" envconfig:"OKTA_CLIENT_RATE_LIMIT_MAX_RETRIES"` - } `yaml:"rateLimit"` - OrgUrl string `yaml:"orgUrl" envconfig:"OKTA_CLIENT_ORGURL"` - Token string `yaml:"token" envconfig:"OKTA_CLIENT_TOKEN"` + ConnectionTimeout int32 `yaml:"connectionTimeout" envconfig:"OKTA_CLIENT_CONNECTION_TIMEOUT"` + OrgUrl string `yaml:"orgUrl" envconfig:"OKTA_CLIENT_ORGURL"` + Token string `yaml:"token" envconfig:"OKTA_CLIENT_TOKEN"` } `yaml:"client"` Testing struct { DisableHttpsCheck bool `yaml:"disableHttpsCheck" envconfig:"OKTA_TESTING_DISABLE_HTTPS_CHECK"` @@ -53,31 +49,6 @@ type config struct { CacheManager cache.Cache } -func NewConfig(conf ...ConfigSetter) (*config, error) { - config := &config{} - - setConfigDefaults(config) - config = readConfigFromSystem(*config) - config = readConfigFromApplication(*config) - config = readConfigFromEnvironment(*config) - - for _, confSetter := range conf { - confSetter(config) - } - return config, nil -} - -func NewCache(config *config) (cache.Cache, error) { - if !config.Okta.Client.Cache.Enabled { - return cache.NewNoOpCache(), nil - } - if config.CacheManager != nil { - return config.CacheManager, nil - } - return cache.NewGoCache(config.Okta.Client.Cache.DefaultTtl, - config.Okta.Client.Cache.DefaultTti), nil -} - type ConfigSetter func(*config) func WithCache(cache bool) ConfigSetter { @@ -163,15 +134,3 @@ func WithTestingDisableHttpsCheck(httpsCheck bool) ConfigSetter { c.Okta.Testing.DisableHttpsCheck = httpsCheck } } - -func WithRequestTimeout(requestTimeout int32) ConfigSetter { - return func(c *config) { - c.Okta.Client.RequestTimeout = requestTimeout - } -} - -func WithRateLimitMaxRetries(maxRetries int32) ConfigSetter { - return func(c *config) { - c.Okta.Client.RateLimit.MaxRetries = maxRetries - } -} diff --git a/vendor/github.com/okta/okta-sdk-golang/okta/okta.go b/vendor/github.com/okta/okta-sdk-golang/okta/okta.go index bf8d06220e318..e4838576f44f6 100644 --- a/vendor/github.com/okta/okta-sdk-golang/okta/okta.go +++ b/vendor/github.com/okta/okta-sdk-golang/okta/okta.go @@ -24,6 +24,8 @@ import ( "io/ioutil" "os/user" + "github.com/okta/okta-sdk-golang/okta/cache" + "github.com/go-yaml/yaml" "github.com/kelseyhightower/envconfig" ) @@ -51,26 +53,39 @@ type resource struct { } func NewClient(ctx context.Context, conf ...ConfigSetter) (*Client, error) { - config, err := NewConfig(conf...) - if err != nil { - return nil, err + config := &config{} + + setConfigDefaults(config) + config = readConfigFromSystem(*config) + config = readConfigFromApplication(*config) + config = readConfigFromEnvironment(*config) + + for _, confSetter := range conf { + confSetter(config) } - cache, err := NewCache(config) - if err != nil { - return nil, err + var oktaCache cache.Cache + if !config.Okta.Client.Cache.Enabled { + oktaCache = cache.NewNoOpCache() + } else { + if config.CacheManager == nil { + oktaCache = cache.NewGoCache(config.Okta.Client.Cache.DefaultTtl, + config.Okta.Client.Cache.DefaultTti) + } else { + oktaCache = config.CacheManager + } } - config.CacheManager = cache + config.CacheManager = oktaCache - config, err = ValidateConfig(config) + config, err := validateConfig(config) if err != nil { panic(err) } c := &Client{} c.config = config - c.requestExecutor = NewRequestExecutor(&config.HttpClient, cache, config) + c.requestExecutor = NewRequestExecutor(&config.HttpClient, oktaCache, config) c.resource.client = c @@ -100,10 +115,8 @@ func setConfigDefaults(c *config) { WithCache(true), WithCacheTtl(300), WithCacheTti(300), - WithUserAgentExtra(""), - WithTestingDisableHttpsCheck(false), - WithRequestTimeout(0), - WithRateLimitMaxRetries(2)) + WithUserAgentExtra("")) + WithTestingDisableHttpsCheck(false) for _, confSetter := range conf { confSetter(c) diff --git a/vendor/github.com/okta/okta-sdk-golang/okta/requestExecutor.go b/vendor/github.com/okta/okta-sdk-golang/okta/requestExecutor.go index 0907366069b8d..5ce029accc915 100644 --- a/vendor/github.com/okta/okta-sdk-golang/okta/requestExecutor.go +++ b/vendor/github.com/okta/okta-sdk-golang/okta/requestExecutor.go @@ -19,15 +19,11 @@ package okta import ( "bytes" "encoding/json" - "errors" - "fmt" "io" "io/ioutil" "net/http" "net/url" "reflect" - "sort" - "strconv" "time" "github.com/okta/okta-sdk-golang/okta/cache" @@ -86,7 +82,6 @@ func (re *RequestExecutor) NewRequest(method string, url string, body interface{ } func (re *RequestExecutor) Do(req *http.Request, v interface{}) (*Response, error) { - requestStarted := time.Now().Unix() cacheKey := cache.CreateCacheKey(req) if req.Method != http.MethodGet { re.cache.Delete(cacheKey) @@ -94,23 +89,26 @@ func (re *RequestExecutor) Do(req *http.Request, v interface{}) (*Response, erro inCache := re.cache.Has(cacheKey) if !inCache { - - resp, err := re.doWithRetries(req, 0, requestStarted, nil) - + resp, err := re.httpClient.Do(req) if err != nil { return nil, err } defer resp.Body.Close() + respBody, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } + origResp := ioutil.NopCloser(bytes.NewBuffer(respBody)) resp.Body = origResp - if resp.StatusCode >= 200 && resp.StatusCode <= 299 && req.Method == http.MethodGet && reflect.TypeOf(v).Kind() != reflect.Slice { + + if req.Method == http.MethodGet && reflect.TypeOf(v).Kind() != reflect.Slice { re.cache.Set(cacheKey, resp) } + return buildResponse(resp, &v) + } resp := re.cache.Get(cacheKey) @@ -118,93 +116,6 @@ func (re *RequestExecutor) Do(req *http.Request, v interface{}) (*Response, erro } -func (re *RequestExecutor) doWithRetries(req *http.Request, retryCount int32, requestStarted int64, lastResponse *http.Response) (*http.Response, error) { - iterationStart := time.Now().Unix() - maxRetries := re.config.Okta.Client.RateLimit.MaxRetries - requestTimeout := int64(re.config.Okta.Client.RequestTimeout) - - if req.Body != nil { - bodyBytes, _ := ioutil.ReadAll(req.Body) - req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) - } - - if requestTimeout > 0 && (iterationStart-requestStarted) >= requestTimeout { - return lastResponse, errors.New("reached the max request time") - } - - resp, err := re.httpClient.Do(req) - - if (err != nil || tooManyRequests(resp)) && retryCount < maxRetries { - if resp != nil { - err := tryDrainBody(resp.Body) - if err != nil { - return nil, err - } - } - - retryLimitReset := resp.Header.Get("X-Rate-Limit-Reset") - date := resp.Header.Get("Date") - if retryLimitReset == "" || date == "" { - return resp, errors.New("a 429 response must include the x-retry-limit-reset and date headers") - } - - if tooManyRequests(resp) { - err := backoffPause(retryCount, resp) - if err != nil { - return nil, err - } - } - retryCount++ - - req.Header.Add("X-Okta-Retry-For", resp.Header.Get("X-Okta-Request-Id")) - req.Header.Add("X-Okta-Retry-Count", fmt.Sprint(retryCount)) - - resp, err = re.doWithRetries(req, retryCount, requestStarted, resp) - } - - return resp, err -} - -func tooManyRequests(resp *http.Response) bool { - return resp != nil && resp.StatusCode == http.StatusTooManyRequests -} - -func tryDrainBody(body io.ReadCloser) error { - defer body.Close() - _, err := io.Copy(ioutil.Discard, io.LimitReader(body, 4096)) - if err != nil { - return err - } - return nil -} - -func backoffPause(retryCount int32, response *http.Response) error { - if response.StatusCode == http.StatusTooManyRequests { - backoffSeconds := Get429BackoffTime(response) - time.Sleep(time.Duration(backoffSeconds) * time.Second) - - return nil - } - - return nil -} - -func Get429BackoffTime(response *http.Response) int64 { - var limitResetMap []int - - for _, time := range response.Header["X-Rate-Limit-Reset"] { - timestamp, _ := strconv.Atoi(time) - limitResetMap = append(limitResetMap, timestamp) - } - - sort.Ints(limitResetMap) - - requestDate, _ := time.Parse("Mon, 02 Jan 2006 15:04:05 Z", response.Header.Get("Date")) - requestDateUnix := requestDate.Unix() - backoffSeconds := int64(limitResetMap[0]) - requestDateUnix + 1 - return backoffSeconds -} - type Response struct { *http.Response } diff --git a/vendor/github.com/okta/okta-sdk-golang/okta/validator.go b/vendor/github.com/okta/okta-sdk-golang/okta/validator.go index 1f3106567a89e..2a639d7a23511 100644 --- a/vendor/github.com/okta/okta-sdk-golang/okta/validator.go +++ b/vendor/github.com/okta/okta-sdk-golang/okta/validator.go @@ -5,15 +5,15 @@ import ( "strings" ) -func ValidateConfig(c *config) (*config, error) { +func validateConfig(c *config) (*config, error) { var err error - err = ValidateOktaDomain(c) + err = validateOktaDomain(c) if err != nil { return nil, err } - err = ValidateApiToken(c) + err = validateApiToken(c) if err != nil { return nil, err } @@ -21,7 +21,7 @@ func ValidateConfig(c *config) (*config, error) { return c, nil } -func ValidateOktaDomain(c *config) error { +func validateOktaDomain(c *config) error { if c.Okta.Client.OrgUrl == "" { return errors.New("your Okta URL is missing. You can copy your domain from the Okta Developer Console. Follow these instructions to find it: https://bit.ly/finding-okta-domain") } @@ -48,7 +48,7 @@ func ValidateOktaDomain(c *config) error { return nil } -func ValidateApiToken(c *config) error { +func validateApiToken(c *config) error { if c.Okta.Client.Token == "" { return errors.New("your Okta API token is missing. You can generate one in the Okta Developer Console. Follow these instructions: https://bit.ly/get-okta-api-token") } diff --git a/vendor/modules.txt b/vendor/modules.txt index af8f3b09e05b1..5069a9a3975f9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,33 +1,33 @@ # cloud.google.com/go v0.39.0 +cloud.google.com/go/monitoring/apiv3 +cloud.google.com/go/storage +cloud.google.com/go/spanner cloud.google.com/go/civil cloud.google.com/go/compute/metadata +cloud.google.com/go/kms/apiv1 cloud.google.com/go/iam cloud.google.com/go/internal -cloud.google.com/go/internal/fields cloud.google.com/go/internal/optional -cloud.google.com/go/internal/protostruct cloud.google.com/go/internal/trace cloud.google.com/go/internal/version -cloud.google.com/go/kms/apiv1 -cloud.google.com/go/monitoring/apiv3 -cloud.google.com/go/spanner +cloud.google.com/go/internal/fields +cloud.google.com/go/internal/protostruct cloud.google.com/go/spanner/internal/backoff -cloud.google.com/go/storage # code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f code.cloudfoundry.org/gofileutils/fileutils # github.com/Azure/azure-sdk-for-go v36.2.0+incompatible +github.com/Azure/azure-sdk-for-go/storage +github.com/Azure/azure-sdk-for-go/services/keyvault/v7.0/keyvault github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2017-12-01/compute github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac -github.com/Azure/azure-sdk-for-go/services/keyvault/v7.0/keyvault github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2018-01-01-preview/authorization -github.com/Azure/azure-sdk-for-go/storage github.com/Azure/azure-sdk-for-go/version # github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 -github.com/Azure/go-ansiterm github.com/Azure/go-ansiterm/winterm +github.com/Azure/go-ansiterm # github.com/Azure/go-autorest/autorest v0.9.2 -github.com/Azure/go-autorest/autorest github.com/Azure/go-autorest/autorest/azure +github.com/Azure/go-autorest/autorest # github.com/Azure/go-autorest/autorest/adal v0.7.0 github.com/Azure/go-autorest/autorest/adal # github.com/Azure/go-autorest/autorest/azure/auth v0.4.0 @@ -62,27 +62,27 @@ github.com/Nvveen/Gotty # github.com/SAP/go-hdb v0.14.1 github.com/SAP/go-hdb/driver github.com/SAP/go-hdb/driver/sqltrace -github.com/SAP/go-hdb/internal/bufio github.com/SAP/go-hdb/internal/protocol +github.com/SAP/go-hdb/internal/bufio github.com/SAP/go-hdb/internal/unicode github.com/SAP/go-hdb/internal/unicode/cesu8 # github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 github.com/StackExchange/wmi # github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f -github.com/aliyun/alibaba-cloud-sdk-go/sdk github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth -github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials -github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/providers -github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints +github.com/aliyun/alibaba-cloud-sdk-go/services/sts +github.com/aliyun/alibaba-cloud-sdk-go/sdk +github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials +github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils github.com/aliyun/alibaba-cloud-sdk-go/services/kms +github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider github.com/aliyun/alibaba-cloud-sdk-go/services/ram -github.com/aliyun/alibaba-cloud-sdk-go/services/sts # github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 github.com/aliyun/aliyun-oss-go-sdk/oss # github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2 @@ -103,53 +103,53 @@ github.com/armon/go-radix github.com/asaskevich/govalidator # github.com/aws/aws-sdk-go v1.25.41 github.com/aws/aws-sdk-go/aws +github.com/aws/aws-sdk-go/aws/credentials +github.com/aws/aws-sdk-go/aws/credentials/stscreds +github.com/aws/aws-sdk-go/aws/endpoints +github.com/aws/aws-sdk-go/aws/session +github.com/aws/aws-sdk-go/service/ec2 +github.com/aws/aws-sdk-go/service/iam +github.com/aws/aws-sdk-go/service/sts github.com/aws/aws-sdk-go/aws/arn github.com/aws/aws-sdk-go/aws/awserr -github.com/aws/aws-sdk-go/aws/awsutil +github.com/aws/aws-sdk-go/service/iam/iamiface +github.com/aws/aws-sdk-go/service/sts/stsiface +github.com/aws/aws-sdk-go/aws/ec2metadata +github.com/aws/aws-sdk-go/service/dynamodb +github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute +github.com/aws/aws-sdk-go/service/s3 +github.com/aws/aws-sdk-go/internal/sdkio +github.com/aws/aws-sdk-go/internal/ini +github.com/aws/aws-sdk-go/internal/shareddefaults github.com/aws/aws-sdk-go/aws/client -github.com/aws/aws-sdk-go/aws/client/metadata +github.com/aws/aws-sdk-go/internal/sdkrand github.com/aws/aws-sdk-go/aws/corehandlers -github.com/aws/aws-sdk-go/aws/credentials -github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds -github.com/aws/aws-sdk-go/aws/credentials/endpointcreds github.com/aws/aws-sdk-go/aws/credentials/processcreds -github.com/aws/aws-sdk-go/aws/credentials/stscreds -github.com/aws/aws-sdk-go/aws/crr github.com/aws/aws-sdk-go/aws/csm github.com/aws/aws-sdk-go/aws/defaults -github.com/aws/aws-sdk-go/aws/ec2metadata -github.com/aws/aws-sdk-go/aws/endpoints github.com/aws/aws-sdk-go/aws/request -github.com/aws/aws-sdk-go/aws/session +github.com/aws/aws-sdk-go/aws/awsutil +github.com/aws/aws-sdk-go/aws/client/metadata github.com/aws/aws-sdk-go/aws/signer/v4 -github.com/aws/aws-sdk-go/internal/ini -github.com/aws/aws-sdk-go/internal/s3err -github.com/aws/aws-sdk-go/internal/sdkio -github.com/aws/aws-sdk-go/internal/sdkmath -github.com/aws/aws-sdk-go/internal/sdkrand -github.com/aws/aws-sdk-go/internal/sdkuri -github.com/aws/aws-sdk-go/internal/shareddefaults github.com/aws/aws-sdk-go/private/protocol github.com/aws/aws-sdk-go/private/protocol/ec2query +github.com/aws/aws-sdk-go/private/protocol/query +github.com/aws/aws-sdk-go/internal/sdkuri +github.com/aws/aws-sdk-go/service/kms +github.com/aws/aws-sdk-go/service/kms/kmsiface +github.com/aws/aws-sdk-go/aws/crr +github.com/aws/aws-sdk-go/private/protocol/jsonrpc +github.com/aws/aws-sdk-go/internal/s3err github.com/aws/aws-sdk-go/private/protocol/eventstream github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi -github.com/aws/aws-sdk-go/private/protocol/json/jsonutil -github.com/aws/aws-sdk-go/private/protocol/jsonrpc -github.com/aws/aws-sdk-go/private/protocol/query -github.com/aws/aws-sdk-go/private/protocol/query/queryutil github.com/aws/aws-sdk-go/private/protocol/rest github.com/aws/aws-sdk-go/private/protocol/restxml github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil -github.com/aws/aws-sdk-go/service/dynamodb -github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute -github.com/aws/aws-sdk-go/service/ec2 -github.com/aws/aws-sdk-go/service/iam -github.com/aws/aws-sdk-go/service/iam/iamiface -github.com/aws/aws-sdk-go/service/kms -github.com/aws/aws-sdk-go/service/kms/kmsiface -github.com/aws/aws-sdk-go/service/s3 -github.com/aws/aws-sdk-go/service/sts -github.com/aws/aws-sdk-go/service/sts/stsiface +github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds +github.com/aws/aws-sdk-go/aws/credentials/endpointcreds +github.com/aws/aws-sdk-go/internal/sdkmath +github.com/aws/aws-sdk-go/private/protocol/query/queryutil +github.com/aws/aws-sdk-go/private/protocol/json/jsonutil # github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 github.com/beorn7/perks/quantile # github.com/bgentry/speakeasy v0.1.0 @@ -159,10 +159,10 @@ github.com/boombuler/barcode github.com/boombuler/barcode/qr github.com/boombuler/barcode/utils # github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f -github.com/briankassouf/jose github.com/briankassouf/jose/crypto github.com/briankassouf/jose/jws github.com/briankassouf/jose/jwt +github.com/briankassouf/jose # github.com/cenkalti/backoff v2.2.1+incompatible github.com/cenkalti/backoff # github.com/centrify/cloud-golang-sdk v0.0.0-20190214225812-119110094d0f @@ -173,8 +173,8 @@ github.com/chrismalek/oktasdk-go/okta # github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible github.com/circonus-labs/circonus-gometrics github.com/circonus-labs/circonus-gometrics/api -github.com/circonus-labs/circonus-gometrics/api/config github.com/circonus-labs/circonus-gometrics/checkmgr +github.com/circonus-labs/circonus-gometrics/api/config # github.com/circonus-labs/circonusllhist v0.1.3 github.com/circonus-labs/circonusllhist # github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 @@ -205,12 +205,12 @@ github.com/docker/go-connections/nat # github.com/docker/go-units v0.4.0 github.com/docker/go-units # github.com/dsnet/compress v0.0.1 -github.com/dsnet/compress github.com/dsnet/compress/bzip2 github.com/dsnet/compress/bzip2/internal/sais github.com/dsnet/compress/internal github.com/dsnet/compress/internal/errors github.com/dsnet/compress/internal/prefix +github.com/dsnet/compress # github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 github.com/duosecurity/duo_api_golang github.com/duosecurity/duo_api_golang/authapi @@ -241,27 +241,29 @@ github.com/go-ole/go-ole/oleutil github.com/go-sql-driver/mysql # github.com/go-test/deep v1.0.2 github.com/go-test/deep +# github.com/go-yaml/yaml v2.1.0+incompatible +github.com/go-yaml/yaml # github.com/gocql/gocql v0.0.0-20190402132108-0e1d5de854df github.com/gocql/gocql github.com/gocql/gocql/internal/lru github.com/gocql/gocql/internal/murmur github.com/gocql/gocql/internal/streams # github.com/gogo/protobuf v1.2.1 -github.com/gogo/protobuf/gogoproto github.com/gogo/protobuf/io github.com/gogo/protobuf/proto -github.com/gogo/protobuf/protoc-gen-gogo/descriptor github.com/gogo/protobuf/sortkeys +github.com/gogo/protobuf/gogoproto +github.com/gogo/protobuf/protoc-gen-gogo/descriptor # github.com/golang/protobuf v1.3.2 github.com/golang/protobuf/proto -github.com/golang/protobuf/protoc-gen-go/descriptor github.com/golang/protobuf/ptypes +github.com/golang/protobuf/ptypes/timestamp github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration -github.com/golang/protobuf/ptypes/empty github.com/golang/protobuf/ptypes/struct -github.com/golang/protobuf/ptypes/timestamp +github.com/golang/protobuf/ptypes/empty github.com/golang/protobuf/ptypes/wrappers +github.com/golang/protobuf/protoc-gen-go/descriptor # github.com/golang/snappy v0.0.1 github.com/golang/snappy # github.com/google/go-github v17.0.0+incompatible @@ -283,13 +285,13 @@ github.com/gorilla/websocket # github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed github.com/hailocab/go-hostpool # github.com/hashicorp/consul-template v0.22.0 -github.com/hashicorp/consul-template/child github.com/hashicorp/consul-template/config -github.com/hashicorp/consul-template/dependency github.com/hashicorp/consul-template/logging github.com/hashicorp/consul-template/manager -github.com/hashicorp/consul-template/renderer github.com/hashicorp/consul-template/signals +github.com/hashicorp/consul-template/child +github.com/hashicorp/consul-template/dependency +github.com/hashicorp/consul-template/renderer github.com/hashicorp/consul-template/template github.com/hashicorp/consul-template/version github.com/hashicorp/consul-template/watch @@ -307,8 +309,6 @@ github.com/hashicorp/go-hclog github.com/hashicorp/go-immutable-radix # github.com/hashicorp/go-kms-wrapping v0.5.0 github.com/hashicorp/go-kms-wrapping -github.com/hashicorp/go-kms-wrapping/entropy -github.com/hashicorp/go-kms-wrapping/internal/xor github.com/hashicorp/go-kms-wrapping/wrappers/aead github.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms github.com/hashicorp/go-kms-wrapping/wrappers/awskms @@ -316,6 +316,8 @@ github.com/hashicorp/go-kms-wrapping/wrappers/azurekeyvault github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms github.com/hashicorp/go-kms-wrapping/wrappers/ocikms github.com/hashicorp/go-kms-wrapping/wrappers/transit +github.com/hashicorp/go-kms-wrapping/entropy +github.com/hashicorp/go-kms-wrapping/internal/xor # github.com/hashicorp/go-memdb v1.0.2 github.com/hashicorp/go-memdb # github.com/hashicorp/go-msgpack v0.5.5 @@ -342,50 +344,50 @@ github.com/hashicorp/go-uuid # github.com/hashicorp/go-version v1.2.0 github.com/hashicorp/go-version # github.com/hashicorp/gokrb5 v7.3.1-0.20191209171754-1a6fa9886ec3+incompatible -github.com/hashicorp/gokrb5/asn1tools +github.com/hashicorp/gokrb5/spnego github.com/hashicorp/gokrb5/client github.com/hashicorp/gokrb5/config +github.com/hashicorp/gokrb5/keytab +github.com/hashicorp/gokrb5/service +github.com/hashicorp/gokrb5/asn1tools github.com/hashicorp/gokrb5/credentials -github.com/hashicorp/gokrb5/crypto -github.com/hashicorp/gokrb5/crypto/common -github.com/hashicorp/gokrb5/crypto/etype -github.com/hashicorp/gokrb5/crypto/rfc3961 -github.com/hashicorp/gokrb5/crypto/rfc3962 -github.com/hashicorp/gokrb5/crypto/rfc4757 -github.com/hashicorp/gokrb5/crypto/rfc8009 github.com/hashicorp/gokrb5/gssapi -github.com/hashicorp/gokrb5/iana -github.com/hashicorp/gokrb5/iana/addrtype -github.com/hashicorp/gokrb5/iana/adtype -github.com/hashicorp/gokrb5/iana/asnAppTag github.com/hashicorp/gokrb5/iana/chksumtype +github.com/hashicorp/gokrb5/iana/msgtype +github.com/hashicorp/gokrb5/krberror +github.com/hashicorp/gokrb5/messages +github.com/hashicorp/gokrb5/types +github.com/hashicorp/gokrb5/crypto +github.com/hashicorp/gokrb5/crypto/etype github.com/hashicorp/gokrb5/iana/errorcode -github.com/hashicorp/gokrb5/iana/etypeID github.com/hashicorp/gokrb5/iana/flags github.com/hashicorp/gokrb5/iana/keyusage -github.com/hashicorp/gokrb5/iana/msgtype github.com/hashicorp/gokrb5/iana/nametype github.com/hashicorp/gokrb5/iana/patype github.com/hashicorp/gokrb5/kadmin -github.com/hashicorp/gokrb5/keytab -github.com/hashicorp/gokrb5/krberror -github.com/hashicorp/gokrb5/messages +github.com/hashicorp/gokrb5/iana/etypeID +github.com/hashicorp/gokrb5/iana +github.com/hashicorp/gokrb5/iana/adtype +github.com/hashicorp/gokrb5/iana/asnAppTag github.com/hashicorp/gokrb5/pac -github.com/hashicorp/gokrb5/service -github.com/hashicorp/gokrb5/spnego -github.com/hashicorp/gokrb5/types +github.com/hashicorp/gokrb5/iana/addrtype +github.com/hashicorp/gokrb5/crypto/common +github.com/hashicorp/gokrb5/crypto/rfc3961 +github.com/hashicorp/gokrb5/crypto/rfc3962 +github.com/hashicorp/gokrb5/crypto/rfc4757 +github.com/hashicorp/gokrb5/crypto/rfc8009 # github.com/hashicorp/golang-lru v0.5.3 github.com/hashicorp/golang-lru github.com/hashicorp/golang-lru/simplelru # github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/hcl github.com/hashicorp/hcl/hcl/ast -github.com/hashicorp/hcl/hcl/parser github.com/hashicorp/hcl/hcl/printer -github.com/hashicorp/hcl/hcl/scanner -github.com/hashicorp/hcl/hcl/strconv +github.com/hashicorp/hcl/hcl/parser github.com/hashicorp/hcl/hcl/token github.com/hashicorp/hcl/json/parser +github.com/hashicorp/hcl/hcl/scanner +github.com/hashicorp/hcl/hcl/strconv github.com/hashicorp/hcl/json/scanner github.com/hashicorp/hcl/json/token # github.com/hashicorp/logutils v1.0.0 @@ -408,11 +410,11 @@ github.com/hashicorp/vault-plugin-auth-azure github.com/hashicorp/vault-plugin-auth-centrify # github.com/hashicorp/vault-plugin-auth-cf v0.0.0-20190821162840-1c2205826fee github.com/hashicorp/vault-plugin-auth-cf -github.com/hashicorp/vault-plugin-auth-cf/models github.com/hashicorp/vault-plugin-auth-cf/signatures +github.com/hashicorp/vault-plugin-auth-cf/models +github.com/hashicorp/vault-plugin-auth-cf/util github.com/hashicorp/vault-plugin-auth-cf/testing/certificates github.com/hashicorp/vault-plugin-auth-cf/testing/cf -github.com/hashicorp/vault-plugin-auth-cf/util # github.com/hashicorp/vault-plugin-auth-gcp v0.5.2-0.20190930204802-acfd134850c2 github.com/hashicorp/vault-plugin-auth-gcp/plugin github.com/hashicorp/vault-plugin-auth-gcp/plugin/cache @@ -446,51 +448,51 @@ github.com/hashicorp/vault-plugin-secrets-kv # github.com/hashicorp/vault/api v1.0.5-0.20200111014044-ba76c080ad1f => ./api github.com/hashicorp/vault/api # github.com/hashicorp/vault/sdk v0.1.14-0.20200111013952-157e805b97be => ./sdk -github.com/hashicorp/vault/sdk/database/dbplugin -github.com/hashicorp/vault/sdk/database/helper/connutil -github.com/hashicorp/vault/sdk/database/helper/credsutil -github.com/hashicorp/vault/sdk/database/helper/dbutil +github.com/hashicorp/vault/sdk/helper/salt +github.com/hashicorp/vault/sdk/helper/strutil +github.com/hashicorp/vault/sdk/helper/wrapping +github.com/hashicorp/vault/sdk/logical +github.com/hashicorp/vault/sdk/helper/parseutil github.com/hashicorp/vault/sdk/framework -github.com/hashicorp/vault/sdk/helper/awsutil -github.com/hashicorp/vault/sdk/helper/base62 -github.com/hashicorp/vault/sdk/helper/certutil +github.com/hashicorp/vault/sdk/helper/policyutil +github.com/hashicorp/vault/sdk/plugin github.com/hashicorp/vault/sdk/helper/cidrutil -github.com/hashicorp/vault/sdk/helper/compressutil github.com/hashicorp/vault/sdk/helper/consts -github.com/hashicorp/vault/sdk/helper/cryptoutil +github.com/hashicorp/vault/sdk/helper/locksutil +github.com/hashicorp/vault/sdk/helper/tokenutil +github.com/hashicorp/vault/sdk/helper/awsutil +github.com/hashicorp/vault/sdk/helper/jsonutil +github.com/hashicorp/vault/sdk/helper/certutil +github.com/hashicorp/vault/sdk/helper/password +github.com/hashicorp/vault/sdk/helper/ldaputil +github.com/hashicorp/vault/sdk/helper/tlsutil +github.com/hashicorp/vault/sdk/database/dbplugin +github.com/hashicorp/vault/sdk/database/helper/dbutil +github.com/hashicorp/vault/sdk/queue github.com/hashicorp/vault/sdk/helper/dbtxn github.com/hashicorp/vault/sdk/helper/errutil -github.com/hashicorp/vault/sdk/helper/hclutil -github.com/hashicorp/vault/sdk/helper/identitytpl -github.com/hashicorp/vault/sdk/helper/jsonutil -github.com/hashicorp/vault/sdk/helper/kdf github.com/hashicorp/vault/sdk/helper/keysutil -github.com/hashicorp/vault/sdk/helper/ldaputil -github.com/hashicorp/vault/sdk/helper/license -github.com/hashicorp/vault/sdk/helper/locksutil +github.com/hashicorp/vault/sdk/helper/base62 github.com/hashicorp/vault/sdk/helper/logging github.com/hashicorp/vault/sdk/helper/mlock -github.com/hashicorp/vault/sdk/helper/parseutil -github.com/hashicorp/vault/sdk/helper/password -github.com/hashicorp/vault/sdk/helper/pathmanager -github.com/hashicorp/vault/sdk/helper/pluginutil -github.com/hashicorp/vault/sdk/helper/pointerutil -github.com/hashicorp/vault/sdk/helper/policyutil -github.com/hashicorp/vault/sdk/helper/salt -github.com/hashicorp/vault/sdk/helper/strutil -github.com/hashicorp/vault/sdk/helper/tlsutil -github.com/hashicorp/vault/sdk/helper/tokenutil github.com/hashicorp/vault/sdk/helper/useragent -github.com/hashicorp/vault/sdk/helper/wrapping -github.com/hashicorp/vault/sdk/logical github.com/hashicorp/vault/sdk/physical github.com/hashicorp/vault/sdk/physical/file github.com/hashicorp/vault/sdk/physical/inmem -github.com/hashicorp/vault/sdk/plugin -github.com/hashicorp/vault/sdk/plugin/mock -github.com/hashicorp/vault/sdk/plugin/pb -github.com/hashicorp/vault/sdk/queue github.com/hashicorp/vault/sdk/version +github.com/hashicorp/vault/sdk/helper/cryptoutil +github.com/hashicorp/vault/sdk/helper/pointerutil +github.com/hashicorp/vault/sdk/helper/hclutil +github.com/hashicorp/vault/sdk/database/helper/credsutil +github.com/hashicorp/vault/sdk/helper/compressutil +github.com/hashicorp/vault/sdk/helper/pathmanager +github.com/hashicorp/vault/sdk/plugin/pb +github.com/hashicorp/vault/sdk/database/helper/connutil +github.com/hashicorp/vault/sdk/helper/identitytpl +github.com/hashicorp/vault/sdk/helper/license +github.com/hashicorp/vault/sdk/helper/pluginutil +github.com/hashicorp/vault/sdk/helper/kdf +github.com/hashicorp/vault/sdk/plugin/mock # github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb github.com/hashicorp/yamux # github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 @@ -499,11 +501,11 @@ github.com/influxdata/influxdb/models github.com/influxdata/influxdb/pkg/escape # github.com/jackc/pgx v3.3.0+incompatible github.com/jackc/pgx -github.com/jackc/pgx/chunkreader github.com/jackc/pgx/internal/sanitize github.com/jackc/pgx/pgio github.com/jackc/pgx/pgproto3 github.com/jackc/pgx/pgtype +github.com/jackc/pgx/chunkreader # github.com/jcmturner/gofork v1.0.0 github.com/jcmturner/gofork/encoding/asn1 github.com/jcmturner/gofork/x/crypto/pbkdf2 @@ -518,25 +520,27 @@ github.com/jmespath/go-jmespath # github.com/joyent/triton-go v0.0.0-20190112182421-51ffac552869 github.com/joyent/triton-go github.com/joyent/triton-go/authentication -github.com/joyent/triton-go/client github.com/joyent/triton-go/errors github.com/joyent/triton-go/storage +github.com/joyent/triton-go/client # github.com/json-iterator/go v1.1.6 github.com/json-iterator/go +# github.com/kelseyhightower/envconfig v1.3.0 +github.com/kelseyhightower/envconfig # github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f +github.com/keybase/go-crypto/openpgp +github.com/keybase/go-crypto/openpgp/packet +github.com/keybase/go-crypto/openpgp/armor +github.com/keybase/go-crypto/openpgp/errors +github.com/keybase/go-crypto/openpgp/s2k +github.com/keybase/go-crypto/rsa github.com/keybase/go-crypto/brainpool github.com/keybase/go-crypto/cast5 github.com/keybase/go-crypto/curve25519 github.com/keybase/go-crypto/ed25519 -github.com/keybase/go-crypto/ed25519/internal/edwards25519 -github.com/keybase/go-crypto/openpgp -github.com/keybase/go-crypto/openpgp/armor github.com/keybase/go-crypto/openpgp/ecdh github.com/keybase/go-crypto/openpgp/elgamal -github.com/keybase/go-crypto/openpgp/errors -github.com/keybase/go-crypto/openpgp/packet -github.com/keybase/go-crypto/openpgp/s2k -github.com/keybase/go-crypto/rsa +github.com/keybase/go-crypto/ed25519/internal/edwards25519 # github.com/konsorten/go-windows-terminal-sequences v1.0.1 github.com/konsorten/go-windows-terminal-sequences # github.com/kr/pretty v0.1.0 @@ -585,18 +589,22 @@ github.com/ncw/swift github.com/nwaples/rardecode # github.com/oklog/run v1.0.0 github.com/oklog/run +# github.com/okta/okta-sdk-golang v1.0.1 +github.com/okta/okta-sdk-golang/okta +github.com/okta/okta-sdk-golang/okta/cache +github.com/okta/okta-sdk-golang/okta/query # github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/go-digest # github.com/opencontainers/image-spec v1.0.1 -github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 +github.com/opencontainers/image-spec/specs-go # github.com/opencontainers/runc v0.1.1 github.com/opencontainers/runc/libcontainer/user # github.com/oracle/oci-go-sdk v12.5.0+incompatible github.com/oracle/oci-go-sdk/common github.com/oracle/oci-go-sdk/common/auth -github.com/oracle/oci-go-sdk/keymanagement github.com/oracle/oci-go-sdk/objectstorage +github.com/oracle/oci-go-sdk/keymanagement # github.com/ory/dockertest v3.3.5+incompatible github.com/ory/dockertest github.com/ory/dockertest/docker @@ -604,23 +612,23 @@ github.com/ory/dockertest/docker/opts github.com/ory/dockertest/docker/pkg/archive github.com/ory/dockertest/docker/pkg/fileutils github.com/ory/dockertest/docker/pkg/homedir +github.com/ory/dockertest/docker/pkg/jsonmessage +github.com/ory/dockertest/docker/pkg/stdcopy +github.com/ory/dockertest/docker/types/registry +github.com/ory/dockertest/docker/types github.com/ory/dockertest/docker/pkg/idtools github.com/ory/dockertest/docker/pkg/ioutils -github.com/ory/dockertest/docker/pkg/jsonmessage github.com/ory/dockertest/docker/pkg/longpath -github.com/ory/dockertest/docker/pkg/mount github.com/ory/dockertest/docker/pkg/pools -github.com/ory/dockertest/docker/pkg/stdcopy github.com/ory/dockertest/docker/pkg/system github.com/ory/dockertest/docker/pkg/term -github.com/ory/dockertest/docker/pkg/term/windows -github.com/ory/dockertest/docker/types -github.com/ory/dockertest/docker/types/blkiodev github.com/ory/dockertest/docker/types/container github.com/ory/dockertest/docker/types/filters github.com/ory/dockertest/docker/types/mount github.com/ory/dockertest/docker/types/network -github.com/ory/dockertest/docker/types/registry +github.com/ory/dockertest/docker/pkg/mount +github.com/ory/dockertest/docker/pkg/term/windows +github.com/ory/dockertest/docker/types/blkiodev github.com/ory/dockertest/docker/types/strslice github.com/ory/dockertest/docker/types/versions # github.com/patrickmn/go-cache v2.1.0+incompatible @@ -634,31 +642,31 @@ github.com/pkg/errors github.com/pmezard/go-difflib/difflib # github.com/posener/complete v1.2.1 github.com/posener/complete -github.com/posener/complete/cmd github.com/posener/complete/cmd/install +github.com/posener/complete/cmd github.com/posener/complete/match # github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 github.com/pquerna/cachecontrol github.com/pquerna/cachecontrol/cacheobject # github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d github.com/pquerna/otp -github.com/pquerna/otp/hotp github.com/pquerna/otp/totp +github.com/pquerna/otp/hotp # github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 github.com/prometheus/client_golang/prometheus -github.com/prometheus/client_golang/prometheus/internal github.com/prometheus/client_golang/prometheus/push +github.com/prometheus/client_golang/prometheus/internal # github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f github.com/prometheus/client_model/go # github.com/prometheus/common v0.2.0 github.com/prometheus/common/expfmt -github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg github.com/prometheus/common/model +github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg # github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 github.com/prometheus/procfs -github.com/prometheus/procfs/internal/util github.com/prometheus/procfs/nfs github.com/prometheus/procfs/xfs +github.com/prometheus/procfs/internal/util # github.com/ryanuber/columnize v2.1.0+incompatible github.com/ryanuber/columnize # github.com/ryanuber/go-glob v1.0.0 @@ -671,10 +679,10 @@ github.com/satori/go.uuid github.com/shirou/gopsutil/cpu github.com/shirou/gopsutil/disk github.com/shirou/gopsutil/host -github.com/shirou/gopsutil/internal/common github.com/shirou/gopsutil/mem -github.com/shirou/gopsutil/net +github.com/shirou/gopsutil/internal/common github.com/shirou/gopsutil/process +github.com/shirou/gopsutil/net # github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 github.com/shirou/w32 # github.com/sirupsen/logrus v1.4.2 @@ -688,191 +696,178 @@ github.com/tv42/httpunix github.com/ugorji/go/codec # github.com/ulikunitz/xz v0.5.6 github.com/ulikunitz/xz -github.com/ulikunitz/xz/internal/hash github.com/ulikunitz/xz/internal/xlog github.com/ulikunitz/xz/lzma +github.com/ulikunitz/xz/internal/hash # github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 github.com/xi2/xz # go.etcd.io/bbolt v1.3.2 go.etcd.io/bbolt # go.etcd.io/etcd v0.0.0-20190412021913-f29b1ada1971 -go.etcd.io/etcd/auth/authpb go.etcd.io/etcd/client go.etcd.io/etcd/clientv3 +go.etcd.io/etcd/clientv3/concurrency +go.etcd.io/etcd/pkg/transport +go.etcd.io/etcd/pkg/pathutil +go.etcd.io/etcd/pkg/srv +go.etcd.io/etcd/pkg/types +go.etcd.io/etcd/version +go.etcd.io/etcd/auth/authpb go.etcd.io/etcd/clientv3/balancer go.etcd.io/etcd/clientv3/balancer/picker go.etcd.io/etcd/clientv3/balancer/resolver/endpoint -go.etcd.io/etcd/clientv3/concurrency go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes go.etcd.io/etcd/etcdserver/etcdserverpb go.etcd.io/etcd/mvcc/mvccpb go.etcd.io/etcd/pkg/logutil -go.etcd.io/etcd/pkg/pathutil -go.etcd.io/etcd/pkg/srv -go.etcd.io/etcd/pkg/systemd go.etcd.io/etcd/pkg/tlsutil -go.etcd.io/etcd/pkg/transport -go.etcd.io/etcd/pkg/types +go.etcd.io/etcd/pkg/systemd go.etcd.io/etcd/raft go.etcd.io/etcd/raft/raftpb -go.etcd.io/etcd/version # go.opencensus.io v0.21.0 -go.opencensus.io -go.opencensus.io/internal -go.opencensus.io/internal/tagencoding +go.opencensus.io/stats +go.opencensus.io/stats/view +go.opencensus.io/plugin/ochttp +go.opencensus.io/trace go.opencensus.io/metric/metricdata +go.opencensus.io/stats/internal +go.opencensus.io/tag +go.opencensus.io/internal/tagencoding go.opencensus.io/metric/metricproducer go.opencensus.io/plugin/ocgrpc -go.opencensus.io/plugin/ochttp go.opencensus.io/plugin/ochttp/propagation/b3 -go.opencensus.io/resource -go.opencensus.io/stats -go.opencensus.io/stats/internal -go.opencensus.io/stats/view -go.opencensus.io/tag -go.opencensus.io/trace -go.opencensus.io/trace/internal go.opencensus.io/trace/propagation +go.opencensus.io/internal +go.opencensus.io/trace/internal go.opencensus.io/trace/tracestate +go.opencensus.io/resource +go.opencensus.io # go.uber.org/atomic v1.4.0 go.uber.org/atomic # go.uber.org/multierr v1.1.0 go.uber.org/multierr # go.uber.org/zap v1.9.1 go.uber.org/zap -go.uber.org/zap/buffer +go.uber.org/zap/zapcore go.uber.org/zap/internal/bufferpool +go.uber.org/zap/buffer go.uber.org/zap/internal/color go.uber.org/zap/internal/exit -go.uber.org/zap/zapcore # golang.org/x/crypto v0.0.0-20191106202628-ed6320f186d4 golang.org/x/crypto/bcrypt -golang.org/x/crypto/blake2b -golang.org/x/crypto/blowfish -golang.org/x/crypto/chacha20poly1305 golang.org/x/crypto/cryptobyte golang.org/x/crypto/cryptobyte/asn1 -golang.org/x/crypto/curve25519 golang.org/x/crypto/ed25519 +golang.org/x/crypto/ssh +golang.org/x/crypto/ssh/agent +golang.org/x/crypto/curve25519 +golang.org/x/crypto/ssh/terminal +golang.org/x/crypto/blowfish +golang.org/x/crypto/md4 golang.org/x/crypto/ed25519/internal/edwards25519 -golang.org/x/crypto/hkdf golang.org/x/crypto/internal/chacha20 -golang.org/x/crypto/internal/subtle -golang.org/x/crypto/md4 +golang.org/x/crypto/poly1305 +golang.org/x/crypto/chacha20poly1305 +golang.org/x/crypto/hkdf golang.org/x/crypto/pbkdf2 +golang.org/x/crypto/blake2b +golang.org/x/crypto/internal/subtle golang.org/x/crypto/pkcs12 golang.org/x/crypto/pkcs12/internal/rc2 -golang.org/x/crypto/poly1305 -golang.org/x/crypto/ssh -golang.org/x/crypto/ssh/agent -golang.org/x/crypto/ssh/terminal # golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 -golang.org/x/net/context -golang.org/x/net/context/ctxhttp -golang.org/x/net/http/httpguts +golang.org/x/net/idna golang.org/x/net/http/httpproxy +golang.org/x/net/context golang.org/x/net/http2 +golang.org/x/net/http/httpguts golang.org/x/net/http2/hpack -golang.org/x/net/idna -golang.org/x/net/internal/timeseries golang.org/x/net/trace +golang.org/x/net/context/ctxhttp +golang.org/x/net/internal/timeseries # golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/oauth2 -golang.org/x/oauth2/clientcredentials -golang.org/x/oauth2/google golang.org/x/oauth2/internal -golang.org/x/oauth2/jws +golang.org/x/oauth2/google golang.org/x/oauth2/jwt +golang.org/x/oauth2/jws +golang.org/x/oauth2/clientcredentials # golang.org/x/sys v0.0.0-20191008105621-543471e840be -golang.org/x/sys/cpu golang.org/x/sys/unix golang.org/x/sys/windows +golang.org/x/sys/cpu # golang.org/x/text v0.3.2 +golang.org/x/text/secure/bidirule +golang.org/x/text/unicode/bidi +golang.org/x/text/unicode/norm +golang.org/x/text/transform +golang.org/x/text/encoding/unicode golang.org/x/text/encoding golang.org/x/text/encoding/internal golang.org/x/text/encoding/internal/identifier -golang.org/x/text/encoding/unicode golang.org/x/text/internal/utf8internal golang.org/x/text/runes -golang.org/x/text/secure/bidirule -golang.org/x/text/transform -golang.org/x/text/unicode/bidi -golang.org/x/text/unicode/norm # golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/time/rate # google.golang.org/api v0.14.0 +google.golang.org/api/option +google.golang.org/api/iam/v1 +google.golang.org/api/googleapi +google.golang.org/api/iterator +google.golang.org/api/transport google.golang.org/api/cloudresourcemanager/v1 google.golang.org/api/compute/v1 -google.golang.org/api/googleapi -google.golang.org/api/googleapi/transport -google.golang.org/api/iam/v1 google.golang.org/api/internal -google.golang.org/api/internal/gensupport -google.golang.org/api/internal/third_party/uritemplates -google.golang.org/api/iterator google.golang.org/api/oauth2/v2 -google.golang.org/api/option +google.golang.org/api/internal/gensupport +google.golang.org/api/transport/http google.golang.org/api/storage/v1 -google.golang.org/api/transport +google.golang.org/api/internal/third_party/uritemplates google.golang.org/api/transport/grpc -google.golang.org/api/transport/http +google.golang.org/api/googleapi/transport google.golang.org/api/transport/http/internal/propagation # google.golang.org/appengine v1.6.0 -google.golang.org/appengine google.golang.org/appengine/cloudsql +google.golang.org/appengine/urlfetch +google.golang.org/appengine +google.golang.org/appengine/socket google.golang.org/appengine/internal +google.golang.org/appengine/internal/urlfetch google.golang.org/appengine/internal/app_identity +google.golang.org/appengine/internal/modules +google.golang.org/appengine/internal/socket google.golang.org/appengine/internal/base google.golang.org/appengine/internal/datastore google.golang.org/appengine/internal/log -google.golang.org/appengine/internal/modules google.golang.org/appengine/internal/remote_api -google.golang.org/appengine/internal/socket -google.golang.org/appengine/internal/urlfetch -google.golang.org/appengine/socket -google.golang.org/appengine/urlfetch # google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 -google.golang.org/genproto/googleapis/api -google.golang.org/genproto/googleapis/api/annotations -google.golang.org/genproto/googleapis/api/distribution -google.golang.org/genproto/googleapis/api/label google.golang.org/genproto/googleapis/api/metric google.golang.org/genproto/googleapis/api/monitoredres +google.golang.org/genproto/googleapis/monitoring/v3 +google.golang.org/genproto/googleapis/api/distribution google.golang.org/genproto/googleapis/cloud/kms/v1 +google.golang.org/genproto/protobuf/field_mask google.golang.org/genproto/googleapis/iam/v1 -google.golang.org/genproto/googleapis/monitoring/v3 -google.golang.org/genproto/googleapis/rpc/code google.golang.org/genproto/googleapis/rpc/errdetails -google.golang.org/genproto/googleapis/rpc/status google.golang.org/genproto/googleapis/spanner/v1 +google.golang.org/genproto/googleapis/rpc/status +google.golang.org/genproto/googleapis/api +google.golang.org/genproto/googleapis/api/label +google.golang.org/genproto/googleapis/api/annotations +google.golang.org/genproto/googleapis/rpc/code google.golang.org/genproto/googleapis/type/expr -google.golang.org/genproto/protobuf/field_mask # google.golang.org/grpc v1.22.0 +google.golang.org/grpc/grpclog +google.golang.org/grpc/codes google.golang.org/grpc +google.golang.org/grpc/keepalive +google.golang.org/grpc/status +google.golang.org/grpc/metadata +google.golang.org/grpc/credentials google.golang.org/grpc/balancer -google.golang.org/grpc/balancer/base -google.golang.org/grpc/balancer/grpclb -google.golang.org/grpc/balancer/grpclb/grpc_lb_v1 google.golang.org/grpc/balancer/roundrobin -google.golang.org/grpc/binarylog/grpc_binarylog_v1 -google.golang.org/grpc/codes google.golang.org/grpc/connectivity -google.golang.org/grpc/credentials -google.golang.org/grpc/credentials/alts -google.golang.org/grpc/credentials/alts/internal -google.golang.org/grpc/credentials/alts/internal/authinfo -google.golang.org/grpc/credentials/alts/internal/conn -google.golang.org/grpc/credentials/alts/internal/handshaker -google.golang.org/grpc/credentials/alts/internal/handshaker/service -google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp -google.golang.org/grpc/credentials/google -google.golang.org/grpc/credentials/internal -google.golang.org/grpc/credentials/oauth google.golang.org/grpc/encoding google.golang.org/grpc/encoding/proto -google.golang.org/grpc/grpclog -google.golang.org/grpc/health -google.golang.org/grpc/health/grpc_health_v1 google.golang.org/grpc/internal google.golang.org/grpc/internal/backoff google.golang.org/grpc/internal/balancerload @@ -881,10 +876,7 @@ google.golang.org/grpc/internal/channelz google.golang.org/grpc/internal/envconfig google.golang.org/grpc/internal/grpcrand google.golang.org/grpc/internal/grpcsync -google.golang.org/grpc/internal/syscall google.golang.org/grpc/internal/transport -google.golang.org/grpc/keepalive -google.golang.org/grpc/metadata google.golang.org/grpc/naming google.golang.org/grpc/peer google.golang.org/grpc/resolver @@ -892,8 +884,24 @@ google.golang.org/grpc/resolver/dns google.golang.org/grpc/resolver/passthrough google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats -google.golang.org/grpc/status google.golang.org/grpc/tap +google.golang.org/grpc/health +google.golang.org/grpc/health/grpc_health_v1 +google.golang.org/grpc/credentials/internal +google.golang.org/grpc/balancer/grpclb +google.golang.org/grpc/credentials/google +google.golang.org/grpc/credentials/oauth +google.golang.org/grpc/balancer/base +google.golang.org/grpc/binarylog/grpc_binarylog_v1 +google.golang.org/grpc/internal/syscall +google.golang.org/grpc/balancer/grpclb/grpc_lb_v1 +google.golang.org/grpc/credentials/alts +google.golang.org/grpc/credentials/alts/internal +google.golang.org/grpc/credentials/alts/internal/handshaker +google.golang.org/grpc/credentials/alts/internal/handshaker/service +google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp +google.golang.org/grpc/credentials/alts/internal/authinfo +google.golang.org/grpc/credentials/alts/internal/conn # gopkg.in/inf.v0 v0.9.1 gopkg.in/inf.v0 # gopkg.in/ini.v1 v1.42.0 @@ -910,43 +918,43 @@ gopkg.in/jcmturner/rpc.v1/ndr # gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce gopkg.in/mgo.v2 gopkg.in/mgo.v2/bson -gopkg.in/mgo.v2/internal/json gopkg.in/mgo.v2/internal/sasl gopkg.in/mgo.v2/internal/scram +gopkg.in/mgo.v2/internal/json # gopkg.in/ory-am/dockertest.v3 v3.3.4 gopkg.in/ory-am/dockertest.v3 # gopkg.in/square/go-jose.v2 v2.3.1 +gopkg.in/square/go-jose.v2/jwt gopkg.in/square/go-jose.v2 -gopkg.in/square/go-jose.v2/cipher gopkg.in/square/go-jose.v2/json -gopkg.in/square/go-jose.v2/jwt +gopkg.in/square/go-jose.v2/cipher # gopkg.in/yaml.v2 v2.2.2 gopkg.in/yaml.v2 # k8s.io/api v0.0.0-20190409092523-d687e77c8ae9 k8s.io/api/authentication/v1 # k8s.io/apimachinery v0.0.0-20190409092423-760d1845f48b k8s.io/apimachinery/pkg/api/errors -k8s.io/apimachinery/pkg/api/resource k8s.io/apimachinery/pkg/apis/meta/v1 +k8s.io/apimachinery/pkg/runtime +k8s.io/apimachinery/pkg/runtime/schema +k8s.io/apimachinery/pkg/types +k8s.io/apimachinery/pkg/util/validation/field +k8s.io/apimachinery/pkg/api/resource k8s.io/apimachinery/pkg/conversion -k8s.io/apimachinery/pkg/conversion/queryparams k8s.io/apimachinery/pkg/fields k8s.io/apimachinery/pkg/labels -k8s.io/apimachinery/pkg/runtime -k8s.io/apimachinery/pkg/runtime/schema k8s.io/apimachinery/pkg/selection -k8s.io/apimachinery/pkg/types -k8s.io/apimachinery/pkg/util/errors k8s.io/apimachinery/pkg/util/intstr +k8s.io/apimachinery/pkg/util/runtime +k8s.io/apimachinery/pkg/watch +k8s.io/apimachinery/pkg/conversion/queryparams +k8s.io/apimachinery/pkg/util/errors k8s.io/apimachinery/pkg/util/json k8s.io/apimachinery/pkg/util/naming -k8s.io/apimachinery/pkg/util/net -k8s.io/apimachinery/pkg/util/runtime k8s.io/apimachinery/pkg/util/sets -k8s.io/apimachinery/pkg/util/validation -k8s.io/apimachinery/pkg/util/validation/field -k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/reflect +k8s.io/apimachinery/pkg/util/validation +k8s.io/apimachinery/pkg/util/net # k8s.io/klog v0.0.0-20190306015804-8e90cee79f82 k8s.io/klog # layeh.com/radius v0.0.0-20190322222518-890bc1058917