Introducing gowrap as a build-time tool to generate interface delegate
structs from templates:
* added as a 'make go-generate' target in services/graph,
* added as a build-time dependency in .bingo/
Introduce an LDAP client abstraction interface to be able to wrap the
go-ldap client API with metrics transparently (and possibly hooks and
such in the future), in order to use delegation patterns to measure the
time LDAP (client) operations take to finish, as well as to track their
results (success, failure, not-found).
Has two implementations that are generated using gowrap:
* a go-ldap adapter implementation that directly delegates to a go-ldap
connection
* a time measuring and metrics collecting implementation that delegates
to another LdapClient
The metrics collecting one is disabled by default, can be enabled with
GRAPH_LDAP_METRICS_DISABLE=false
It collects durations of outbound LDAP client operations into a histogram, as
well as the number of concurrent outbound LDAP operations in a gauge (via an
atomic int and a gauge function, as that performs best).
Add an HTTP middleware that measures how long Graph HTTP API requests
take, storing taken time into a histogram along with labels for
* method,
* path pattern (from the chi routes),
* Graph API version prefix,
* Graph API resource name,
* and the resulting status code.
It also tracks the number of concurrent inbound Graph API HTTP requests
using a gauge (also using an atomic int and a gauge function).
Disabled by default, can be enabled with
GRAPH_HTTP_METRICS_DISABLE=false
Add Backend and EducationBackend delegate implementations that measure
execution time on the level of the higher API call operations there
(CreateUser, DeleteUser, ..., CreateSchool, ...), generated using
gowrap.
Disabled by default, can be enabled with
GRAPH_IDENTITY_BACKEND_METRICS_DISABLE=false
Also added a small k6 script to produce some read-only load on the Graph
API, for a casual test of the metrics, as well as k6 in mise.toml.
Make an internal changes to how singular LDAP entry searches work in the LDAP
identity backends:
* check whether searches for a singular entry returns more than one
result, in which case a new error TooManyResults is returned, instead
of leaving that undetected, blindly taking the first result, and
potentially risking data inconsistencies
Improve the loggers in identity backends by adding attributes for their
request targets (Reva gateway address or LDAP URI, respectively).
Also add a "backend" attribute for all Graph API logs (set to "ldap" or
"cs3"), to help debug potential issues, and remove them from all the logger
debug calls at the beginning of each LDAP-related function as those should
really be part of the logger and set beforehand.
The LDAP identity backend logger also has two new attributes to help
debugging with logs:
* write (bool): whether write operations are enabled
* refint (bool): whether refint is enabled or not
Also adds a dedicated counter metric for user password change operations.
Minor campfire improvements:
* add a constructor func for the CS3 backend
* add a constructor func for the LDAP backend
* in the LDAP identity backend, in searchLDAPEntryByFilter (used by all
search/get public functions), errors that occur when performing LDAP
SEARCH operations were blindly mapped to a ItemNotFound error,
instead of being analyzed as it could be caused by a technical error
* in the requireadmin middleware, add debug logging to explain why a
request is denied
* when an LDAP password change fails because the user entry was not
found in LDAP, we now have a log message that tracks that
Remove the ability to look up schools by externalId directly (from LDAP
filters, duplicate checks, and the EducationBackend interface). This
approach was somewhat unclean, we shouldn't add more an more attributes
as keys for direct lookup.
Instead, expose externalId filtering via the OData $filter query
parameter on GET /education/schools, following the same pattern as
for education users.
Related: #1598
This adds support of simple OData filters on the 'education/users'
endpoint. Filters of the type '$filter=<attr> eq <value>' are supported
now for the following educationUser properties:
"displayname", "mail", "userType", "primaryRole" and "externalId"
Closes: #1599
Up to now we only set the OpaqueId attribute, which breaks sharing as soon as
multi-tenancy is enabled. We need the full UserId (including the
tenantId and the idp value).
Related Issue: #1194
The UserIds as returned by e.g. GetAcceptedUser do already contain
the provider domain in the IDP field now.
Also adjust the provider domain in the OCM config to be really a domain
without URI scheme and path.
It is now possible to filter users based on the lastSuccessfulSignInDateTime attribute
using query filter like:
'$filter=signInActivity/lastSuccessfulSignInDateTime le 2021-09-01T00:00:00Z'
Note: This does only work with LDAP servers actually supporting '<=' filters.
The built-in LDAP server (idm) does not support this feature.
* enhancement: add graph beta listPermissions endpoint
besides the new api endpoint it includes several utilities to simplify the graph api development.
* resolve drive and item id from the request path
* generic pointer and value utilities
* space root detection
* update GetDriveAndItemIDParam signature to return a error
* move errorcode package
* enhancement: add generic error code handling
* fix: rebase
This adds some initial support for using $filter (as defined in the
odata spec) on the /users endpoint. Currently the following filters are
supported:
A single filter on `id` property of the `memberOf` relation of users.
To list all users that are members of a specific group:
```
curl 'https://localhost:9200/graph/v1.0/users?$filter=memberOf/any(m:m/id eq '262982c1-2362-4afa-bfdf-8cbfef64a06e')
```
A logical AND filteri on the `id` property of the `memberOf` relation of users.
`$filter=memberOf/any(m:m/id eq 262982c1-2362-4afa-bfdf-8cbfef64a06e) and memberOf/any(m:m/id eq 6040aa17-9c64-4fef-9bd0-77234d71bad0)`
This will cause at least two queries on the identity backend. The `and`
operation is performed locally.
Closes: #5487
In preparation for some more advanced queries pass the parse odata request
tVo the identity backend methods instead of the raw url.Values{}. This also
add some helpers for validating $expand and $search queries to reject
some unsupported queries.
Also remove support for `$select=memberOf` and `$select=drive|drives` queries
and stick to the technically correct `$expand=...`.
We don't need to support any complex queries on /education (yet?). And if we would need
to add support for $search, $filter, $expand or $select we should pass the parsed odata Query
instead of the raw url.Values struct.
As described in #5410: add support for updating educationClass properties.
This adds the `UpdateEducationClass` to the `EducationBackend` interface,
and implements it on the `ErrEducationBackend` and `LDAP` backends.
It also alters `PatchEducationClass` to call the `UpdateEducationClass` method.
Closes#5410
* Renamed files for consistency reasons
err_school.go implements the full education interface not just schools.
ldap_school.go renamed to ldap_education_school.go for making it
consistent with ldap_education_user.go
* graph: Add stubs for education/classes endpoints
The acutal backend implementations are still empty.
This makes the identity errors public so other packages can match on them.
It also moves them to the same file as the interface, as that makes them more discoverable.