- Updated environment configuration to unify frontend for mail and drive under a single service. - Revised README to reflect changes in frontend setup and routing for the unified application. - Introduced new API documentation endpoints for better accessibility of API specifications. - Enhanced drive and mail services with improved handling of file uploads and metadata enrichment. - Implemented new API token management features, including creation, listing, and revocation of tokens. - Added tests for new functionalities in drive and mail services to ensure reliability and correctness.
167 lines
4.9 KiB
Go
167 lines
4.9 KiB
Go
package authentik
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/config"
|
|
)
|
|
|
|
const suiteGroup = "Ulti Suite"
|
|
|
|
// AppSpec describes one Authentik OAuth application to provision when enabled.
|
|
type AppSpec struct {
|
|
Key string
|
|
Slug string
|
|
ProviderName string
|
|
DisplayName string
|
|
ClientID func(*config.Config) string
|
|
ClientSecret func(*config.Config) string
|
|
LaunchURL func(*config.Config) string
|
|
RedirectURIs func(*config.Config) []string
|
|
Enabled func(*config.Config) bool
|
|
OfflineAccess bool
|
|
}
|
|
|
|
func baseURL(cfg *config.Config) string {
|
|
host := strings.TrimSpace(cfg.Domain)
|
|
if host == "" {
|
|
host = "localhost"
|
|
}
|
|
scheme := "http"
|
|
if cfg.AuthentikPublicHTTPS {
|
|
scheme = "https"
|
|
}
|
|
return fmt.Sprintf("%s://%s", scheme, host)
|
|
}
|
|
|
|
func Catalog(cfg *config.Config) []AppSpec {
|
|
return []AppSpec{
|
|
{
|
|
Key: "ultimail",
|
|
Slug: "ulti",
|
|
ProviderName: "ulti-backend-provider",
|
|
DisplayName: "Ultimail",
|
|
ClientID: func(c *config.Config) string { return c.OIDCClientID },
|
|
ClientSecret: func(c *config.Config) string { return c.OIDCClientSecret },
|
|
LaunchURL: func(c *config.Config) string { return c.MailAppURL + "/" },
|
|
RedirectURIs: ultimailRedirectURIs,
|
|
Enabled: func(c *config.Config) bool { return c.OIDCClientID != "" && c.OIDCClientSecret != "" },
|
|
OfflineAccess: true,
|
|
},
|
|
{
|
|
Key: "nextcloud",
|
|
Slug: "nextcloud",
|
|
ProviderName: "ulti-nextcloud-provider",
|
|
DisplayName: "Nextcloud",
|
|
ClientID: func(c *config.Config) string { return c.NCOIDCClientID },
|
|
ClientSecret: func(c *config.Config) string { return c.NCOIDCClientSecret },
|
|
LaunchURL: func(c *config.Config) string { return baseURL(c) + "/cloud/" },
|
|
RedirectURIs: nextcloudRedirectURIs,
|
|
Enabled: func(c *config.Config) bool { return c.NextcloudEnabled },
|
|
},
|
|
{
|
|
Key: "onlyoffice",
|
|
Slug: "onlyoffice",
|
|
ProviderName: "ulti-onlyoffice-provider",
|
|
DisplayName: "OnlyOffice",
|
|
ClientID: func(c *config.Config) string { return c.OnlyOfficeOIDCClientID },
|
|
ClientSecret: func(c *config.Config) string { return c.OnlyOfficeOIDCClientSecret },
|
|
LaunchURL: func(c *config.Config) string { return c.OnlyOfficePublicURL },
|
|
RedirectURIs: onlyofficeRedirectURIs,
|
|
Enabled: func(c *config.Config) bool { return c.OnlyOfficeEnabled },
|
|
},
|
|
{
|
|
Key: "immich",
|
|
Slug: "immich",
|
|
ProviderName: "ulti-immich-provider",
|
|
DisplayName: "Ultiphotos",
|
|
ClientID: func(c *config.Config) string { return c.ImmichOIDCClientID },
|
|
ClientSecret: func(c *config.Config) string { return c.ImmichOIDCClientSecret },
|
|
LaunchURL: func(c *config.Config) string { return baseURL(c) + "/photos/" },
|
|
RedirectURIs: immichRedirectURIs,
|
|
Enabled: func(c *config.Config) bool { return c.ImmichEnabled },
|
|
},
|
|
{
|
|
Key: "ultidrive",
|
|
Slug: "ultidrive",
|
|
ProviderName: "ulti-drive-provider",
|
|
DisplayName: "UltiDrive",
|
|
ClientID: func(c *config.Config) string { return c.DriveOIDCClientID },
|
|
ClientSecret: func(c *config.Config) string { return c.DriveOIDCClientSecret },
|
|
LaunchURL: func(c *config.Config) string { return baseURL(c) + "/drive/" },
|
|
RedirectURIs: driveRedirectURIs,
|
|
Enabled: func(c *config.Config) bool {
|
|
return c.NextcloudEnabled && c.DriveOIDCClientID != ""
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func ultimailRedirectURIs(cfg *config.Config) []string {
|
|
base := baseURL(cfg)
|
|
mail := strings.TrimRight(cfg.MailAppURL, "/")
|
|
return uniqueURIs(
|
|
mail+"/api/auth/callback",
|
|
"http://localhost:3000/api/auth/callback",
|
|
"http://127.0.0.1:3000/api/auth/callback",
|
|
base+"/api/auth/callback",
|
|
)
|
|
}
|
|
|
|
func nextcloudRedirectURIs(cfg *config.Config) []string {
|
|
base := baseURL(cfg)
|
|
return uniqueURIs(
|
|
base+"/cloud/apps/user_oidc/code",
|
|
"http://localhost/cloud/apps/user_oidc/code",
|
|
"http://127.0.0.1/cloud/apps/user_oidc/code",
|
|
)
|
|
}
|
|
|
|
func onlyofficeRedirectURIs(cfg *config.Config) []string {
|
|
base := baseURL(cfg)
|
|
office := strings.TrimRight(cfg.OnlyOfficePublicURL, "/")
|
|
return uniqueURIs(
|
|
office+"/",
|
|
office+"/oauth2/callback",
|
|
base+"/office/",
|
|
base+"/office/oauth2/callback",
|
|
"http://localhost/office/",
|
|
)
|
|
}
|
|
|
|
func immichRedirectURIs(cfg *config.Config) []string {
|
|
base := baseURL(cfg)
|
|
return uniqueURIs(
|
|
base+"/photos/auth/login",
|
|
base+"/photos/user-settings",
|
|
"http://localhost/photos/auth/login",
|
|
)
|
|
}
|
|
|
|
func driveRedirectURIs(cfg *config.Config) []string {
|
|
base := baseURL(cfg)
|
|
return uniqueURIs(
|
|
base+"/api/auth/callback",
|
|
"http://localhost:3000/api/auth/callback",
|
|
"http://127.0.0.1:3000/api/auth/callback",
|
|
)
|
|
}
|
|
|
|
func uniqueURIs(uris ...string) []string {
|
|
seen := map[string]struct{}{}
|
|
var out []string
|
|
for _, u := range uris {
|
|
u = strings.TrimSpace(u)
|
|
if u == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[u]; ok {
|
|
continue
|
|
}
|
|
seen[u] = struct{}{}
|
|
out = append(out, u)
|
|
}
|
|
return out
|
|
}
|