aboutsummaryrefslogtreecommitdiff
path: root/clientapi
diff options
context:
space:
mode:
authorBruce MacDonald <brucewmacdonald@gmail.com>2021-04-07 05:26:20 -0700
committerGitHub <noreply@github.com>2021-04-07 13:26:20 +0100
commitd27607af78a53bda636f14f603b02b2952d6e1d8 (patch)
treec5c5488c7395a45af24ef598308ef7f6545515ca /clientapi
parentf8d3a762c49a1dafe4e484a2440ade2bb6ba32ac (diff)
Implement OpenID module (#599) (#1812)
* Implement OpenID module (#599) - Unrelated: change Riot references to Element in client API routing Signed-off-by: Bruce MacDonald <contact@bruce-macdonald.com> * OpenID module tweaks (#599) - specify expiry is ms rather than vague ts - add OpenID token lifetime to configuration - use Go naming conventions for the path params - store plaintext token rather than hash - remove openid table sqllite mutex * Add default OpenID token lifetime (#599) * Update dendrite-config.yaml Co-authored-by: Kegsay <kegsay@gmail.com> Co-authored-by: Kegsay <kegan@matrix.org>
Diffstat (limited to 'clientapi')
-rw-r--r--clientapi/routing/openid.go70
-rw-r--r--clientapi/routing/routing.go19
2 files changed, 86 insertions, 3 deletions
diff --git a/clientapi/routing/openid.go b/clientapi/routing/openid.go
new file mode 100644
index 00000000..13656e28
--- /dev/null
+++ b/clientapi/routing/openid.go
@@ -0,0 +1,70 @@
+// Copyright 2021 The Matrix.org Foundation C.I.C.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package routing
+
+import (
+ "net/http"
+
+ "github.com/matrix-org/dendrite/clientapi/jsonerror"
+ "github.com/matrix-org/dendrite/setup/config"
+ "github.com/matrix-org/dendrite/userapi/api"
+ "github.com/matrix-org/util"
+)
+
+type openIDTokenResponse struct {
+ AccessToken string `json:"access_token"`
+ TokenType string `json:"token_type"`
+ MatrixServerName string `json:"matrix_server_name"`
+ ExpiresIn int64 `json:"expires_in"`
+}
+
+// CreateOpenIDToken creates a new OpenID Connect (OIDC) token that a Matrix user
+// can supply to an OpenID Relying Party to verify their identity
+func CreateOpenIDToken(
+ req *http.Request,
+ userAPI api.UserInternalAPI,
+ device *api.Device,
+ userID string,
+ cfg *config.ClientAPI,
+) util.JSONResponse {
+ // does the incoming user ID match the user that the token was issued for?
+ if userID != device.UserID {
+ return util.JSONResponse{
+ Code: http.StatusForbidden,
+ JSON: jsonerror.Forbidden("Cannot request tokens for other users"),
+ }
+ }
+
+ request := api.PerformOpenIDTokenCreationRequest{
+ UserID: userID, // this is the user ID from the incoming path
+ }
+ response := api.PerformOpenIDTokenCreationResponse{}
+
+ err := userAPI.PerformOpenIDTokenCreation(req.Context(), &request, &response)
+ if err != nil {
+ util.GetLogger(req.Context()).WithError(err).Error("userAPI.CreateOpenIDToken failed")
+ return jsonerror.InternalServerError()
+ }
+
+ return util.JSONResponse{
+ Code: http.StatusOK,
+ JSON: openIDTokenResponse{
+ AccessToken: response.Token.Token,
+ TokenType: "Bearer",
+ MatrixServerName: string(cfg.Matrix.ServerName),
+ ExpiresIn: response.Token.ExpiresAtMS / 1000, // convert ms to s
+ },
+ }
+}
diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go
index a56359b4..5d4f90a4 100644
--- a/clientapi/routing/routing.go
+++ b/clientapi/routing/routing.go
@@ -469,7 +469,7 @@ func Setup(
}),
).Methods(http.MethodPost, http.MethodOptions)
- // Stub endpoints required by Riot
+ // Stub endpoints required by Element
r0mux.Handle("/login",
httputil.MakeExternalAPI("login", func(req *http.Request) util.JSONResponse {
@@ -506,7 +506,7 @@ func Setup(
}),
).Methods(http.MethodGet, http.MethodOptions)
- // Riot user settings
+ // Element user settings
r0mux.Handle("/profile/{userID}",
httputil.MakeExternalAPI("profile", func(req *http.Request) util.JSONResponse {
@@ -592,7 +592,7 @@ func Setup(
}),
).Methods(http.MethodPost, http.MethodOptions)
- // Riot logs get flooded unless this is handled
+ // Element logs get flooded unless this is handled
r0mux.Handle("/presence/{userID}/status",
httputil.MakeExternalAPI("presence", func(req *http.Request) util.JSONResponse {
if r := rateLimits.rateLimit(req); r != nil {
@@ -685,6 +685,19 @@ func Setup(
}),
).Methods(http.MethodGet)
+ r0mux.Handle("/user/{userID}/openid/request_token",
+ httputil.MakeAuthAPI("openid_request_token", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
+ if r := rateLimits.rateLimit(req); r != nil {
+ return *r
+ }
+ vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
+ return CreateOpenIDToken(req, userAPI, device, vars["userID"], cfg)
+ }),
+ ).Methods(http.MethodPost, http.MethodOptions)
+
r0mux.Handle("/user_directory/search",
httputil.MakeAuthAPI("userdirectory_search", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
if r := rateLimits.rateLimit(req); r != nil {