fabbricadigitale / scimd Goto Github PK
View Code? Open in Web Editor NEWSCIM v2 golang implementation
License: MIT License
SCIM v2 golang implementation
License: MIT License
Currently resource struct is as follows:
type Resource struct {
Common
Attributes map[string]map[string]interface{} `json:"-"`
}
Should we privatize the Attributes
and create a setter ?
Filtering of static resources (Schemas, ResourceTypes) is not supported yet.
A layer to exclude unsupported chars contained in the Resource properties. It's need a one-to-one corrispondation from Resource to documentResource
TODOs:
"changePassword": {
"supported": false
},
within the Service Provider configuration
While using the query's Resources method, Iter's Next method it's being called and no iteration is being performed and so it seems that the result set is empty
It's needed to implement a way to apply the internal service provider logic to some attributes.
For example, password must be hashed prior to being stored.
Middleware pattern could be useful to accomplish that.
With validation tag "required" on bool type fields if you don't give that field value true, the test using Validator.Struct()
it will return this error :
'ResourceType.SchemaExtensions[0].Required' Error:Field validation for 'Required' failed on the 'required' tag
Fixed temporarily 6f23992 removing the required validation tag
This validator checks that if an attribute with a mutability of "writeOnly" has a returned setting of "never" (rfc7643).
Because the attributes are flattened the subattributes of a complex excludedAttribute cannot be differentiated, so they remain in the resulting set (ref).
GET \v2\User\...excludedAttributes=urn:something:User:name
included/default attributes
urn:something:User:name
urn:something:User:name.familyName
urn:something:User:email.value
excluded attributes
urn:something:User:name
resulting set = included/default attributes - excluded attributes
urn:something:User:name.familyName
urn:something:User:email.value
It makes so much assumptions for my tastes.
Infact it breaks when meta contains only resourceType and not all the other subattributes this method assumes always exist.
Create a custom validator that checks a give string matches the attribute notation.
Use the Path
parser already in place (within api/attr
directory).
When done, test it.
When tests will pass use it within the PR #29.
In order to release a beta version, here there is a list of task to be completed:
complete server handlers - 0
API validation - 1
compare password - 2
change password + enabling/disabling it - 3
check pagination and sorting - 4
error handling (validators, API) - 5
complete unit test
test harness (API) (#69)
test concurrency
setup CI + coverage
PATCH (optional)
CLI (commands, flags)
root search (POST)
etag
enabling/disabling filtering
enabling/disabling sorting
@leodido, @leogr, @samechelon feel free to add/remove tasks to/from this list.
The current situation is:
messages
needs core
schemas
needs core
resources
needs core
and schemas
Questions:
Refs #9
Hey @samechelon, use the custom validator attrname
to validate that the attribute names respect the rules.
So you have to populate with validate:attrname
the structs that require it.
Pay attention that for non scalar fields you have to use special keywords provided by the go-validator library (eg., dive
).
When you've done with this first sub-task, please provide the tests.
Note that tests for resource structs already exists, so augment them.
FYI @leogr
I propose to rename IsAssigned
.
We should also rename IsMultiValued
into IsMultiValue
since the complementar method is IsSingular
.
How to handle the authenticated subject alias (eg., /Me
endpoint) - Section 3.11 @ RFC7644
/User
Location
header pointing to the aliased resource (ie., User
)Copying from my notes at PR #46.
cc @fabbricadigitale/openinnovation
RFC 7643 @ section 3.1 mandates that the meta
attributes have a "returned" characteristic equal to "default".
This contrasts with the logic of attribute inclusion (and exclusion, ie. projection).
Namely,
attributes A multi-valued list of strings indicating the names of
resource attributes to return in the response, overriding the set
of attributes that would be returned by default.
attributes When specified, the default list of attributes SHALL be
overridden,
Our projection logic follows the RFC logic.
So, at the end when we specify to include only some attributes we lose the meta ones.
This causes panics in the code since within the storage/mongo/adapater.go::toResource()
method we expect/assume the dd["meta"]
cannot be nil.
Referring to the specific case of the Users-Groups relationship, I would like to focus on the relationship between resources in general.
The User resource has a "groups" attribute that represents a list of all the groups to which the user belongs. Note that this is an attribute with mutability readOnly.
The possibility of adding a relationship is left to the Gruop resource which has a list of "members" with a mutability readWrite.
Currently, the part of logic that for a new group member, adding this information to the corresponding User resource is missing.
I'm thinking about two solutions:
the information is stored in the user resource, so in the Create Group something must be activated so the corresponding User resource is changed.
the membership information is kept only in the Group resource and every time the user resource is requested the relationship in the Group resource is searched.
I think the latter is the most suitable in a mongodb context.
Excluding an attribute's subattribute will exclude every other subattribute of that attribute
eg., HERE
TEST RESULT
The test's result in this case will be positive, so it will pass, even though should be negative, it shouldn't pass, because the excluded subattribute
is urn:ietf:params:scim:schemas:core:2.0:User:emails.value
, while making a check on another subattribute
of email
that should be present among the email
attribute
's subattributes
.
The "path" attribute is described by the following ABNF syntax rule:
PATH = attrPath / valuePath [subAttr]
It's needed implementing valuePath and subAttr.
(more info: https://tools.ietf.org/html/rfc7644#section-3.5.2)
In order to posticipate patch
implementation I take note of potential critical issues.
The path attribute could be a valuePath expression. The ABNF syntax rule is PATH = attrPath / valuePath [subAttr]
. There is no way to access to subAttr from valuePath (#38).
It's to evaluate attribute mutability before to perform patch operations.
If patch operation introduces an attribute of a new schema, the client may implicit modify the schemas
attribute by adding the related schema URN.
A patch can perform more than one operation. Operations are applied sequentially in order they appear in the operations
array. The sequence is atomic, so if a single operation fails, the original scim resource have to be restored.
Add a table to Docs/Design.md to show validations vs actions
It is an optional server feature, we could implement it later.
The following is a draft of api's messages:
package messages
const BULK_REQUEST_URN = "urn:ietf:params:scim:api:messages:2.0:BulkRequest"
const BULK_RESPONSE_URN = "urn:ietf:params:scim:api:messages:2.0:BulkResponse"
type bulk struct {
Schemas []string `json:"schemas"`
Operations []struct {
Method string `json:"method"`
Path string `json:"path"`
BulkID string `json:"bulkId,omitempty"`
Version string `json:"version,omitempty"`
Data struct {
Schemas []string `json:"schemas"`
DisplayName string `json:"displayName"`
Members []struct {
Type string `json:"type"`
Value string `json:"value"`
} `json:"members"`
} `json:"data"`
} `json:"Operations"`
}
type BulkRequest struct {
bulk
FailOnErrors int `json:"failOnErrors,omitempty"`
}
type BulkResponse struct {
bulk
FailOnErrors int `json:"failOnErrors,omitempty"`
}
If there're no caveats, we should use Data Types also for Structured Resources.
In order to complete server handlers, here a list of TODO:
API for update (PUT) resources
Notice that PUT MUST NOT be used to create new resources
Search, Put and Delete handlers
field validation when posting a resource.
@leodido note that we can decorate field of the struct CommonAttribute with `binding:"required" etc, but we cannot do the same with the datatype.Complex resource data.
add in create and update api the business logic to retrieve the resource just created/updated
to be continued
I have push'd configuration phase for the upcoming server to the feature/server branch.
Tests have to be done.
config()
func and test that it returns a ServiceProviderConfig
instanceSchemaRepository
instance containing x Schema
instances has been createdResourceTypeRepository
instance containing y ResourceType
instances has been createdx := Number of JSON files within default/schemas directory
y := Number of JSON files within default/resources directory
Note that this step requires some parametrization (path of service provider config JSON) of the config
function.
So:
$ref
is ambiguous or is a special case$ref
nor myCu$stomAttr
as attr path).Thus, I think the presence of $
in the RFC is a typo. For those reason, since #28 it has been removed from implementation.
Refs:
Features like credentials validation, password recovery and account locking should be included in scimd? or these should be handled by another module with direct access to the identity store?
It's need an API thats for a given attribute path returns the related set of schema attributes.
We need a way to define the default count for pagination.
Probably this have to act also as an hard-cap (ie., maximum).
Currently the service provider configuration does not specify this.
How we want to implement this server configuration step?
cc @fabbricadigitale/openinnovation
Currently Structured Resources does not implement Unassigned and Null rules.
The main issue is that we can assign nil
to scalar attribute of a struct
.
In case of nested struct
(eg. Meta
) we could embed by-pointer, but it seems overkilling in case of scalars.
However, may be we do not need Unassigned and Null for attributes of these resources (ie. Schema
, ResourceType
, and ServiceProviderConfig
. If we can confirm that then we can close this issue and document this special case.
As per https://tools.ietf.org/html/rfc7643#section-2.1, attribute names MUST conform to the following ABNF rules:
ATTRNAME = ALPHA *(nameChar)
nameChar = "$" / "-" / "_" / DIGIT / ALPHA
Furthermore, ABNF strings are case insensitive so all attribute names should be case insensitive too, but it's difficult to achieve because implementation should:
schemas.core.Attribute
)fooBaz
and foobaz
)Maybe wont'fix?
If an empty ResourceType
is passed to the Contexts()
method will panic here
What to do if an empty ResourceType
somehow is passed to this method?
cc @leodido @samechelon @skryja
--- FAIL: TestResourceTypeValidation (0.00s)
Error Trace: resource_type_test.go:59
Error: "Key: 'ResourceType.Common.Schemas' Error:Field validation for 'Schemas' failed on the 'gt' tag
Key: 'ResourceType.Common.ID' Error:Field validation for 'ID' failed on the 'required' tag
Key: 'ResourceType.Common.Meta.Location' Error:Field validation for 'Location' failed on the 'uri' tag
Key: 'ResourceType.Common.Meta.ResourceType' Error:Field validation for 'ResourceType' failed on the 'required' tag
Key: 'ResourceType.Common.Meta.Created' Error:Field validation for 'Created' failed on the 'required' tag
Key: 'ResourceType.Common.Meta.LastModified' Error:Field validation for 'LastModified' failed on the 'required' tag
Key: 'ResourceType.Name' Error:Field validation for 'Name' failed on the 'required' tag
Key: 'ResourceType.Endpoint' Error:Field validation for 'Endpoint' failed on the 'startswith' tag
Key: 'ResourceType.Schema' Error:Field validation for 'Schema' failed on the 'required' tag" should have 3 item(s), but has 9
--- FAIL: TestServiceProviderConfigValidation (0.00s)
Error Trace: service_provider_config_test.go:77
Error: "Key: 'ServiceProviderConfig.Common.Schemas' Error:Field validation for 'Schemas' failed on the 'gt' tag
Key: 'ServiceProviderConfig.Common.ID' Error:Field validation for 'ID' failed on the 'required' tag
Key: 'ServiceProviderConfig.Common.Meta.Location' Error:Field validation for 'Location' failed on the 'uri' tag
Key: 'ServiceProviderConfig.Common.Meta.ResourceType' Error:Field validation for 'ResourceType' failed on the 'required' tag
Key: 'ServiceProviderConfig.Common.Meta.Created' Error:Field validation for 'Created' failed on the 'required' tag
Key: 'ServiceProviderConfig.Common.Meta.LastModified' Error:Field validation for 'LastModified' failed on the 'required' tag
Key: 'ServiceProviderConfig.Patch.Supported' Error:Field validation for 'Supported' failed on the 'required' tag
Key: 'ServiceProviderConfig.Bulk.Supported' Error:Field validation for 'Supported' failed on the 'required' tag
Key: 'ServiceProviderConfig.Bulk.MaxOperations' Error:Field validation for 'MaxOperations' failed on the 'required' tag
Key: 'ServiceProviderConfig.Bulk.MaxPayloadSize' Error:Field validation for 'MaxPayloadSize' failed on the 'required' tag
Key: 'ServiceProviderConfig.Filter.Supported' Error:Field validation for 'Supported' failed on the 'required' tag
Key: 'ServiceProviderConfig.Filter.MaxResults' Error:Field validation for 'MaxResults' failed on the 'required' tag
Key: 'ServiceProviderConfig.ChangePassword.Supported' Error:Field validation for 'Supported' failed on the 'required' tag
Key: 'ServiceProviderConfig.Sort.Supported' Error:Field validation for 'Supported' failed on the 'required' tag
Key: 'ServiceProviderConfig.Etag.Supported' Error:Field validation for 'Supported' failed on the 'required' tag
Key: 'ServiceProviderConfig.AuthenticationSchemes' Error:Field validation for 'AuthenticationSchemes' failed on the 'required' tag" should have 10 item(s), but has 16
There're some TODOs within /schemas/core
to be done.
Maybe some parts are not yet fully tested, and should be done.
Depends on #33
But it is necessary to exclude attributes that the server must not return (eg returned: never
attributes)
Line 68 in e7e5c9d
When a new resource is created, an HTTP response is returned with HTTP status code 201 (Created). There isn't the newly created resource in the body of the response.
We want to fix that? @leodido @samechelon @leogr
RFC7644 is ambiguous about the not
trailing space.
ABNF rule say:
FILTER = attrExp / logExp / valuePath / *1"not" "(" FILTER ")"
(ie. no trailing space)
But examples have spaces:
filter=userType ne "Employee" and not (emails co "example.com" or emails.value co "example.org")
Currently, the implementation includes a trailing space thus we're assuming that not ()
is the canonical form, even the parser matches both not ()
and not()
.
Maybe it's not problematic.
Reference here.
Structured and Mapped Resources are different but should be identical for consumers.
For instance, ListResponse
needs to use both but currently cannot.
Also, a Resource Interface could totally de-couple core
and resource
packages.
Since core
needs to use Resource Interface it should be defined in the same package, then core
could implement it for Structured and resource
for Mapped.
Furthermore, third-party could use it to implement other kinds of resource.
However, the two kinds are using attributes in different ways actually I have no clear ideas how the interface should be.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.