From ce3b8aacf73b841887f3eec631851d086a7578f1 Mon Sep 17 00:00:00 2001
From: tobi <31960611+tsmethurst@users.noreply.github.com>
Date: Fri, 7 Jun 2024 16:21:57 +0200
Subject: [PATCH] [chore] Warn about email/password change when using OIDC
(#2975)
* [chore] Warn about email/password change when using OIDC
* go fmt
---
docs/api/swagger.yaml | 10 +++
docs/user_guide/settings.md | 8 ++-
internal/api/client/user/passwordchange.go | 11 ++++
internal/api/model/instancev1.go | 2 +
internal/api/model/instancev2.go | 2 +
internal/config/helpers.gen.go | 3 +-
internal/typeutils/internaltofrontend.go | 2 +
web/source/settings/lib/types/instance.ts | 1 +
web/source/settings/views/user/settings.tsx | 72 +++++++++++++++++++--
9 files changed, 101 insertions(+), 10 deletions(-)
diff --git a/docs/api/swagger.yaml b/docs/api/swagger.yaml
index 6bb5b45ea..fe28847f7 100644
--- a/docs/api/swagger.yaml
+++ b/docs/api/swagger.yaml
@@ -1541,6 +1541,10 @@ definitions:
$ref: '#/definitions/InstanceConfigurationEmojis'
media_attachments:
$ref: '#/definitions/instanceConfigurationMediaAttachments'
+ oidc_enabled:
+ description: True if instance is running with OIDC as auth/identity backend, else omitted.
+ type: boolean
+ x-go-name: OIDCEnabled
polls:
$ref: '#/definitions/instanceConfigurationPolls'
statuses:
@@ -1656,6 +1660,10 @@ definitions:
$ref: '#/definitions/InstanceConfigurationEmojis'
media_attachments:
$ref: '#/definitions/instanceConfigurationMediaAttachments'
+ oidc_enabled:
+ description: True if instance is running with OIDC as auth/identity backend, else omitted.
+ type: boolean
+ x-go-name: OIDCEnabled
polls:
$ref: '#/definitions/instanceConfigurationPolls'
statuses:
@@ -9044,6 +9052,8 @@ paths:
description: forbidden
"406":
description: not acceptable
+ "422":
+ description: unprocessable request because instance is running with OIDC backend
"500":
description: internal error
security:
diff --git a/docs/user_guide/settings.md b/docs/user_guide/settings.md
index 1d0ec177d..1b243f166 100644
--- a/docs/user_guide/settings.md
+++ b/docs/user_guide/settings.md
@@ -157,13 +157,19 @@ When you are finished updating your post settings, remember to click the `Save p
You can use the Password Change section of the panel to set a new password for your account. For security reasons, you must provide your current password to validate the change.
+!!! info
+ If your instance is using OIDC as its authorization/identity provider, you will not be able to change your password via the GoToSocial settings panel, and you should contact your OIDC provider instead.
+
For more information on the way GoToSocial manages passwords, please see the [Password management document](./password_management.md).
### Email Change
You can use the Email Change section of the panel to change the email address for your account. For security reasons, you must provide your current password to validate the change.
-Once a new email address has been entered, and you have clicked "Change email address", you must open the inbox of the new email address and confirm your address via the link provided. Once you've done that, your email address change will be confirmed, and you should use the new email address to log in.
+Once a new email address has been entered, and you have clicked "Change email address", you must open the inbox of the new email address and confirm your address via the link provided. Once you've done that, your email address change will be confirmed.
+
+!!! info
+ If your instance is using OIDC as its authorization/identity provider, you will be able to change your email address via the settings panel, but it will only affect the email address GoToSocial uses to contact you, it will not change the email address you need to use to log in to your account. To change that, you should contact your OIDC provider.
## Migration
diff --git a/internal/api/client/user/passwordchange.go b/internal/api/client/user/passwordchange.go
index c2928e9e5..df9f5b0c8 100644
--- a/internal/api/client/user/passwordchange.go
+++ b/internal/api/client/user/passwordchange.go
@@ -24,10 +24,13 @@ import (
"github.com/gin-gonic/gin"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
+const OIDCPasswordHelp = "password change request cannot be processed by GoToSocial as this instance is running with OIDC enabled; you must change password using your OIDC provider"
+
// PasswordChangePOSTHandler swagger:operation POST /api/v1/user/password_change userPasswordChange
//
// Change the password of authenticated user.
@@ -62,6 +65,8 @@ import (
// description: forbidden
// '406':
// description: not acceptable
+// '422':
+// description: unprocessable request because instance is running with OIDC backend
// '500':
// description: internal error
func (m *Module) PasswordChangePOSTHandler(c *gin.Context) {
@@ -76,6 +81,12 @@ func (m *Module) PasswordChangePOSTHandler(c *gin.Context) {
return
}
+ if config.GetOIDCEnabled() {
+ err := errors.New("instance running with OIDC")
+ apiutil.ErrorHandler(c, gtserror.NewErrorUnprocessableEntity(err, OIDCPasswordHelp), m.processor.InstanceGetV1)
+ return
+ }
+
form := &apimodel.PasswordChangeRequest{}
if err := c.ShouldBind(form); err != nil {
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
diff --git a/internal/api/model/instancev1.go b/internal/api/model/instancev1.go
index 217edc08c..beb4f430d 100644
--- a/internal/api/model/instancev1.go
+++ b/internal/api/model/instancev1.go
@@ -127,4 +127,6 @@ type InstanceV1Configuration struct {
Accounts InstanceConfigurationAccounts `json:"accounts"`
// Instance configuration pertaining to emojis.
Emojis InstanceConfigurationEmojis `json:"emojis"`
+ // True if instance is running with OIDC as auth/identity backend, else omitted.
+ OIDCEnabled bool `json:"oidc_enabled,omitempty"`
}
diff --git a/internal/api/model/instancev2.go b/internal/api/model/instancev2.go
index a1b98ea65..fce801117 100644
--- a/internal/api/model/instancev2.go
+++ b/internal/api/model/instancev2.go
@@ -163,6 +163,8 @@ type InstanceV2Configuration struct {
Translation InstanceV2ConfigurationTranslation `json:"translation"`
// Instance configuration pertaining to emojis.
Emojis InstanceConfigurationEmojis `json:"emojis"`
+ // True if instance is running with OIDC as auth/identity backend, else omitted.
+ OIDCEnabled bool `json:"oidc_enabled,omitempty"`
}
// Information about registering for this instance.
diff --git a/internal/config/helpers.gen.go b/internal/config/helpers.gen.go
index edfe96e57..71a77e753 100644
--- a/internal/config/helpers.gen.go
+++ b/internal/config/helpers.gen.go
@@ -2,7 +2,7 @@
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
-//
+//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
@@ -4074,4 +4074,3 @@ func GetRequestIDHeader() string { return global.GetRequestIDHeader() }
// SetRequestIDHeader safely sets the value for global configuration 'RequestIDHeader' field
func SetRequestIDHeader(v string) { global.SetRequestIDHeader(v) }
-
diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go
index f3c027316..80f083ef1 100644
--- a/internal/typeutils/internaltofrontend.go
+++ b/internal/typeutils/internaltofrontend.go
@@ -1328,6 +1328,7 @@ func (c *Converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
instance.Configuration.Accounts.MaxFeaturedTags = instanceAccountsMaxFeaturedTags
instance.Configuration.Accounts.MaxProfileFields = instanceAccountsMaxProfileFields
instance.Configuration.Emojis.EmojiSizeLimit = int(config.GetMediaEmojiLocalMaxSize())
+ instance.Configuration.OIDCEnabled = config.GetOIDCEnabled()
// URLs
instance.URLs.StreamingAPI = "wss://" + i.Domain
@@ -1467,6 +1468,7 @@ func (c *Converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
instance.Configuration.Accounts.MaxFeaturedTags = instanceAccountsMaxFeaturedTags
instance.Configuration.Accounts.MaxProfileFields = instanceAccountsMaxProfileFields
instance.Configuration.Emojis.EmojiSizeLimit = int(config.GetMediaEmojiLocalMaxSize())
+ instance.Configuration.OIDCEnabled = config.GetOIDCEnabled()
// registrations
instance.Registrations.Enabled = config.GetAccountsRegistrationOpen()
diff --git a/web/source/settings/lib/types/instance.ts b/web/source/settings/lib/types/instance.ts
index 4c6f5061b..11f75032c 100644
--- a/web/source/settings/lib/types/instance.ts
+++ b/web/source/settings/lib/types/instance.ts
@@ -49,6 +49,7 @@ export interface InstanceConfiguration {
polls: InstancePolls;
accounts: InstanceAccounts;
emojis: InstanceEmojis;
+ oidc_enabled?: boolean;
}
export interface InstanceAccounts {
diff --git a/web/source/settings/views/user/settings.tsx b/web/source/settings/views/user/settings.tsx
index a27cc1ba3..5696144a0 100644
--- a/web/source/settings/views/user/settings.tsx
+++ b/web/source/settings/views/user/settings.tsx
@@ -28,6 +28,7 @@ import { useVerifyCredentialsQuery } from "../../lib/query/oauth";
import { useEmailChangeMutation, usePasswordChangeMutation, useUpdateCredentialsMutation, useUserQuery } from "../../lib/query/user";
import Loading from "../../components/loading";
import { User } from "../../lib/types/user";
+import { useInstanceV1Query } from "../../lib/query/gts-api";
export default function UserSettings() {
return (
@@ -106,6 +107,24 @@ function UserSettingsForm({ data }) {
}
function PasswordChange() {
+ // Load instance data.
+ const {
+ data: instance,
+ isFetching: isFetchingInstance,
+ isLoading: isLoadingInstance
+ } = useInstanceV1Query();
+ if (isFetchingInstance || isLoadingInstance) {
+ return