diff --git a/go.mod b/go.mod index 7aa2e892383..e5d58c77cb6 100644 --- a/go.mod +++ b/go.mod @@ -62,7 +62,7 @@ require ( github.com/nadoo/ipset v0.5.0 github.com/netbirdio/management-integrations/integrations v0.0.0-20241106153857-de8e2beb5254 github.com/netbirdio/signal-dispatcher/dispatcher v0.0.0-20241010133937-e0df50df217d - github.com/okta/okta-sdk-golang/v2 v2.18.0 + github.com/okta/okta-sdk-golang/v5 v5.0.4 github.com/oschwald/maxminddb-golang v1.12.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pion/logging v0.2.2 @@ -137,6 +137,7 @@ require ( github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect github.com/cpuguy83/dockercfg v0.3.2 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/distribution/reference v0.6.0 // indirect @@ -150,6 +151,7 @@ require ( github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect @@ -157,6 +159,7 @@ require ( github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/go-text/render v0.1.0 // indirect github.com/go-text/typesetting v0.1.0 // indirect + github.com/goccy/go-json v0.10.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/btree v1.1.2 // indirect @@ -180,6 +183,12 @@ require ( github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect + github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/jwx v1.2.30 // indirect + github.com/lestrrat-go/option v1.0.1 // indirect github.com/libdns/libdns v0.2.2 // indirect github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect github.com/mdlayher/genetlink v1.3.2 // indirect @@ -229,7 +238,6 @@ require ( golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240509183442-62759503f434 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 // indirect gvisor.dev/gvisor v0.0.0-20231020174304-b8a429915ff1 // indirect diff --git a/go.sum b/go.sum index 2bb7342511e..288d8eedab2 100644 --- a/go.sum +++ b/go.sum @@ -159,6 +159,8 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -221,6 +223,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= @@ -252,6 +256,8 @@ github.com/go-text/typesetting v0.1.0 h1:vioSaLPYcHwPEPLT7gsjCGDCoYSbljxoHJzMnKw github.com/go-text/typesetting v0.1.0/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI= github.com/go-text/typesetting-utils v0.0.0-20240329101916-eee87fb235a3 h1:levTnuLLUmpavLGbJYLJA7fQnKeS7P1eCdAlM+vReXk= github.com/go-text/typesetting-utils v0.0.0-20240329101916-eee87fb235a3/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -416,6 +422,8 @@ github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc= +github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk= github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 h1:Po+wkNdMmN+Zj1tDsJQy7mJlPlwGNQd9JZoPjObagf8= github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49/go.mod h1:YiutDnxPRLk5DLUFj6Rw4pRBBURZY07GFr54NdV9mQg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -458,6 +466,19 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= +github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= +github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= +github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= +github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= +github.com/lestrrat-go/jwx v1.2.30 h1:VKIFrmjYn0z2J51iLPadqoHIVLzvWNa1kCsTqNDHYPA= +github.com/lestrrat-go/jwx v1.2.30/go.mod h1:vMxrwFhunGZ3qddmfmEm2+uced8MSI6QFWGTKygjSzQ= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= +github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= @@ -539,8 +560,8 @@ github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7g github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/okta/okta-sdk-golang/v2 v2.18.0 h1:cfDasMb7CShbZvOrF6n+DnLevWwiHgedWMGJ8M8xKDc= -github.com/okta/okta-sdk-golang/v2 v2.18.0/go.mod h1:dz30v3ctAiMb7jpsCngGfQUAEGm1/NsWT92uTbNDQIs= +github.com/okta/okta-sdk-golang/v5 v5.0.4 h1:HDq1L+3vECjTZRPmsRYxgeWOGRuaxk1+tdRkdscAeLQ= +github.com/okta/okta-sdk-golang/v5 v5.0.4/go.mod h1:T/vmECtJX33YPZSVD+sorebd8LLhe38Bi/VrFTjgVX0= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -782,6 +803,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -981,6 +1003,7 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -991,6 +1014,7 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1214,8 +1238,6 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs= diff --git a/management/server/idp/okta.go b/management/server/idp/okta.go index b9cd006be0e..0a36ed7e5c7 100644 --- a/management/server/idp/okta.go +++ b/management/server/idp/okta.go @@ -4,19 +4,17 @@ import ( "context" "fmt" "net/http" - "net/url" "strings" "time" - "github.com/okta/okta-sdk-golang/v2/okta" - "github.com/okta/okta-sdk-golang/v2/okta/query" + "github.com/okta/okta-sdk-golang/v5/okta" "github.com/netbirdio/netbird/management/server/telemetry" ) // OktaManager okta manager client instance. type OktaManager struct { - client *okta.Client + client *okta.APIClient httpClient ManagerHTTPClient credentials ManagerCredentials helper ManagerHelper @@ -68,7 +66,7 @@ func NewOktaManager(config OktaClientConfig, appMetrics telemetry.AppMetrics) (* return nil, fmt.Errorf("okta IdP configuration is incomplete, GrantType is missing") } - _, client, err := okta.NewClient(context.Background(), + oktaConfig, err := okta.NewConfiguration( okta.WithOrgUrl(config.Issuer), okta.WithToken(config.APIToken), okta.WithHttpClientPtr(httpClient), @@ -85,7 +83,7 @@ func NewOktaManager(config OktaClientConfig, appMetrics telemetry.AppMetrics) (* } return &OktaManager{ - client: client, + client: okta.NewAPIClient(oktaConfig), httpClient: httpClient, credentials: credentials, helper: helper, @@ -103,9 +101,9 @@ func (om *OktaManager) CreateUser(_ context.Context, _, _, _, _ string) (*UserDa return nil, fmt.Errorf("method CreateUser not implemented") } -// GetUserDataByID requests user data from keycloak via ID. -func (om *OktaManager) GetUserDataByID(_ context.Context, userID string, appMetadata AppMetadata) (*UserData, error) { - user, resp, err := om.client.User.GetUser(context.Background(), userID) +// GetUserDataByID requests user data from Okta via ID. +func (om *OktaManager) GetUserDataByID(ctx context.Context, userID string, appMetadata AppMetadata) (*UserData, error) { + user, resp, err := om.client.UserAPI.GetUser(ctx, userID).Execute() if err != nil { return nil, err } @@ -121,10 +119,7 @@ func (om *OktaManager) GetUserDataByID(_ context.Context, userID string, appMeta return nil, fmt.Errorf("unable to get user %s, statusCode %d", userID, resp.StatusCode) } - userData, err := parseOktaUser(user) - if err != nil { - return nil, err - } + userData := parseOktaUser(user) userData.AppMetadata = appMetadata return userData, nil @@ -133,7 +128,8 @@ func (om *OktaManager) GetUserDataByID(_ context.Context, userID string, appMeta // GetUserByEmail searches users with a given email. // If no users have been found, this function returns an empty list. func (om *OktaManager) GetUserByEmail(_ context.Context, email string) ([]*UserData, error) { - user, resp, err := om.client.User.GetUser(context.Background(), url.QueryEscape(email)) + filter := fmt.Sprintf("profile.email eq \"%s\"", email) + users, resp, err := om.client.UserAPI.ListUsers(context.Background()).Filter(filter).Execute() if err != nil { return nil, err } @@ -149,14 +145,12 @@ func (om *OktaManager) GetUserByEmail(_ context.Context, email string) ([]*UserD return nil, fmt.Errorf("unable to get user %s, statusCode %d", email, resp.StatusCode) } - userData, err := parseOktaUser(user) - if err != nil { - return nil, err + usersData := make([]*UserData, 0, len(users)) + for _, user := range users { + usersData = append(usersData, parseOktaUser(&user)) } - users := make([]*UserData, 0) - users = append(users, userData) - return users, nil + return usersData, nil } // GetAccount returns all the users for a given profile. @@ -198,8 +192,7 @@ func (om *OktaManager) GetAllAccounts(_ context.Context) (map[string][]*UserData // getAllUsers returns all users in an Okta account. func (om *OktaManager) getAllUsers() ([]*UserData, error) { - qp := query.NewQueryParams(query.WithLimit(200)) - userList, resp, err := om.client.User.ListUsers(context.Background(), qp) + userList, resp, err := om.client.UserAPI.ListUsers(context.Background()).Limit(200).Execute() if err != nil { return nil, err } @@ -212,8 +205,8 @@ func (om *OktaManager) getAllUsers() ([]*UserData, error) { } for resp.HasNextPage() { - paginatedUsers := make([]*okta.User, 0) - resp, err = resp.Next(context.Background(), &paginatedUsers) + paginatedUsers := make([]okta.User, 0) + resp, err = resp.Next(&paginatedUsers) if err != nil { return nil, err } @@ -230,12 +223,7 @@ func (om *OktaManager) getAllUsers() ([]*UserData, error) { users := make([]*UserData, 0, len(userList)) for _, user := range userList { - userData, err := parseOktaUser(user) - if err != nil { - return nil, err - } - - users = append(users, userData) + users = append(users, parseOktaUser(&user)) } return users, nil @@ -254,7 +242,7 @@ func (om *OktaManager) InviteUserByID(_ context.Context, _ string) error { // DeleteUser from Okta func (om *OktaManager) DeleteUser(_ context.Context, userID string) error { - resp, err := om.client.User.DeactivateOrDeleteUser(context.Background(), userID, nil) + resp, err := om.client.UserAPI.DeleteUser(context.Background(), userID).Execute() if err != nil { return err } @@ -273,34 +261,27 @@ func (om *OktaManager) DeleteUser(_ context.Context, userID string) error { return nil } +// oktaUser interface for Okta user. +type oktaUser interface { + GetId() string + GetProfile() okta.UserProfile +} + // parseOktaUser parse okta user to UserData. -func parseOktaUser(user *okta.User) (*UserData, error) { - var oktaUser struct { - Email string `json:"email"` - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - } +func parseOktaUser(user oktaUser) *UserData { + profile := user.GetProfile() - if user == nil { - return nil, fmt.Errorf("invalid okta user") + var names []string + if firstName := profile.GetFirstName(); firstName != "" { + names = append(names, firstName) } - - if user.Profile != nil { - helper := JsonParser{} - buf, err := helper.Marshal(*user.Profile) - if err != nil { - return nil, err - } - - err = helper.Unmarshal(buf, &oktaUser) - if err != nil { - return nil, err - } + if lastName := profile.GetLastName(); lastName != "" { + names = append(names, lastName) } return &UserData{ - Email: oktaUser.Email, - Name: strings.Join([]string{oktaUser.FirstName, oktaUser.LastName}, " "), - ID: user.Id, - }, nil + Email: profile.GetEmail(), + Name: strings.Join(names, " "), + ID: user.GetId(), + } } diff --git a/management/server/idp/okta_test.go b/management/server/idp/okta_test.go index 20df246f82a..ec3b3133924 100644 --- a/management/server/idp/okta_test.go +++ b/management/server/idp/okta_test.go @@ -3,63 +3,45 @@ package idp import ( "testing" - "github.com/okta/okta-sdk-golang/v2/okta" + "github.com/okta/okta-sdk-golang/v5/okta" "github.com/stretchr/testify/assert" ) func TestParseOktaUser(t *testing.T) { type parseOktaUserTest struct { name string - inputProfile *okta.User + inputUser *okta.User expectedUserData *UserData - assertErrFunc assert.ErrorAssertionFunc } - parseOktaTestCase1 := parseOktaUserTest{ - name: "Good Request", - inputProfile: &okta.User{ - Id: "123", - Profile: &okta.UserProfile{ - "email": "test@example.com", - "firstName": "John", - "lastName": "Doe", + testCases := []parseOktaUserTest{ + { + name: "valid okta user", + inputUser: &okta.User{ + Id: okta.PtrString("123"), + Profile: &okta.UserProfile{ + Email: okta.PtrString("test@example.com"), + FirstName: *okta.NewNullableString(okta.PtrString("John")), + LastName: *okta.NewNullableString(okta.PtrString("Doe")), + }, }, - }, - expectedUserData: &UserData{ - Email: "test@example.com", - Name: "John Doe", - ID: "123", - AppMetadata: AppMetadata{ - WTAccountID: "456", + expectedUserData: &UserData{ + Email: "test@example.com", + Name: "John Doe", + ID: "123", }, }, - assertErrFunc: assert.NoError, - } - - parseOktaTestCase2 := parseOktaUserTest{ - name: "Invalid okta user", - inputProfile: nil, - expectedUserData: nil, - assertErrFunc: assert.Error, + { + name: "invalid okta user", + inputUser: nil, + expectedUserData: &UserData{}, + }, } - for _, testCase := range []parseOktaUserTest{parseOktaTestCase1, parseOktaTestCase2} { - t.Run(testCase.name, func(t *testing.T) { - userData, err := parseOktaUser(testCase.inputProfile) - testCase.assertErrFunc(t, err, testCase.assertErrFunc) - - if err == nil { - assert.True(t, userDataEqual(testCase.expectedUserData, userData), "user data should match") - } + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + userData := parseOktaUser(tt.inputUser) + assert.Equal(t, tt.expectedUserData, userData, "user data should match") }) - - } -} - -// userDataEqual helper function to compare UserData structs for equality. -func userDataEqual(a, b *UserData) bool { - if a.Email != b.Email || a.Name != b.Name || a.ID != b.ID { - return false } - return true }