Skip to content

Instantly share code, notes, and snippets.

@rotty3000
Created April 8, 2025 15:59
Show Gist options
  • Save rotty3000/fc17f312f64dbad0afe1ff8d2ae434e8 to your computer and use it in GitHub Desktop.
Save rotty3000/fc17f312f64dbad0afe1ff8d2ae434e8 to your computer and use it in GitHub Desktop.
Client Extension ENV contract in Go
LIFERAY_ROUTES_DXP Configuration:
Domains: [localhost]
Main Domain: localhost
Server Protocol: http
LIFERAY_ROUTES_CLIENT_EXTENSION Configuration for 'liferay-sample-etc-spring-boot-oauth-application-user-agent':
Headless Server Audience:
Headless Server Client ID:
Headless Server Client Secret:
Headless Server Scopes:
Authorization URI: /o/oauth2/authorize
Introspection URI: /o/oauth2/introspect
JWKS URI: /o/oauth2/jwks
Token URI: /o/oauth2/token
Redirect URIs: [/o/oauth2/redirect]
User Agent Audience: http://localhost:58081
User Agent Client ID: id-3230c153-65cc-803c-b37d-3012ee4fa5a
User Agent Scopes: Liferay.Headless.Admin.User.everything
Liferay.Headless.Admin.Workflow.everything
// How to use.
//
// Deploy the liferay-sample-etc-spring-boot sample to a locally running Liferay.
// Then execute the following (changing paths as necessary)
//
// LIFERAY_ROUTES_DXP=${LIFERAY_HOME}/routes/default/dxp \
// LIFERAY_ROUTES_CLIENT_EXTENSION=${LIFERAY_HOME}/routes/default/liferay-sample-etc-spring-boot \
// OAUTH_ERC=liferay-sample-etc-spring-boot-oauth-application-user-agent \
// go run main.go
//
package main
import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"
)
// DXPConfig holds the configuration from the LIFERAY_ROUTES_DXP directory.
type DXPConfig struct {
Domains []string
MainDomain string
ServerProtocol string
}
// ClientExtensionOAuth2Config holds the OAuth 2.0 configuration from the LIFERAY_ROUTES_CLIENT_EXTENSION directory.
type ClientExtensionOAuth2Config struct {
HeadlessServerAudience string
HeadlessServerClientID string
HeadlessServerClientSecret string
HeadlessServerScopes string
AuthorizationURI string
IntrospectionURI string
JWKSURI string
TokenURI string
RedirectURIs []string
UserAgentAudience string
UserAgentClientID string
UserAgentScopes string
}
// getDXPConfig reads the configuration files from the LIFERAY_ROUTES_DXP directory.
func getDXPConfig() (*DXPConfig, error) {
configDir := os.Getenv("LIFERAY_ROUTES_DXP")
if configDir == "" {
return nil, fmt.Errorf("LIFERAY_ROUTES_DXP environment variable not found")
}
config := &DXPConfig{
Domains: make([]string, 0),
}
// Read com.liferay.lxc.dxp.domains
domainsFilePath := filepath.Join(configDir, "com.liferay.lxc.dxp.domains")
domainsFile, err := os.Open(domainsFilePath)
if err == nil {
defer domainsFile.Close()
scanner := bufio.NewScanner(domainsFile)
for scanner.Scan() {
domain := strings.TrimSpace(scanner.Text())
if domain != "" {
config.Domains = append(config.Domains, domain)
}
}
if err := scanner.Err(); err != nil {
fmt.Printf("Error reading %s: %v\n", domainsFilePath, err)
}
} else if !os.IsNotExist(err) {
fmt.Printf("Error opening %s: %v\n", domainsFilePath, err)
}
// Read com.liferay.lxc.dxp.main.domain
mainDomainFilePath := filepath.Join(configDir, "com.liferay.lxc.dxp.main.domain")
mainDomainBytes, err := os.ReadFile(mainDomainFilePath)
if err == nil {
config.MainDomain = strings.TrimSpace(string(mainDomainBytes))
} else if !os.IsNotExist(err) {
fmt.Printf("Error reading %s: %v\n", mainDomainFilePath, err)
}
// Read com.liferay.lxc.dxp.server.protocol
protocolFilePath := filepath.Join(configDir, "com.liferay.lxc.dxp.server.protocol")
protocolBytes, err := os.ReadFile(protocolFilePath)
if err == nil {
config.ServerProtocol = strings.TrimSpace(string(protocolBytes))
} else if !os.IsNotExist(err) {
fmt.Printf("Error reading %s: %v\n", protocolFilePath, err)
}
return config, nil
}
// loadClientExtensionOAuth2Config reads the OAuth 2.0 configuration files from the LIFERAY_ROUTES_CLIENT_EXTENSION directory.
func loadClientExtensionOAuth2Config(referenceCode string) (*ClientExtensionOAuth2Config, error) {
configDir := os.Getenv("LIFERAY_ROUTES_CLIENT_EXTENSION")
if configDir == "" {
return nil, fmt.Errorf("LIFERAY_ROUTES_CLIENT_EXTENSION environment variable not found")
}
config := &ClientExtensionOAuth2Config{
RedirectURIs: make([]string, 0),
}
readFileContent := func(filename string) string {
filePath := filepath.Join(configDir, fmt.Sprintf("%s.%s", referenceCode, filename))
contentBytes, err := os.ReadFile(filePath)
if err == nil {
return strings.TrimSpace(string(contentBytes))
} else if !os.IsNotExist(err) {
fmt.Printf("Error reading %s: %v\n", filePath, err)
}
return ""
}
// Headless Server Application
config.HeadlessServerAudience = readFileContent("oauth2.headless.server.audience")
config.HeadlessServerClientID = readFileContent("oauth2.headless.server.client.id")
config.HeadlessServerClientSecret = readFileContent("oauth2.headless.server.client.secret")
config.HeadlessServerScopes = readFileContent("oauth2.headless.server.scopes")
// OAuth 2.0 Endpoints (common to both types)
config.AuthorizationURI = readFileContent("oauth2.authorization.uri")
config.IntrospectionURI = readFileContent("oauth2.introspection.uri")
config.JWKSURI = readFileContent("oauth2.jwks.uri")
config.TokenURI = readFileContent("oauth2.token.uri")
// Redirect URIs (User Agent)
redirectURIsContent := readFileContent("oauth2.redirect.uris")
if redirectURIsContent != "" {
for _, uri := range strings.Split(redirectURIsContent, "\n") {
trimmedURI := strings.TrimSpace(uri)
if trimmedURI != "" {
config.RedirectURIs = append(config.RedirectURIs, trimmedURI)
}
}
}
// User Agent Application
config.UserAgentAudience = readFileContent("oauth2.user.agent.audience")
config.UserAgentClientID = readFileContent("oauth2.user.agent.client.id")
config.UserAgentScopes = readFileContent("oauth2.user.agent.scopes")
return config, nil
}
func main() {
// Process LIFERAY_ROUTES_DXP
dxpConfig, err := getDXPConfig()
if err != nil {
fmt.Printf("Error getting DXP config: %v\n", err)
} else if dxpConfig != nil {
fmt.Println("LIFERAY_ROUTES_DXP Configuration:")
fmt.Printf(" Domains: %v\n", dxpConfig.Domains)
fmt.Printf(" Main Domain: %s\n", dxpConfig.MainDomain)
fmt.Printf(" Server Protocol: %s\n", dxpConfig.ServerProtocol)
}
// Process LIFERAY_ROUTES_CLIENT_EXTENSION
// Replace "your-app-reference-code" with the actual reference code from your client-extension.yaml
appReferenceCode := os.Getenv("OAUTH_ERC")
ceOAuth2Config, err := loadClientExtensionOAuth2Config(appReferenceCode)
if err != nil {
fmt.Printf("Error getting Client Extension OAuth 2.0 config: %v\n", err)
} else if ceOAuth2Config != nil {
fmt.Printf("LIFERAY_ROUTES_CLIENT_EXTENSION Configuration for '%s':\n", appReferenceCode)
fmt.Printf(" Headless Server Audience: %s\n", ceOAuth2Config.HeadlessServerAudience)
fmt.Printf(" Headless Server Client ID: %s\n", ceOAuth2Config.HeadlessServerClientID)
fmt.Printf(" Headless Server Client Secret: %s\n", ceOAuth2Config.HeadlessServerClientSecret)
fmt.Printf(" Headless Server Scopes: %s\n", ceOAuth2Config.HeadlessServerScopes)
fmt.Printf(" Authorization URI: %s\n", ceOAuth2Config.AuthorizationURI)
fmt.Printf(" Introspection URI: %s\n", ceOAuth2Config.IntrospectionURI)
fmt.Printf(" JWKS URI: %s\n", ceOAuth2Config.JWKSURI)
fmt.Printf(" Token URI: %s\n", ceOAuth2Config.TokenURI)
fmt.Printf(" Redirect URIs: %v\n", ceOAuth2Config.RedirectURIs)
fmt.Printf(" User Agent Audience: %s\n", ceOAuth2Config.UserAgentAudience)
fmt.Printf(" User Agent Client ID: %s\n", ceOAuth2Config.UserAgentClientID)
fmt.Printf(" User Agent Scopes: %s\n", ceOAuth2Config.UserAgentScopes)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment