oscar_config.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package webapi
  2. import (
  3. "net"
  4. "strconv"
  5. "strings"
  6. "github.com/mk6i/open-oscar-server/config"
  7. )
  8. // OSCARConfigAdapter adapts the main server configuration to provide
  9. // OSCAR-specific configuration for the Web API bridge.
  10. type OSCARConfigAdapter struct {
  11. cfg config.Config
  12. listeners []config.Listener
  13. }
  14. // NewOSCARConfigAdapter creates a new OSCAR configuration adapter.
  15. func NewOSCARConfigAdapter(cfg config.Config) *OSCARConfigAdapter {
  16. listeners, _ := cfg.ParseListenersCfg()
  17. return &OSCARConfigAdapter{
  18. cfg: cfg,
  19. listeners: listeners,
  20. }
  21. }
  22. // GetBOSAddress returns the plain (non-SSL) BOS server address for client connections.
  23. // This parses the configured BOS advertised host to extract the hostname and port.
  24. func (a *OSCARConfigAdapter) GetBOSAddress() (host string, port int) {
  25. // Default to first listener configuration
  26. if len(a.listeners) == 0 {
  27. return "localhost", 5190 // Default OSCAR port
  28. }
  29. listener := a.listeners[0]
  30. // Parse the advertised host for plain connections
  31. if listener.BOSAdvertisedHostPlain != "" {
  32. host, portStr := splitHostPort(listener.BOSAdvertisedHostPlain)
  33. if portStr != "" {
  34. if p, err := strconv.Atoi(portStr); err == nil {
  35. port = p
  36. }
  37. }
  38. if port == 0 {
  39. port = 5190 // Default OSCAR port
  40. }
  41. return host, port
  42. }
  43. // Fall back to parsing the listen address
  44. if listener.BOSListenAddress != "" {
  45. host, portStr, err := net.SplitHostPort(listener.BOSListenAddress)
  46. if err == nil {
  47. if host == "" {
  48. host = "localhost"
  49. }
  50. if p, err := strconv.Atoi(portStr); err == nil {
  51. port = p
  52. }
  53. }
  54. if port == 0 {
  55. port = 5190
  56. }
  57. return host, port
  58. }
  59. return "localhost", 5190
  60. }
  61. // GetSSLBOSAddress returns the SSL-enabled BOS server address for client connections.
  62. func (a *OSCARConfigAdapter) GetSSLBOSAddress() (host string, port int) {
  63. // Default to first listener configuration with SSL
  64. for _, listener := range a.listeners {
  65. if listener.HasSSL && listener.BOSAdvertisedHostSSL != "" {
  66. host, portStr := splitHostPort(listener.BOSAdvertisedHostSSL)
  67. if portStr != "" {
  68. if p, err := strconv.Atoi(portStr); err == nil {
  69. port = p
  70. }
  71. }
  72. if port == 0 {
  73. port = 5190 // Default OSCAR SSL port (could be different)
  74. }
  75. return host, port
  76. }
  77. }
  78. // Fall back to plain address if no SSL configured
  79. return a.GetBOSAddress()
  80. }
  81. // IsSSLAvailable checks if any listener has SSL configured.
  82. func (a *OSCARConfigAdapter) IsSSLAvailable() bool {
  83. for _, listener := range a.listeners {
  84. if listener.HasSSL {
  85. return true
  86. }
  87. }
  88. return false
  89. }
  90. // IsAuthDisabled returns whether authentication is disabled.
  91. func (a *OSCARConfigAdapter) IsAuthDisabled() bool {
  92. return a.cfg.DisableAuth
  93. }
  94. // splitHostPort splits a host:port string, handling IPv6 addresses correctly.
  95. // Unlike net.SplitHostPort, this doesn't return an error for missing ports.
  96. func splitHostPort(hostport string) (host string, port string) {
  97. // Handle IPv6 addresses
  98. if strings.HasPrefix(hostport, "[") {
  99. endIdx := strings.LastIndex(hostport, "]")
  100. if endIdx != -1 {
  101. host = hostport[1:endIdx]
  102. if endIdx+1 < len(hostport) && hostport[endIdx+1] == ':' {
  103. port = hostport[endIdx+2:]
  104. }
  105. return
  106. }
  107. }
  108. // Handle IPv4 and hostnames
  109. lastColon := strings.LastIndex(hostport, ":")
  110. if lastColon != -1 {
  111. // Check if this might be an IPv6 address without brackets
  112. if strings.Count(hostport, ":") > 1 {
  113. // Multiple colons, likely IPv6 without port
  114. host = hostport
  115. return
  116. }
  117. host = hostport[:lastColon]
  118. port = hostport[lastColon+1:]
  119. return
  120. }
  121. // No port specified
  122. host = hostport
  123. return
  124. }