mirror of
https://github.com/goauthentik/authentik
synced 2026-04-28 10:28:22 +02:00
* packages/client-go: init Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space> * format Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove mod/sum Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix translate Signed-off-by: Jens Langhammer <jens@goauthentik.io> * no go replace Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update rust makefile with pwd Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space> * fix build Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix docs Signed-off-by: Jens Langhammer <jens@goauthentik.io> * don't need a version ig? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * exclude go client from cspell Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix main docker build Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space> Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
package ak
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
api "goauthentik.io/packages/client-go"
|
|
)
|
|
|
|
// Generic interface that mimics a generated request by the API client
|
|
// Requires mainly `Treq` which will be the actual request type, and
|
|
// `Tres` which is the response type
|
|
type PaginatorRequest[Treq any, Tres any] interface {
|
|
Page(page int32) Treq
|
|
PageSize(size int32) Treq
|
|
Execute() (Tres, *http.Response, error)
|
|
}
|
|
|
|
// Generic interface that mimics a generated response by the API client
|
|
type PaginatorResponse[Tobj any] interface {
|
|
GetResults() []Tobj
|
|
GetPagination() api.Pagination
|
|
}
|
|
|
|
// Paginator options for page size
|
|
type PaginatorOptions struct {
|
|
PageSize int
|
|
Logger *log.Entry
|
|
}
|
|
|
|
// Automatically fetch all objects from an API endpoint using the pagination
|
|
// data received from the server.
|
|
func Paginator[Tobj any, Treq any, Tres PaginatorResponse[Tobj]](
|
|
req PaginatorRequest[Treq, Tres],
|
|
opts PaginatorOptions,
|
|
) ([]Tobj, error) {
|
|
if opts.Logger == nil {
|
|
opts.Logger = log.NewEntry(log.StandardLogger())
|
|
}
|
|
var bfreq, cfreq any
|
|
fetchOffset := func(page int32) (Tres, error) {
|
|
bfreq = req.Page(page)
|
|
cfreq = bfreq.(PaginatorRequest[Treq, Tres]).PageSize(int32(opts.PageSize))
|
|
res, hres, err := cfreq.(PaginatorRequest[Treq, Tres]).Execute()
|
|
if err != nil {
|
|
opts.Logger.WithError(err).WithField("page", page).Warning("failed to fetch page")
|
|
if hres != nil && hres.StatusCode >= 400 && hres.StatusCode < 500 {
|
|
return res, err
|
|
}
|
|
}
|
|
return res, err
|
|
}
|
|
var page int32 = 1
|
|
errs := make([]error, 0)
|
|
objects := make([]Tobj, 0)
|
|
for {
|
|
apiObjects, err := fetchOffset(page)
|
|
if err != nil {
|
|
if page == 1 {
|
|
return objects, err
|
|
}
|
|
errs = append(errs, err)
|
|
continue
|
|
}
|
|
objects = append(objects, apiObjects.GetResults()...)
|
|
if apiObjects.GetPagination().Next > 0 {
|
|
page += 1
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
return objects, errors.Join(errs...)
|
|
}
|