Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type OIDC struct {
AutoRegister bool
LinkByUsername bool
Scopes []string
IDPName string
}

type Configuration struct {
Expand Down Expand Up @@ -117,6 +118,7 @@ func Get() (*Configuration, []FutureLog) {
UsernameClaim: "preferred_username",
AutoRegister: true,
Scopes: []string{"openid", "profile", "email"},
IDPName: "OIDC",
},
}

Expand Down Expand Up @@ -180,6 +182,7 @@ func Get() (*Configuration, []FutureLog) {
add(parseBool(&c.OIDC.AutoRegister, EnvOIDCAutoRegister))
add(parseBool(&c.OIDC.LinkByUsername, EnvOIDCLinkByUsername))
add(parseList(&c.OIDC.Scopes, EnvOIDCScopes))
add(parseString(&c.OIDC.IDPName, EnvOIDCIDPName))

add(parseString(&c.NoColor, EnvNoColor))

Expand Down
2 changes: 2 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func TestConfigEnv(t *testing.T) {
t.Setenv("GOTIFY_SERVER_CORS_ALLOWMETHODS", "GET,POST")
t.Setenv("GOTIFY_SERVER_CORS_ALLOWHEADERS", "Authorization,content-type")
t.Setenv("GOTIFY_SERVER_STREAM_ALLOWEDORIGINS", ".+.example.com,otherdomain.com")
t.Setenv("GOTIFY_OIDC_IDP_NAME", "Company XYZ SSO")

conf, _ := Get()
assert.Equal(t, 80, conf.Server.Port, "should use defaults")
Expand All @@ -33,6 +34,7 @@ func TestConfigEnv(t *testing.T) {
assert.Equal(t, []string{"GET", "POST"}, conf.Server.Cors.AllowMethods)
assert.Equal(t, []string{"Authorization", "content-type"}, conf.Server.Cors.AllowHeaders)
assert.Equal(t, []string{".+.example.com", "otherdomain.com"}, conf.Server.Stream.AllowedOrigins)
assert.Equal(t, "Company XYZ SSO", conf.OIDC.IDPName)
}

func TestLocalAuthDisabled(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions config/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ const (
EnvOIDCLinkByUsername = "GOTIFY_OIDC_LINK_BY_USERNAME"
EnvLocalAuthEnabled = "GOTIFY_LOCALAUTH_ENABLED"
EnvOIDCScopes = "GOTIFY_OIDC_SCOPES"
EnvOIDCIDPName = "GOTIFY_OIDC_IDP_NAME"
EnvNoColor = "NOCOLOR"
)
9 changes: 8 additions & 1 deletion docs/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -2947,7 +2947,8 @@
"version",
"register",
"localAuth",
"oidc"
"oidc",
"oidcIdpName"
],
"properties": {
"localAuth": {
Expand All @@ -2962,6 +2963,12 @@
"x-go-name": "Oidc",
"example": true
},
"oidcIdpName": {
"description": "Name of the OIDC identity provider.",
"type": "string",
"x-go-name": "OIDCIDPName",
"example": "OIDC"
},
"register": {
"description": "If registration is enabled.",
"type": "boolean",
Expand Down
5 changes: 5 additions & 0 deletions gotify-server.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@
# Type: boolean
# GOTIFY_LOCALAUTH_ENABLED=true

# Name of the OIDC identity provider displayed in UI.
# Type: text
# Example: Authelia
# GOTIFY_OIDC_IDP_NAME=OIDC

# Database driver to use. For mysql and postgres the target database must
# already exist and the configured user must have sufficient permissions.
#
Expand Down
5 changes: 5 additions & 0 deletions model/gotifyinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ type GotifyInfo struct {
// required: true
// example: true
Oidc bool `json:"oidc"`
// Name of the OIDC identity provider.
//
// required: true
// example: OIDC
OIDCIDPName string `json:"oidcIdpName"`
}
10 changes: 8 additions & 2 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func Create(db *database.GormDatabase, vInfo *model.VersionInfo, conf *config.Co
userChangeNotifier.OnUserDeleted(pluginManager.RemoveUser)
userChangeNotifier.OnUserAdded(pluginManager.InitializeForUserID)

ui.Register(g, *vInfo, conf.Registration, conf.LocalAuthEnabled, conf.OIDC.Enabled)
ui.Register(g, *vInfo, conf.Registration, conf.LocalAuthEnabled, conf.OIDC.Enabled, conf.OIDC.IDPName)

if conf.OIDC.Enabled {
oidcHandler := api.NewOIDC(conf, db, userChangeNotifier)
Expand Down Expand Up @@ -191,7 +191,13 @@ func Create(db *database.GormDatabase, vInfo *model.VersionInfo, conf *config.Co
// schema:
// $ref: "#/definitions/GotifyInfo"
g.GET("gotifyinfo", func(ctx *gin.Context) {
ctx.JSON(200, &model.GotifyInfo{Version: vInfo.Version, Oidc: conf.OIDC.Enabled, Register: conf.Registration, LocalAuth: conf.LocalAuthEnabled})
ctx.JSON(200, &model.GotifyInfo{
Version: vInfo.Version,
Oidc: conf.OIDC.Enabled,
Register: conf.Registration,
LocalAuth: conf.LocalAuthEnabled,
OIDCIDPName: conf.OIDC.IDPName,
})
})

g.Group("/").Use(authentication.RequireApplicationOrClient).POST("/message", messageHandler.CreateMessage)
Expand Down
12 changes: 11 additions & 1 deletion router/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ func (s *IntegrationSuite) BeforeTest(string, string) {
g, closable := Create(
s.db.GormDatabase,
&model.VersionInfo{Version: "1.0.0", BuildDate: "2018-02-20-17:30:47", Commit: "asdasds"},
&config.Configuration{PassStrength: 5, LocalAuthEnabled: true},
&config.Configuration{
PassStrength: 5,
LocalAuthEnabled: true,
OIDC: config.OIDC{IDPName: "Company XYZ SSO"},
},
)
s.closable = closable
s.server = httptest.NewServer(g)
Expand All @@ -60,6 +64,12 @@ func (s *IntegrationSuite) TestVersionInfo() {
doRequestAndExpect(s.T(), req, 200, `{"version":"1.0.0", "commit":"asdasds", "buildDate":"2018-02-20-17:30:47"}`)
}

func (s *IntegrationSuite) TestGotifyInfo() {
req := s.newRequest("GET", "gotifyinfo", "")

doRequestAndExpect(s.T(), req, 200, `{"version":"1.0.0", "oidc":false, "register":false, "localAuth":true, "oidcIdpName":"Company XYZ SSO"}`)
}

func (s *IntegrationSuite) TestHeaderInProd() {
mode.Set(mode.Prod)
req := s.newRequest("GET", "version", "")
Expand Down
27 changes: 18 additions & 9 deletions ui/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,28 @@ import (
var box embed.FS

type uiConfig struct {
Register bool `json:"register"`
Version model.VersionInfo `json:"version"`
LocalAuth bool `json:"localAuth"`
OIDC bool `json:"oidc"`
Register bool `json:"register"`
Version model.VersionInfo `json:"version"`
LocalAuth bool `json:"localAuth"`
OIDC bool `json:"oidc"`
OIDCIDPName string `json:"oidcIdpName"`
}

// Register registers the ui on the root path.
func Register(r *gin.Engine, version model.VersionInfo, register, localAuthEnabled, oidcEnabled bool) {
func Register(
r *gin.Engine,
version model.VersionInfo,
register bool,
localAuthEnabled bool,
oidcEnabled bool,
oidcIDPName string,
) {
uiConfigBytes, err := json.Marshal(uiConfig{
Version: version,
Register: register,
LocalAuth: localAuthEnabled,
OIDC: oidcEnabled,
Version: version,
Register: register,
LocalAuth: localAuthEnabled,
OIDC: oidcEnabled,
OIDCIDPName: oidcIDPName,
})
if err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion ui/src/ElevateStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class ElevateStore {
}

if (!this.elevated) {
this.snack('OIDC elevation was not completed.');
this.snack(`${config.get('oidcIdpName')} elevation was not completed.`);
}
this.cleanupOidcElevate();
};
Expand Down
7 changes: 4 additions & 3 deletions ui/src/common/ElevationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const ElevationForm = observer(() => {
const localAuthEnabled = config.get('localAuth');
const oidcEnabled = config.get('oidc');
const oidcPending = elevateStore.oidcElevatePending;
const oidcIdpName = config.get('oidcIdpName');

const handleLocalElevate = async () => {
try {
Expand All @@ -31,7 +32,7 @@ const ElevationForm = observer(() => {
return (
<Box sx={{textAlign: 'center', my: 2}}>
<CircularProgress sx={{mb: 2}} />
<Typography sx={{mb: 1}}>Waiting for OIDC sign-in...</Typography>
<Typography sx={{mb: 1}}>Waiting for {oidcIdpName} sign-in...</Typography>
<Typography variant="body2" color="textSecondary" sx={{mb: 1}}>
Complete sign-in in the new tab, then close it to continue.
</Typography>
Expand All @@ -40,7 +41,7 @@ const ElevationForm = observer(() => {
variant="outlined"
fullWidth
onClick={() => elevateStore.cleanupOidcElevate()}>
Cancel OIDC Login
Cancel {oidcIdpName} Login
</Button>
</Box>
);
Expand Down Expand Up @@ -91,7 +92,7 @@ const ElevationForm = observer(() => {
color="primary"
fullWidth
onClick={() => elevateStore.oidcElevate(ElevateDuration)}>
Elevate via OIDC
Elevate via {oidcIdpName}
</Button>
</>
)}
Expand Down
2 changes: 2 additions & 0 deletions ui/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface IConfig {
version: IVersion;
oidc: boolean;
localAuth: boolean;
oidcIdpName: string;
}

declare global {
Expand All @@ -20,6 +21,7 @@ const config: IConfig = {
version: {commit: 'unknown', buildDate: 'unknown', version: 'unknown'},
oidc: false,
localAuth: true,
oidcIdpName: 'OIDC',
...window.config,
};

Expand Down
4 changes: 3 additions & 1 deletion ui/src/user/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const Login = observer(() => {
const navigate = useNavigate();
const localAuthEnabled = config.get('localAuth');
const oidcEnabled = config.get('oidc');
const oidcIdpName = config.get('oidcIdpName');

React.useEffect(() => {
if (currentUser.loggedIn) {
navigate('/');
Expand Down Expand Up @@ -103,7 +105,7 @@ const Login = observer(() => {
size="large"
color="primary"
style={{marginBottom: 5}}>
Login with OIDC
Login with {oidcIdpName}
</Button>
</>
)}
Expand Down
Loading