diff --git a/docs/specification.rst b/docs/specification.rst index 3686ea8366..e2626078a1 100644 --- a/docs/specification.rst +++ b/docs/specification.rst @@ -260,7 +260,7 @@ For the default HTTP transport, all API calls use a Content-Type of ``application/json``. In addition, all strings MUST be encoded as UTF-8. Clients are authenticated using opaque ``access_token`` strings (see -`Registration and Login`_ for details), passed as a querystring parameter on +`Registration and Login`_ for details), passed as a query string parameter on all requests. .. TODO @@ -375,6 +375,321 @@ When the client first logs in, they will need to initially synchronise with their home server. This is achieved via the |initialSync|_ API. This API also returns an ``end`` token which can be used with the event stream. + +Registration and login +====================== + +Clients must register with a home server in order to use Matrix. After +registering, the client will be given an access token which must be used in ALL +requests to that home server as a query parameter 'access_token'. + +If the client has already registered, they need to be able to login to their +account. The home server may provide many different ways of logging in, such as +user/password auth, login via a social network (OAuth2), login by confirming a +token sent to their email address, etc. This specification does not define how +home servers should authorise their users who want to login to their existing +accounts, but instead defines the standard interface which implementations +should follow so that ANY client can login to ANY home server. Clients login +using the |login|_ API. Clients register using the |register|_ API. +Registration follows the same procedure as login, but the path requests are +sent to are different. + +The registration/login process breaks down into the following: + 1. Determine the requirements for logging in. + 2. Submit the login stage credentials. + 3. Get credentials or be told the next stage in the login process and repeat + step 2. + +As each home server may have different ways of logging in, the client needs to +know how they should login. All distinct login stages MUST have a corresponding +``type``. A ``type`` is a namespaced string which details the mechanism for +logging in. + +A client may be able to login via multiple valid login flows, and should choose +a single flow when logging in. A flow is a series of login stages. The home +server MUST respond with all the valid login flows when requested:: + + The client can login via 3 paths: 1a and 1b, 2a and 2b, or 3. The client should + select one of these paths. + + { + "flows": [ + { + "type": "", + "stages": [ "", "" ] + }, + { + "type": "", + "stages": [ "", "" ] + }, + { + "type": "" + } + ] + } + +After the login is completed, the client's fully-qualified user ID and a new +access token MUST be returned:: + + { + "user_id": "@user:matrix.org", + "access_token": "abcdef0123456789" + } + +The ``user_id`` key is particularly useful if the home server wishes to support +localpart entry of usernames (e.g. "user" rather than "@user:matrix.org"), as +the client may not be able to determine its ``user_id`` in this case. + +If a login has multiple requests, the home server may wish to create a session. +If a home server responds with a 'session' key to a request, clients MUST +submit it in subsequent requests until the login is completed:: + + { + "session": "" + } + +This specification defines the following login types: + - ``m.login.password`` + - ``m.login.oauth2`` + - ``m.login.email.code`` + - ``m.login.email.url`` + - ``m.login.email.identity`` + +Password-based +-------------- +:Type: + ``m.login.password`` +:Description: + Login is supported via a username and password. + +To respond to this type, reply with:: + + { + "type": "m.login.password", + "user": "", + "password": "" + } + +The home server MUST respond with either new credentials, the next stage of the +login process, or a standard error response. + +OAuth2-based +------------ +:Type: + ``m.login.oauth2`` +:Description: + Login is supported via OAuth2 URLs. This login consists of multiple requests. + +To respond to this type, reply with:: + + { + "type": "m.login.oauth2", + "user": "" + } + +The server MUST respond with:: + + { + "uri": + } + +The home server acts as a 'confidential' client for the purposes of OAuth2. If +the uri is a ``sevice selection URI``, it MUST point to a webpage which prompts +the user to choose which service to authorize with. On selection of a service, +this MUST link through to an ``Authorization Request URI``. If there is only 1 +service which the home server accepts when logging in, this indirection can be +skipped and the "uri" key can be the ``Authorization Request URI``. + +The client then visits the ``Authorization Request URI``, which then shows the +OAuth2 Allow/Deny prompt. Hitting 'Allow' returns the ``redirect URI`` with the +auth code. Home servers can choose any path for the ``redirect URI``. The +client should visit the ``redirect URI``, which will then finish the OAuth2 +login process, granting the home server an access token for the chosen service. +When the home server gets this access token, it verifies that the cilent has +authorised with the 3rd party, and can now complete the login. The OAuth2 +``redirect URI`` (with auth code) MUST respond with either new credentials, the +next stage of the login process, or a standard error response. + +For example, if a home server accepts OAuth2 from Google, it would return the +Authorization Request URI for Google:: + + { + "uri": "https://accounts.google.com/o/oauth2/auth?response_type=code& + client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos" + } + +The client then visits this URI and authorizes the home server. The client then +visits the REDIRECT_URI with the auth code= query parameter which returns:: + + { + "user_id": "@user:matrix.org", + "access_token": "0123456789abcdef" + } + +Email-based (code) +------------------ +:Type: + ``m.login.email.code`` +:Description: + Login is supported by typing in a code which is sent in an email. This login + consists of multiple requests. + +To respond to this type, reply with:: + + { + "type": "m.login.email.code", + "user": "", + "email": "" + } + +After validating the email address, the home server MUST send an email +containing an authentication code and return:: + + { + "type": "m.login.email.code", + "session": "" + } + +The second request in this login stage involves sending this authentication +code:: + + { + "type": "m.login.email.code", + "session": "", + "code": "" + } + +The home server MUST respond to this with either new credentials, the next +stage of the login process, or a standard error response. + +Email-based (url) +----------------- +:Type: + ``m.login.email.url`` +:Description: + Login is supported by clicking on a URL in an email. This login consists of + multiple requests. + +To respond to this type, reply with:: + + { + "type": "m.login.email.url", + "user": "", + "email": "" + } + +After validating the email address, the home server MUST send an email +containing an authentication URL and return:: + + { + "type": "m.login.email.url", + "session": "" + } + +The email contains a URL which must be clicked. After it has been clicked, the +client should perform another request:: + + { + "type": "m.login.email.url", + "session": "" + } + +The home server MUST respond to this with either new credentials, the next +stage of the login process, or a standard error response. + +A common client implementation will be to periodically poll until the link is +clicked. If the link has not been visited yet, a standard error response with +an errcode of ``M_LOGIN_EMAIL_URL_NOT_YET`` should be returned. + + +Email-based (identity server) +----------------------------- +:Type: + ``m.login.email.identity`` +:Description: + Login is supported by authorising an email address with an identity server. + +Prior to submitting this, the client should authenticate with an identity +server. After authenticating, the session information should be submitted to +the home server. + +To respond to this type, reply with:: + + { + "type": "m.login.email.identity", + "threepidCreds": [ + { + "sid": "", + "clientSecret": "", + "idServer": "" + } + ] + } + + + +N-Factor Authentication +----------------------- +Multiple login stages can be combined to create N-factor authentication during +login. + +This can be achieved by responding with the ``next`` login type on completion +of a previous login stage:: + + { + "next": "" + } + +If a home server implements N-factor authentication, it MUST respond with all +``stages`` when initially queried for their login requirements:: + + { + "type": "<1st login type>", + "stages": [ <1st login type>, <2nd login type>, ... , ] + } + +This can be represented conceptually as:: + + _______________________ + | Login Stage 1 | + | type: "" | + | ___________________ | + | |_Request_1_________| | <-- Returns "session" key which is used throughout. + | ___________________ | + | |_Request_2_________| | <-- Returns a "next" value of "login type2" + |_______________________| + | + | + _________V_____________ + | Login Stage 2 | + | type: "" | + | ___________________ | + | |_Request_1_________| | + | ___________________ | + | |_Request_2_________| | + | ___________________ | + | |_Request_3_________| | <-- Returns a "next" value of "login type3" + |_______________________| + | + | + _________V_____________ + | Login Stage 3 | + | type: "" | + | ___________________ | + | |_Request_1_________| | <-- Returns user credentials + |_______________________| + +Fallback +-------- +Clients cannot be expected to be able to know how to process every single login +type. If a client determines it does not know how to handle a given login type, +it should request a login fallback page:: + + GET matrix/client/api/v1/login/fallback + +This MUST return an HTML page which can perform the entire login process. + + Rooms ===== @@ -1347,320 +1662,6 @@ numbers, website URLs, etc...). This specification puts no requirements on the display name other than it being a valid unicode string. - -Registration and login -====================== - -Clients must register with a home server in order to use Matrix. After -registering, the client will be given an access token which must be used in ALL -requests to that home server as a query parameter 'access_token'. - -If the client has already registered, they need to be able to login to their -account. The home server may provide many different ways of logging in, such as -user/password auth, login via a social network (OAuth2), login by confirming a -token sent to their email address, etc. This specification does not define how -home servers should authorise their users who want to login to their existing -accounts, but instead defines the standard interface which implementations -should follow so that ANY client can login to ANY home server. Clients login -using the |login|_ API. Clients register using the |register|_ API. -Registration follows the same procedure as login, but the path requests are -sent to are different. - -The registration/login process breaks down into the following: - 1. Determine the requirements for logging in. - 2. Submit the login stage credentials. - 3. Get credentials or be told the next stage in the login process and repeat - step 2. - -As each home server may have different ways of logging in, the client needs to -know how they should login. All distinct login stages MUST have a corresponding -``type``. A ``type`` is a namespaced string which details the mechanism for -logging in. - -A client may be able to login via multiple valid login flows, and should choose -a single flow when logging in. A flow is a series of login stages. The home -server MUST respond with all the valid login flows when requested:: - - The client can login via 3 paths: 1a and 1b, 2a and 2b, or 3. The client should - select one of these paths. - - { - "flows": [ - { - "type": "", - "stages": [ "", "" ] - }, - { - "type": "", - "stages": [ "", "" ] - }, - { - "type": "" - } - ] - } - -After the login is completed, the client's fully-qualified user ID and a new -access token MUST be returned:: - - { - "user_id": "@user:matrix.org", - "access_token": "abcdef0123456789" - } - -The ``user_id`` key is particularly useful if the home server wishes to support -localpart entry of usernames (e.g. "user" rather than "@user:matrix.org"), as -the client may not be able to determine its ``user_id`` in this case. - -If a login has multiple requests, the home server may wish to create a session. -If a home server responds with a 'session' key to a request, clients MUST -submit it in subsequent requests until the login is completed:: - - { - "session": "" - } - -This specification defines the following login types: - - ``m.login.password`` - - ``m.login.oauth2`` - - ``m.login.email.code`` - - ``m.login.email.url`` - - ``m.login.email.identity`` - -Password-based --------------- -:Type: - ``m.login.password`` -:Description: - Login is supported via a username and password. - -To respond to this type, reply with:: - - { - "type": "m.login.password", - "user": "", - "password": "" - } - -The home server MUST respond with either new credentials, the next stage of the -login process, or a standard error response. - -OAuth2-based ------------- -:Type: - ``m.login.oauth2`` -:Description: - Login is supported via OAuth2 URLs. This login consists of multiple requests. - -To respond to this type, reply with:: - - { - "type": "m.login.oauth2", - "user": "" - } - -The server MUST respond with:: - - { - "uri": - } - -The home server acts as a 'confidential' client for the purposes of OAuth2. If -the uri is a ``sevice selection URI``, it MUST point to a webpage which prompts -the user to choose which service to authorize with. On selection of a service, -this MUST link through to an ``Authorization Request URI``. If there is only 1 -service which the home server accepts when logging in, this indirection can be -skipped and the "uri" key can be the ``Authorization Request URI``. - -The client then visits the ``Authorization Request URI``, which then shows the -OAuth2 Allow/Deny prompt. Hitting 'Allow' returns the ``redirect URI`` with the -auth code. Home servers can choose any path for the ``redirect URI``. The -client should visit the ``redirect URI``, which will then finish the OAuth2 -login process, granting the home server an access token for the chosen service. -When the home server gets this access token, it verifies that the cilent has -authorised with the 3rd party, and can now complete the login. The OAuth2 -``redirect URI`` (with auth code) MUST respond with either new credentials, the -next stage of the login process, or a standard error response. - -For example, if a home server accepts OAuth2 from Google, it would return the -Authorization Request URI for Google:: - - { - "uri": "https://accounts.google.com/o/oauth2/auth?response_type=code& - client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos" - } - -The client then visits this URI and authorizes the home server. The client then -visits the REDIRECT_URI with the auth code= query parameter which returns:: - - { - "user_id": "@user:matrix.org", - "access_token": "0123456789abcdef" - } - -Email-based (code) ------------------- -:Type: - ``m.login.email.code`` -:Description: - Login is supported by typing in a code which is sent in an email. This login - consists of multiple requests. - -To respond to this type, reply with:: - - { - "type": "m.login.email.code", - "user": "", - "email": "" - } - -After validating the email address, the home server MUST send an email -containing an authentication code and return:: - - { - "type": "m.login.email.code", - "session": "" - } - -The second request in this login stage involves sending this authentication -code:: - - { - "type": "m.login.email.code", - "session": "", - "code": "" - } - -The home server MUST respond to this with either new credentials, the next -stage of the login process, or a standard error response. - -Email-based (url) ------------------ -:Type: - ``m.login.email.url`` -:Description: - Login is supported by clicking on a URL in an email. This login consists of - multiple requests. - -To respond to this type, reply with:: - - { - "type": "m.login.email.url", - "user": "", - "email": "" - } - -After validating the email address, the home server MUST send an email -containing an authentication URL and return:: - - { - "type": "m.login.email.url", - "session": "" - } - -The email contains a URL which must be clicked. After it has been clicked, the -client should perform another request:: - - { - "type": "m.login.email.url", - "session": "" - } - -The home server MUST respond to this with either new credentials, the next -stage of the login process, or a standard error response. - -A common client implementation will be to periodically poll until the link is -clicked. If the link has not been visited yet, a standard error response with -an errcode of ``M_LOGIN_EMAIL_URL_NOT_YET`` should be returned. - - -Email-based (identity server) ------------------------------ -:Type: - ``m.login.email.identity`` -:Description: - Login is supported by authorising an email address with an identity server. - -Prior to submitting this, the client should authenticate with an identity -server. After authenticating, the session information should be submitted to -the home server. - -To respond to this type, reply with:: - - { - "type": "m.login.email.identity", - "threepidCreds": [ - { - "sid": "", - "clientSecret": "", - "idServer": "" - } - ] - } - - - -N-Factor Authentication ------------------------ -Multiple login stages can be combined to create N-factor authentication during -login. - -This can be achieved by responding with the ``next`` login type on completion -of a previous login stage:: - - { - "next": "" - } - -If a home server implements N-factor authentication, it MUST respond with all -``stages`` when initially queried for their login requirements:: - - { - "type": "<1st login type>", - "stages": [ <1st login type>, <2nd login type>, ... , ] - } - -This can be represented conceptually as:: - - _______________________ - | Login Stage 1 | - | type: "" | - | ___________________ | - | |_Request_1_________| | <-- Returns "session" key which is used throughout. - | ___________________ | - | |_Request_2_________| | <-- Returns a "next" value of "login type2" - |_______________________| - | - | - _________V_____________ - | Login Stage 2 | - | type: "" | - | ___________________ | - | |_Request_1_________| | - | ___________________ | - | |_Request_2_________| | - | ___________________ | - | |_Request_3_________| | <-- Returns a "next" value of "login type3" - |_______________________| - | - | - _________V_____________ - | Login Stage 3 | - | type: "" | - | ___________________ | - | |_Request_1_________| | <-- Returns user credentials - |_______________________| - -Fallback --------- -Clients cannot be expected to be able to know how to process every single login -type. If a client determines it does not know how to handle a given login type, -it should request a login fallback page:: - - GET matrix/client/api/v1/login/fallback - -This MUST return an HTML page which can perform the entire login process. - Identity ======== .. NOTE::