Specification
This document specifies RestAuth, a simple protocol that may be used for implementing shared authentication, authorization and preferences. It is (loosely) based on the REST Paradigm[i 1] with some deviations to ease protocol implementation.
Status
This is the development version of the RestAuth protocol. Older versions are available here:
ChangeLog
0.7 - Not released yet
Changes to version 0.6 are:
- Getting or setting a property now returns a dictionary for consistency. This introduces an incompatibility between RestAuth versions.
- Clarify that properties and groups are subject to the same restrictions on entity names when created.
- Restrictions on entity names now specifies a stringprep profile of disallowed characters. No other characters are now disallowed, therefore "\" et al. are now legal characters.
- Three new headers are now part of the specification:
- New parameters:
- Pass an initial set of groups when creating a user.
- Pass a set of groups when verifying a password.
- Pass an initial set of users when creating a group.
- Add url as a predefined property name.
- Passing an empty string for a password is considered to be equal to not passing a password at all.
- New methods:
Version 0.6 - 2012-08-16
- The HTTP Status code 403 Forbidden may now be returned on all requests. It indicates that the credentials provided by the client are valid, but the client is not authorized to perform the action.
- The standard now defines that the server may automatically define an initial set of properties for newly created users.
- Two new predefined property names: last login and date joined.
- A PUT request to /users/<user>/props/ allows setting multiple properties at once.
- Fixed minor spelling mistakes, etc.
The exact difference between the two protocols may be viewed by this diff.
Version 0.5 - 2011-08-28
Initial version of the protocol.
Copyright
Copyright (C) Mathias Ertl (2010-2015)
Introduction
RestAuth defines an HTTP based protocol intended to enable shared authentication, authorization and preferences. The primary design goals are the use of established Internet standards and ease of implementation, both on the client and on the server side.
Statelessness
As with any protocol based on the REST paradigm[i 1], RestAuth is a stateless protocol. This also means that the system does not implement transactions of any kind. For example, a user that exists in the first request is not guaranteed to exist in a second request a second later.
Data types
This document specifies an HTTP interface with the body of the request/response containing the relevant data. The protocol specification is agnostic to data formats. This document instead defines three simple abstract data types and provides mappings to common Internet data formats (see Mapping abstract data types to concrete data types).
String
A simple string as found in most programming languages. In general this is a UTF-8 string and the format itself does not pose any restrictions on used characters. An implementing service may impose some restrictions, especially when handling user-, group or propertynames (see Restrictions on entity names).
Dictionary
Any number of key/value pairs, each key being a string, values may be either strings, dictionaries or lists.
Note: A dictionary or list contained within a dictionary (currently) only has string values.
List
A list of strings, used when returning multiple items (usually identifiers for entities) at once.
Standards
The RestAuth protocol builds upon several different Internet standards. Defined here are standards and versions thereof that any implementing client or server is required to implement:
- Hypertext Transfer Protocol -- HTTP/1.1[n 1][i 2]
- HTTP Authentication: Basic and Digest Access Authentication[n 2]
- The application/json Media Type for JavaScript Object Notation (JSON)[n 3][i 3]
- The UTF-8[n 4][i 4] character encoding scheme
Other standards that may be of interest when implementing software building on the RestAuth protocol:
Notation
If request strings include a value dependent on the context, this value is enclosed in angle brackets. For example, if the client wants to do a request for the properties of the user "example", it does a GET request to /users/example/props/. The specification specifies to do a request to /users/<username>/props/.
Protocol framework
The RestAuth protocol is based upon HTTP 1.1[n 1]. This section defines common headers that have to be included in all or most requests and/or responses as well as error status codes that may be returned by a server implementation.
Restrictions on entity names
Entity names, that includes users, user properties and groups, are subject to the following stringprep[n 6] profile:
Table | Notes |
---|---|
Table B1 Commonly mapped to nothing | Characters should be stripped before processing any RestAuth entity. |
Table B2 Mapping for case-folding used with NFKC | Characters should be normalized and lowercased before processing. |
Table C.1.2 Non-ASCII space characters | Illegal in any RestAuth entity name |
Table C.2 Control characters | Illegal in any RestAuth entity name |
Table C.3 Private use | Illegal in any RestAuth entity name |
Table C.4 Non-character code points | Illegal in any RestAuth entity name |
Table C.5 Surrogate codes | Illegal in any RestAuth entity name |
Table C.6 Inappropriate for plain text | Illegal in any RestAuth entity name |
Table C.7 Inappropriate for canonical representation | Illegal in any RestAuth entity name |
Table C.8 Change display properties or are deprecated | Illegal in any RestAuth entity name |
Table C.9 Tagging characters | Illegal in any RestAuth entity name |
A few things to note:
- Table B1 includes a few characters also present in other tables. A RestAuth service should strip the characters in Table B1 first before checking for any invalid characters.
- Table C.1.1 is *not* a restriction, simple spaces are allowed.
- All entity names must be case insensitive. The RestAuth service is responsible for lower-casing entity names upon creation and during queries.
- A RestAuth service may introduce additional practical restrictions on entity names. This may include (for example) additional invalid characters or a minimum or maximum length.
Security considerations
Since a RestAuth service stores sensitive information, security is of the utmost importance. For a server implementation to be standards compliant, several security criteria have to be met:
Use of SSL
Both clients and servers must use HTTPS exclusively. Clients or client libraries must not support HTTP without SSL. Server implementations must not offer pure HTTP connections if the server provides its own web server.
Configuration examples, etc., have to assume that HTTPS is used.
If clients are themselves servers (i.e. a Content Management System), they should use SSL for all traffic that transmits passwords or secret session data (i.e. HTTP cookies).
Password hashes
A server implementation must store passwords hashed with a hashing algorithm currently considered secure. This explicitly excludes:
- Unsalted hashes such as pure MD5 or SHA1 hashes
- Primitively salted hashes
No specific password hash algorithm is mandated in this document, since any hash-algorithm might be considered insecure in the future. Software authors are encouraged to use existing libraries of the respective language for secure hashing.
Service authentication
RestAuth service implementations must require the use of an HTTP authentication mechanism as defined in "HTTP Authentication: Basic and Digest Access Authentication"[n 2] on all requests. Both servers and clients must support Basic Access Authentication[n 7], support for Digest Access Authentication[n 8] is optional.
Note: Do not confuse the username and password used in request authentication with the usernames and passwords that are shared between services and stored in a RestAuth implementation.
Content encoding
The data encoded in request and response bodies must be encoded in UTF-8[n 9][i 4].
Request headers
Accept header
All requests SHOULD include an Accept
header[n 10] indicating media types acceptable by the client.
If the server needs to generate a response (when returning a 200 OK status code) and the header does not specify any media type the server can generate, it MUST return a 406 Not Acceptable status code. If the server does not need to generate a response body (as with a 201 Created or 204 No Content status code) it might ignore a missing Accept header.
If the header is missing, the server may return a 406 Not Acceptable status code or assume a default media type.
Content-Type header
Every POST[n 11] or PUT[n 12] request MUST include a Content-Type
[n 13] header.
If the header indicates a content-type not supported by the server or is missing, it MUST return a 415 Unsupported Media Type. If the content is not parsable as the type indicated by this header, the server MUST return a 400 Bad Request status code.
Referer header
All requests MAY include a Referer
header[n 14] to indicate the URL an end-user was viewing when triggering a request. It is recommended to use the full URL (including the domain) and not a relative URL.
X-Forwarded-For
All requests MAY include a X-Forwarded-For header to indicate the IP address of the end-user.
X-RestAuth-Version
Requests SHOULD include a X-RestAuth-Version
header to indicate the version of RestAuth being used.
If the header is not included, it is up to the server to decide what version to assume.
Response headers
Content-Type header
Every response except for 204 No Content must include a Content-Type header.
The Content-Type of the response MUST be one indicated by the Accept header send in the original request. If the request gives a wildcard, the server can use some sensible default.
Resource-Type header
If the server returns a 404 Not Found, it must include the Resource-Type header, which must indicate the type of resource not found. The value must be one of user, group or property. If the request URI addressed multiple resources at once (i.e. when getting a user property), the value of the header must be the first resource addressed in the URI.
Response codes
This section lists response codes the server may return on any or most requests. Requests that may be returned by any request are 401 Unauthorized, 406 Not Acceptable and 500 Internal Server Error. The status codes 400 Bad Request, 411 Length Required and 415 Unsupported Media Type may occur with any POST or PUT request. Apart from these status codes, the specification on individual requests gives an authoritative list of status codes returned by each individual request.
200 OK
The general status code that should be returned upon successfully processing a request is 200 OK[n 15].
201 Created
A RestAuth service must respond with status code 201 Created[n 16] if the request created a new resource. This status code must only occur with POST or PUT requests.
Note that as by the HTTP/1.1 specification[n 1], responses of this type must include both a Location header and a response body giving the URI under which the newly created resource can be addressed. The presence of a response body infers the presence of a Content-Type header.
204 No Content
A RestAuth service must respond with status code 204 No Content[n 17] if the request only verifies the existence of the addressed entity or if an entity was successfully updated.
Note that by definition, this response must not include a response body. Please see the referenced HTTP specification for details.
400 Bad Request
The RestAuth service must respond with status code 400 Bad Request[n 18] if
- the request body could not be parsed as the content-type indicated by the Content-Type header
- the request body was parsable but did not contain the parameters expected.
Since this status code addresses the request body and only POST[n 11] and PUT[n 12] requests have such a body, this status code only occurs with requests of type POST or PUT.
401 Unauthorized
The RestAuth service must respond with status code 401 Unauthorized[n 19] if the client failed to authenticate itself. The WWW-Authenticate header must be present in such a response and include at least a Basic Authentication[n 7] challenge. A Digest Authentication[n 8] may also be present but is optional.
This status code may occur with requests of any type and at any URI.
403 Forbidden
The RestAuth service must respond with status code 403 Forbidden[n 20] if the client did successfully authenticate itself, but the client is not allowed to perform such a request. An example would be if only a specific subset of operations is available for a certain client for security reasons.
This status code may occur with requests of any type and at any URI.
404 Not Found
The RestAuth service must respond with status code 404 Not Found[n 21] if a resource accessed by the request does not exist. In case of this response code, the Resource-Type header must exist and indicate the type of the resource not found.
This status code must not occur with a request that does not address an individual entity. In particular, this includes:
- requests meant to return a list of entities (i.e. querying all users: GET /users). If there are no entities defined, the service must return an empty list.
- requests meant to add an entity to a an existing collection (i.e. adding a user: POST /users/). If the entity is already defined, the service must return 409 Conflict.
Note: Since 404 Not Found is the standard response code for pages not found, you are likely to encounter this error if your request uses an invalid path, i.e. to /userrs/, /ussers/ or so.
406 Not Acceptable
The RestAuth service must respond with status code 406 Not Acceptable[n 22] if the service cannot generate a response in any of the data formats indicated by the Accept header. If the header is not present at all, the server may return this status code or assume a sensible default.
If the specification specifies a status code that does not include a message body in case of success (201 Created or 204 No Content), the RestAuth service may ignore a missing Accept header.
409 Conflict
The RestAuth service must respond with status code 409 Conflict[n 23] if the request attempts to create an entity that is already defined.
This status code can only occur on top-level POST requests, currently only creating users, properties or groups.
411 Length Required
The RestAuth service must respond with status code 411 Length Required[n 24] if a POST or PUT request does not have a Content-Length header.
Since this status code addresses the request body and only POST[n 11] and PUT[n 12] requests have such a body, this status code only occurs with requests of type POST or PUT.
412 Precondition Failed
The RestAuth service must respond with status code 412 Precondition Failed[n 25] if a requests attempts to update a resource to a value not acceptable to the system. In particular, this includes unacceptable (too short, unacceptable characters, ...) usernames or passwords.
415 Unsupported Media Type
When receiving a POST or PUT request, a RestAuth service MUST return status code 415 Unsupported Media Type[n 26] if the request does not include a Content-Type header or if the header indicates a media type unsupported by the server implementation.
This status code only occurs with POST[n 11] or PUT[n 12] requests.
500 Internal Server Error
The RestAuth service may return status code 500 Internal Server Error[n 27] if any internal error occurs.
501 Not Implemented
The RestAuth service may return status code 501 Not Implemented[n 28] when a client makes a request related to Meta-groups and the service does not support them.
Managing users
RestAuth tries to make it as simple as possible to implement basic user authentication. A user described in this section consists of nothing more but a unique name (which is used as a unique identifier in all requests) and a password, it has no properties or groups. This section just specifies the very basic user management operations.
Because of the simplicity of the task, all requests except getting a list of users do not require any response body - it is enough to know the response code.
Get a list of users
To get a list of all users known to the system, the client does a GET request to /users/.
The server must respond with a list of usernames known to it. The response code must be 200 OK if no internal error occurs.
Create a user
To create a new user, the client does a POST request to /users/. The request body must be a dictionary, that must include the name of the user and may include a password, initial properties and initial groups.
key | value | type |
---|---|---|
Mandatory parameters | ||
user |
The name of the user. | String |
Optional parameters | ||
password |
The password for the user. If the parameter is not included or an empty string, the user does not have a password and is unable to log in. Consequently, every password verification request must return with 404 Not Found. | String |
properties |
Initial properties, where keys represent the name of a property and their respective value represents the value of that property. | Dictionary |
groups |
An initial list of groups. Groups that don't exist must be automatically created. | List |
The server must respond with status code 201 Created if the user is successfully created and with 409 Conflict if the user already exists.
The restrictions on entity names do apply for this request. The service may enforce additional requirements on usernames and/or passwords. If the submitted data does not meet any of these requirements (as well as the minimum requirements on usernames), the server must respond with a 412 Precondition Failed.
Verify that a user exists
To verify that a user exists, the client does a GET request to /users/<username>/.
The server must respond with status code 204 No Content if the user exists and 404 Not Found if not.
Verify password
To verify a users password, the client does a POST request to /users/<username>/. The request body must be a dictionary containing the password to verify:
key | value | type |
---|---|---|
password |
The password to verify. | String |
Optional parameters | ||
groups |
A list of groups. If provided, the user is required to be a member of at least one of the given groups. | List |
The server must respond with status code 204 No Content if the user exists and the password is correct. If either the user does not exist or the password is not correct, the server must respond with status code 404 Not Found.
If the optional groups
parameter is given and is a non-empty list, the user is also required to be a member of at least one of the given groups. If the user is not a member of any of the given groups, the the server must return 404 Not Found just as if the password was incorrect.
Note: Following the REST paradigm, this really should be a GET request, not a POST request. GET requests have one major disadvantage, though: GET parameters are usually logged in the log-files of a web server. This would mean that a password verification request to /users/<username>?password=<password> would be logged. There are ways around logging this, but services should always be "secure by default".
Change password
To change the password of a user, the client does a PUT request to /users/<username>/. The request body must be a dictionary containing the new password:
key | value | type |
---|---|---|
Optional parameters | ||
password |
The password to verify | String |
If the password
parameter is not given or an empty string, the user should have no password and be unable to log in. Any password verification request must return with 404 Not Found.
The server must respond with status code 204 No Content if the password was successfully updated and with status code 404 Not Found if the user does not exist. If the service enforces additional requirements on passwords and the new password does meet any of these requirements, the server must respond with a 412 Precondition Failed.
Delete a user
To delete a user, the client does a DELETE request to /users/<username>/.
The server must respond with status code 204 No Content if the user was deleted. If the user didn't exist, the server must respond with 404 Not Found.
Managing user properties
It is possible to use RestAuth to store user properties, commonly used for shared user preferences. Properties are just simple key/value pairs and both keys and values are completely arbitrary. The specification only gives recommendations about property names and a list of predefined property names for popular preferences.
A property and its value always only exists in the context of a specific user. Thus, the common prefix for all requests defined in this section is /users/<username>/props/ where <username> is of course the name of the user in this context.
Recommendations about property names
The RestAuth protocol does not define any mandatory conventions on protocol names, services may share properties with any name they like. There are however some "common sense" assumptions.
- If a property is only useful within one specific application, consider storing the property locally. If you still want to save it in a RestAuth server, prefix it with the service name.
- If a property is useful for multiple clients of the same type (i.e. several installations of the same content management system), prefix the preferences with a name for this type of system.
- Only if preferences may be useful to multiple clients, use a simple name. You may want to consider mapping them to one of the predefined names.
Initial set of properties for new users
The server may automatically create some properties if a new user is created, so a new user is not guaranteed to have an empty set of properties. A common usecase would be to automatically create the date joined property.
Predefined property names
This section gives some recommendations about property names for some well known properties that are likely to occur in multiple systems.
key | what |
---|---|
email |
Email address of the user. |
url |
Homepage of the user. |
jid |
Jabber address of the user. |
full name |
Full name of the user. If possible, use 'first name' and 'last name' instead. |
first name |
First name of the user. |
last name |
Last name of the user. |
language |
The preferred language of the user. |
last login |
The last time the user logged in. The RestAuth server should auto-update the value every time the password is verified.
|
date joined |
The date the user joined. The RestAuth server must automatically set this value once the user is created.
|
Get all properties
To get a list of all properties and their respective values for a user, the client performs a GET request to /users/<user>/props/.
The server must respond with status code 200 OK if the user exists. The response body must contain a dictionary, where the keys represent the name of the property and the value the value of that property. If the user is not found, the client must respond with 404 Not Found.
Create a new property
To create a new property for a user, the client performs a POST request to /users/<user>/props/. This request is intended for creating new properties where the client wants to be sure not to overwrite any old value.
The request body must be a dictionary with two key/value pairs:
key | value | type |
---|---|---|
prop |
The name of the property to define. | String |
value |
The value for that property. | String |
If the property is successfully created, the server must respond with status code 201 Created. If the property already exists, the server must respond with 409 Conflict. If the user is not found, the server must respond with 404 Not Found.
The restrictions on entity names do apply for this request. If the submitted data does not meet the requirements, the server must respond with a 412 Precondition Failed.
Set values of multiple properties
To set multiple properties at once, the client performs a PUT request to /users/<user>/props/. The request body must be a dictionary where each key/value pair represents the name and value of a property. Any properties that don't exist must be created.
The response code for a successful request is 204 No Content. This means that no old values are returned in the request.
If the user does not exist, the server must respond with 404 Not Found.
Get value of a property
To get the value for one specific property, the client performs a GET request to /users/<user>/props/<prop>/.
If the addressed user and property exists, the server must respond with 200 OK. The response body must the response body must be a dictionary representing the value of the property:
key | value | type |
---|---|---|
value |
The previous value of the property. | String |
If the user or the property does not exist, the server must respond with 404 Not Found.
Set value of a property
To set the value of a property (or create it, if it doesn't exist), the client performs a PUT request to /users/<user>/props/<prop>/. The request body must be a dictionary containing the new value:
key | value | type |
---|---|---|
value |
The new value of the property. | String |
If the property was created by this request, the server must respond with status code 201 Created. If the property already existed, the server must respond with status code 200 OK and the response body must be a dictionary representing the previous value of that property:
key | value | type |
---|---|---|
value |
The previous value of the property. | String |
If the user is not found, the server must respond with 404 Not Found.
The restrictions on entity names do apply for this request. If the submitted data does not meet the requirements, the server must respond with a 412 Precondition Failed.
Delete a property
To delete a property, the client does DELETE request to /users/<username>/props/<prop>/.
The server must respond with status code 204 No Content if the property was deleted. If the user or the property does not exist, the server must respond with 404 Not Found.
Managing user groups
It is possible to use RestAuth to store user groups, commonly used for shared authorization. Any user may be member of zero, one or multiple groups. The specification does not mandate any particular inheritance (see Nested groups) or visibility model (see Group visibility), thus clients might not be able to tell where any particular membership is coming from.
Meta-groups
A RestAuth implementation may provide meta-groups. The concept describes that one or more groups may be themselves member of a group, called a meta-group. A group that is a member of a meta-group inherits all memberships from it and is called a sub-group of the meta-group. The membership to a sub-group is said to be inherited if the user is a member of the meta-group and local if the user is a member of the sub-group. A meta-group may itself also be a member of a meta-meta-group.
One common use case is granting some users privileges in all clients and some other users in only a few clients. To achieve this, the RestAuth service could have a meta group. The meta-group is not used by any client directly, instead each client has its own group, each a sub-group of the meta-group, to manage the respective privilege(s). The meta-group contains all the users that should have the privilege for all clients, the sub-group only contains the users that should have this privilege in one individual client.
Implementation of meta-groups is optional (but recommended). If the RestAuth service implements meta-groups, it must provide adding a group to a group and removing a group from a group.
Group visibility
A RestAuth server may choose to implement groups in a way that they are local to the client creating and accessing them. A group from client A is hence not visible for client B and vice versa. Additionally, a group may not be associated by any service and thus not accessible by any service directly, potentially useful as meta-groups.
The implementation of group visibility does not change the interface in any way. But implementing group visibility together with meta-groups might lead to situation that the client is unable to tell the difference between a local and an inherited membership.
Get a list of groups
To get a list of all groups known to the system, the client does a GET request to /groups/.
The server must respond with a list of groups known to it. The response code must be 200 OK if no internal error occurs.
Get all groups of a user
To get a list of all groups known to the system, the client does a GET request to /groups/ with get GET parameter user=<user>.
The server must respond with a list of groups that the user is a member of. The response code must be 200 OK if no error occurs or with 404 Not Found if the user does not exist.
Create a group
To create a new group, the client does a POST request to /groups/. The request body must be a dictionary representing the name of the group and an optional list of initial users:
key | value | type |
---|---|---|
group |
The name of the group to create. | String |
Optional parameters | ||
users |
An initial set of users for the group. | List |
The server must respond with status code 201 Created if the group is successfully created and with 409 Conflict it the group already exists. If any of the initial users don't exist, the server must respond with status code 404 Not Found.
The restrictions on entity names do apply for this request. If the submitted data does not meet the requirements, the server must respond with a 412 Precondition Failed.
Set groups of a user
To set the groups of a user, the client does a PUT request to /groups/ with a Dictionary containing these fields:
key | meaning | type |
---|---|---|
user |
The user to set the groups for. | String |
groups |
The groups of the user. | List |
The server must respond with status code 204 No Content if the operation was successful and with 404 Not Found it the user was not found. Groups that do not exist have to be created by this request. Passing an empty list removes all list memberships. Note that if a service provides Meta-groups and group visibility, this request must not remove memberships inherited from groups from a different service.
The restrictions on entity names do apply for this request. If the submitted groups do not meet the requirements, the server must respond with a 412 Precondition Failed.
Verify that a group exists
To verify that a group exists, the client does a GET request to /groups/<group>/.
The server must respond with status code 204 No Content if the group exists and 404 Not Found if not.
Delete a group
To delete a group, the client does a DELETE request to /groups/<group>/.
The server must respond with status code 204 No Content if the user was deleted. If the group didn't exist, the server must respond with 404 Not Found.
Get all users in a group
To get a list of all users in a specified group, the client does a GET request to /groups/<group>/users/.
The server must respond with a list of users in the specified group. The response code must be 200 OK if the group exists or 404 Not Found if the group does not exist.
Add a user to a group
To add a user to a group, the client performs a POST request to /groups/<group>/users/. The request body must be a dictionary containing the name of the user to add:
key | value | type |
---|---|---|
user |
The name of the user to add. | String |
The server must respond with status code 204 No Content if no error occurred (including if the user already was in the group). If the user or the group do not exist, the response code must be 404 Not Found.
Set users of a group
To set the users of a group, the client performs a PUT request to /groups/<group>/users/. The request body must be a dictionary containing the user names to add:
key | value | type |
---|---|---|
users |
The name of the user to add. | List |
The server must respond with status code 204 No Content if no error occurred. This request replaces the previous set of users, group memberships that are not listed in the given request have to be removed. If the group does not exist or any of the given users do not exist, the response code must be 404 Not Found.
Verify that a user is in a group
To verify that a user is in a certain group, the client does a GET request to /groups/<group>/users/<user>/.
The server must respond with status code 204 No Content if the user is in the group and 404 Not Found if not. Note that the Resource-Type header must say 'user' even if the user exists and is just not in the respective group.
Remove a user from a group
To remove a user from a group, the client does a DELETE request to /groups/<group>/users/<user>/.
The server must respond with status code 204 No Content if the user was removed. If either user or group does not exist or the user is not a member of the group, it must respond with status code 404 Not Found.
Get a list of sub-groups
To get a list of sub-groups of a group, the client does a GET request to /groups/<meta-group>/groups/.
The server must respond with a list of sub-groups. The response code must be 200 OK if the group exists or 404 Not Found if the group does not exist. If the service does not support Meta-groups, it should return 501 Not Implemented.
Add a group to a group
To make a group meta-group of a group, the client does a POST request to /groups/<meta-group>/groups/. The request body must be a dictionary containing the name of the sub-group:
key | value | type |
---|---|---|
group |
The name of the sub-group to add. | String |
The server must respond with status code 204 No Content if the sub-group was successfully added. If either group does not exists, the server must respond with 404 Not Found. If the service does not support Meta-groups, it should return 501 Not Implemented.
Set sub-groups of a group
To set the subgroups of a group, the client performs a PUT request to /groups/<meta-group>/groups/. The request body must be a dictionary containing the group names to add:
key | value | type |
---|---|---|
groups |
The names of the groups to add. | List |
This request replaces the previous subgroups, so a subsequent call to get a list of subgroups must return the same list as given in this request. Note that groups in a different service must not be affected by this call, if group inheritance spans groups for different services (see Group visibility).
The server must respond with status code 204 No Content if no error occurred. If the meta-group does not exist or any of the sub-groups do not exist, the response code must be 404 Not Found. If the service does not support Meta-groups, it should return 501 Not Implemented.
Verify that a group is in a group
To verify that a group is in a certain group, the client does a GET request to /groups/<meta-group>/groups/<sub-group>/.
The server must respond with status code 204 No Content if the group is in the group and 404 Not Found if not. Note that the Resource-Type header must say 'group' even if the group exists and is just not in the respective group. If the service does not support Meta-groups, it should return 501 Not Implemented.
Remove a group from a group
To remove a sub-group of a group, the client does a DELETE request to /groups/<meta-group>/groups/<sub-group>/. This request is not intended to delete the sub-group entirely, it only removes the relation between sub- and meta-group.
The server must respond with status code 204 No Content if the sub-group was successfully removed. If either group does not exists or if the sub-group is not actually a sub-group, the server must respond with 404 Not Found. If the service does not support Meta-groups, it should return 501 Not Implemented.
Doing dry-runs
Some systems want to test if a specific operation would work at the given instant. Due to the statelessness of RestAuth and HTTP in general, a client can never guarantee i.e. that creating a user actually works after doing a dry-run of that operation as the user could have been created by a different client in the meantime.
In general, a dry-run is specified by prefixing the URL path with "/test/" and doing the same request. The request may return any status code that the corresponding non-dry-run request may return. A RestAuth implementation may support dry-runs for any operation that does a POST, PUT or DELETE request (except for verifying a password). The protocol mandates the support for dry-runs of the following operations:
Mapping abstract data types to concrete data types
RestAuth itself does not define any mappings. Mappings for various serialization formats are defined in various REPs[n 29].
Related standards
Related protocols are Atom[i 6], a de facto reference implementation of the REST paradigm and of course various protocols and systems that compete in the field such as LDAP[i 7] or OpenID[i 8].
References
Normative references
- ↑ 1.0 1.1 1.2 Fielding, R., Gettys, J., Mogul, J., Frysyk, H., Masinter, L., Leach, P. and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
- ↑ 2.0 2.1 Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., Sink, E. and L. Stewart, "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, June 1999.
- ↑ Crockford, D., "The application/json Media Type for JavaScript Object Notation (JSON)", RFC 4627, July 2006.
- ↑ Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 3629, November 2003.
- ↑ Tim Bray, et al., "Extensible Markup Language (XML) 1.0 (Fifth Edition)", www.w3.org/TR/REC-xml, November 2008.
- ↑ P. Hoffman, M. Blanchet, Preparation of Internationalized Strings ("stringprep"), RFC 3454, December 2002.
- ↑ 7.0 7.1 Franks, et al., "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, Section 2, Basic Access Authentication Scheme
- ↑ 8.0 8.1 Franks, et al., "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, Section 3, Digest Access Authentication Scheme
- ↑ Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC 3629, November 2003
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 14.1, Accept
- ↑ 11.0 11.1 11.2 11.3 Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 9.5, POST
- ↑ 12.0 12.1 12.2 12.3 Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 9.6, PUT
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 14.11, Content-Type
- ↑ Fielding, R., Reschke, J., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, Section 5.5.2, Referer
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.2.1, 200 OK
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.2.2, 201 Created
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.2.5, 204 No Content
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.1, 400 Bad Request
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.2, 401 Authorization Required
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.5, 403 Forbidden
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.5, 404 Not Found
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.7, 406 Not Acceptable
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.10, 409 Conflict
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.12, 411 Length Required
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.13, 412 Precondition Failed
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.4.16, 415 Unsupported Media Type
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.5.1, 500 Internal Server Error
- ↑ Fielding, et al., "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, Section 10.5.2, 501 Not Implemented
- ↑ https://restauth.net/REPs