Skip to content
Open
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
7 changes: 7 additions & 0 deletions gotify-server.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@
# Type: boolean
# GOTIFY_LOCALAUTH_ENABLED=true

# Name of the OIDC identity provider displayed in the login and elevation UI.
# Only used if GOTIFY_OIDC_ENABLED is true. Defaults to OIDC.
#
# Type: text
# Example: Company XYZ SSO
# 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
3 changes: 2 additions & 1 deletion 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 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