mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
118 lines
4 KiB
ReStructuredText
118 lines
4 KiB
ReStructuredText
|
|
Schema
|
|
------
|
|
|
|
Schema is one of the three foundational concepts of the server, along with filters and entries.
|
|
Schema defines how attribute values *must* be represented, sorted, indexed and more. It also
|
|
defines what attributes could exist on an entry.
|
|
|
|
Why Schema?
|
|
-----------
|
|
|
|
The way that the server is designed, you could extract the backend parts and just have "Entries"
|
|
with no schema. That's totally valid if you want!
|
|
|
|
However, usually in the world all data maintains some form of structure, even if loose. We want to
|
|
have ways to say a database entry represents a person, and what a person requires.
|
|
|
|
Attributes
|
|
----------
|
|
|
|
In the entry document, I discuss that avas have a single attribute, and 1 to infinite values that
|
|
are utf8 case sensitive strings. Which schema attribute types we can constrain these avas on an
|
|
entry.
|
|
|
|
For example, while the entry may be capable of holding 1 to infinite "name" values, the schema
|
|
defines that only one name is valid on the entry. Addition of a second name would be a violation. Of
|
|
course, schema also defines "multi-value", our usual 1 to infinite value storage concept.
|
|
|
|
Schema can also define that values of the attribute must conform to a syntax. For example, name
|
|
is a case *insensitive* string. So despite the fact that avas store case-sensitive data, all inputs
|
|
to name will be normalised to a lowercase form for faster matching. There are a number of syntax
|
|
types built into the server, and we'll add more later.
|
|
|
|
Finally, an attribute can be defined as indexed, and in which ways it can be indexed. We often will
|
|
want to search for "mail" on a person, so we can define in the schema that mail is indexed by the
|
|
backend indexing system. We don't define *how* the index is built - only that some index should exist
|
|
for when a query is made.
|
|
|
|
Classes
|
|
-------
|
|
|
|
So while we have attributes that define "what is valid in the avas", classes define "which attributes
|
|
can exist on the entry itself".
|
|
|
|
A class defines requirements that are "may", "must", "systemmay", "systemmust". The system- variants
|
|
exist so that we can ship what we believe are good definitions. The may and must exists so you can
|
|
edit and extend our classes with your extra attribute fields (but it may be better just to add
|
|
your own class types :) )
|
|
|
|
An attribute in a class marked as "may" is optional on the entry. It can be present as an ava, or
|
|
it may not be.
|
|
|
|
An attribute in a class marked as "must" is required on the entry. An ava that is valid to the
|
|
attribute syntax is required on this entry.
|
|
|
|
An attribute that is not "may" or "must" can not be present on this entry.
|
|
|
|
Lets imagine we have a class (pseudo example) of "person". We'll make it:
|
|
|
|
Class {
|
|
"name": "person",
|
|
"systemmust": ["name"],
|
|
"systemmay": ["mail"]
|
|
}
|
|
|
|
If we had an entry such as:
|
|
|
|
Entry {
|
|
"class": ["person"],
|
|
"uid": ["bob"],
|
|
"mail": ["bob@email"]
|
|
}
|
|
|
|
This would be invalid: We are missing the "systemmust" name attribute. It's also invalid because uid
|
|
is not present in systemmust or systemmay.
|
|
|
|
Entry {
|
|
"class": ["person"],
|
|
"name": ["claire"],
|
|
"mail": ["claire@email"]
|
|
}
|
|
|
|
This entry is now valid. We have met the must requirement of name, and we have the optional
|
|
mail ava populated. The following is also valid.
|
|
|
|
Entry {
|
|
"class": ["person"],
|
|
"name": ["claire"],
|
|
}
|
|
|
|
Classes are 'additive' - this means given two classes on an entry, the must/may are unioned, and the
|
|
strongest rule is applied to attribute presence.
|
|
|
|
Imagine we have also
|
|
|
|
Class {
|
|
"name": "person",
|
|
"systemmust": ["name"],
|
|
"systemmay": ["mail"]
|
|
}
|
|
|
|
Class {
|
|
"name": "emailperson",
|
|
"systemmust": ["mail"]
|
|
}
|
|
|
|
With our entry now, this turns the "may" from person, into a "must" because of the emailperson
|
|
class. On our entry Claire, that means this entry below is now invalid:
|
|
|
|
Entry {
|
|
"class": ["person", "emailperson"],
|
|
"name": ["claire"],
|
|
}
|
|
|
|
Simply adding an ava of mail back to the entry would make it valid once again.
|
|
|
|
|