diff --git a/internal/anysdk/auth_dto.go b/internal/anysdk/auth_dto.go index 1266114..3f69f75 100644 --- a/internal/anysdk/auth_dto.go +++ b/internal/anysdk/auth_dto.go @@ -43,6 +43,13 @@ type AuthDTO interface { GetAuthStyle() int GetAccountID() string GetAccountIDEnvVar() string + GetOciTenancyOCIDEnvVar() string + GetOciUserOCIDEnvVar() string + GetOciFingerprintEnvVar() string + GetOciPrivateKeyEnvVar() string + GetOciPrivateKeyPathEnvVar() string + GetOciPassphraseEnvVar() string + GetOciRegionEnvVar() string } type standardAuthDTO struct { @@ -76,6 +83,50 @@ type standardAuthDTO struct { AuthStyle int `json:"auth_style" yaml:"auth_style"` AccoountID string `json:"account_id" yaml:"account_id"` AccountIDEnvVar string `json:"account_id_env_var" yaml:"account_id_var"` + // OCI signing (oci_signing_v1) doc-level env var indirections: a provider + // doc may ship default env var names so that a populated environment + // needs no runtime auth context at all. Only indirections are accepted + // at doc level - literal credential values belong exclusively in the + // runtime auth context. + // Key naming: every property carries an OCI reference at the operator + // surface (tenancy_ocid/user_ocid via "ocid", the rest via an oci_ + // prefix) so generic terms (fingerprint, private key, passphrase) stay + // available to other auth types without collision. + OciTenancyOCIDEnvVar string `json:"tenancy_ocid_envvar,omitempty" yaml:"tenancy_ocid_envvar,omitempty"` + OciUserOCIDEnvVar string `json:"user_ocid_envvar,omitempty" yaml:"user_ocid_envvar,omitempty"` + OciFingerprintEnvVar string `json:"oci_fingerprint_envvar,omitempty" yaml:"oci_fingerprint_envvar,omitempty"` + OciPrivateKeyEnvVar string `json:"oci_private_key_envvar,omitempty" yaml:"oci_private_key_envvar,omitempty"` + OciPrivateKeyPathEnvVar string `json:"oci_private_key_path_envvar,omitempty" yaml:"oci_private_key_path_envvar,omitempty"` + OciPassphraseEnvVar string `json:"oci_passphrase_envvar,omitempty" yaml:"oci_passphrase_envvar,omitempty"` + OciRegionEnvVar string `json:"oci_region_envvar,omitempty" yaml:"oci_region_envvar,omitempty"` +} + +func (qt standardAuthDTO) GetOciTenancyOCIDEnvVar() string { + return qt.OciTenancyOCIDEnvVar +} + +func (qt standardAuthDTO) GetOciUserOCIDEnvVar() string { + return qt.OciUserOCIDEnvVar +} + +func (qt standardAuthDTO) GetOciFingerprintEnvVar() string { + return qt.OciFingerprintEnvVar +} + +func (qt standardAuthDTO) GetOciPrivateKeyEnvVar() string { + return qt.OciPrivateKeyEnvVar +} + +func (qt standardAuthDTO) GetOciPrivateKeyPathEnvVar() string { + return qt.OciPrivateKeyPathEnvVar +} + +func (qt standardAuthDTO) GetOciPassphraseEnvVar() string { + return qt.OciPassphraseEnvVar +} + +func (qt standardAuthDTO) GetOciRegionEnvVar() string { + return qt.OciRegionEnvVar } func (qt standardAuthDTO) GetAccountID() string { diff --git a/internal/anysdk/operation_store.go b/internal/anysdk/operation_store.go index f1c672d..b455832 100644 --- a/internal/anysdk/operation_store.go +++ b/internal/anysdk/operation_store.go @@ -1735,14 +1735,21 @@ func (op *standardOpenAPIOperationStore) parameterize(prov Provider, parentDoc S // TODO: clean up sv = strings.TrimSuffix(sv, "/") path := replaceSimpleStringVars(fmt.Sprintf("%s%s", sv, op.OperationRef.extractPathItem()), pathParams) - u, err := url.Parse(fmt.Sprintf("%s?%s", path, q.Encode())) - if strings.Contains(path, "?") { - if len(q) > 0 { - u, err = url.Parse(fmt.Sprintf("%s&%s", path, q.Encode())) - } else { - u, err = url.Parse(path) - } - } + // Never emit a dangling "?" for an empty query: url.Parse records it as + // ForceQuery and reproduces it on the wire, and signature schemes that + // cover (request-target) then fail against servers that normalise the + // request line before verification (OCI 401 NotAuthenticated on every + // no-query body verb). + encodedQuery := q.Encode() + rawURL := path + if encodedQuery != "" { + separator := "?" + if strings.Contains(path, "?") { + separator = "&" + } + rawURL = fmt.Sprintf("%s%s%s", path, separator, encodedQuery) + } + u, err := url.Parse(rawURL) if err != nil { return nil, err } diff --git a/pkg/authsurface/surface.go b/pkg/authsurface/surface.go index 1d844d9..f102461 100644 --- a/pkg/authsurface/surface.go +++ b/pkg/authsurface/surface.go @@ -33,4 +33,11 @@ type AuthDTO interface { GetAuthStyle() int GetAccountID() string GetAccountIDEnvVar() string + GetOciTenancyOCIDEnvVar() string + GetOciUserOCIDEnvVar() string + GetOciFingerprintEnvVar() string + GetOciPrivateKeyEnvVar() string + GetOciPrivateKeyPathEnvVar() string + GetOciPassphraseEnvVar() string + GetOciRegionEnvVar() string } diff --git a/public/formulation/interfaces.go b/public/formulation/interfaces.go index c067dc9..e00bf12 100644 --- a/public/formulation/interfaces.go +++ b/public/formulation/interfaces.go @@ -768,6 +768,13 @@ type AuthDTO interface { GetKeyIDEnvVar() string GetLocation() string GetName() string + GetOciFingerprintEnvVar() string + GetOciPassphraseEnvVar() string + GetOciPrivateKeyEnvVar() string + GetOciPrivateKeyPathEnvVar() string + GetOciRegionEnvVar() string + GetOciTenancyOCIDEnvVar() string + GetOciUserOCIDEnvVar() string GetScopes() []string GetSubject() string GetSuccessor() (AuthDTO, bool) diff --git a/public/formulation/wrappers.go b/public/formulation/wrappers.go index 9affd8f..ebd5e4f 100644 --- a/public/formulation/wrappers.go +++ b/public/formulation/wrappers.go @@ -2631,6 +2631,34 @@ type wrappedAuthDTO struct { inner authsurface.AuthDTO } +func (w *wrappedAuthDTO) GetOciTenancyOCIDEnvVar() string { + return w.inner.GetOciTenancyOCIDEnvVar() +} + +func (w *wrappedAuthDTO) GetOciUserOCIDEnvVar() string { + return w.inner.GetOciUserOCIDEnvVar() +} + +func (w *wrappedAuthDTO) GetOciFingerprintEnvVar() string { + return w.inner.GetOciFingerprintEnvVar() +} + +func (w *wrappedAuthDTO) GetOciPrivateKeyEnvVar() string { + return w.inner.GetOciPrivateKeyEnvVar() +} + +func (w *wrappedAuthDTO) GetOciPrivateKeyPathEnvVar() string { + return w.inner.GetOciPrivateKeyPathEnvVar() +} + +func (w *wrappedAuthDTO) GetOciPassphraseEnvVar() string { + return w.inner.GetOciPassphraseEnvVar() +} + +func (w *wrappedAuthDTO) GetOciRegionEnvVar() string { + return w.inner.GetOciRegionEnvVar() +} + func (w *wrappedAuthDTO) GetAccountID() string { r0 := w.inner.GetAccountID() return r0