Skip to content

Commit e37bcb7

Browse files
committed
Add APIHandler interface methods for default base domain and token endpoints
1 parent 83aa4ca commit e37bcb7

File tree

5 files changed

+58
-17
lines changed

5 files changed

+58
-17
lines changed

internal/apihandlers/jamfpro/jamfpro_api_handler.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,26 @@ type Logger interface {
118118

119119
// Functions
120120

121+
func (j *JamfAPIHandler) GetDefaultBaseDomain() string {
122+
return DefaultBaseDomain
123+
}
124+
125+
func (j *JamfAPIHandler) GetOAuthTokenEndpoint() string {
126+
return OAuthTokenEndpoint
127+
}
128+
129+
func (j *JamfAPIHandler) GetBearerTokenEndpoint() string {
130+
return BearerTokenEndpoint
131+
}
132+
133+
func (j *JamfAPIHandler) GetTokenRefreshEndpoint() string {
134+
return TokenRefreshEndpoint
135+
}
136+
137+
func (j *JamfAPIHandler) GetTokenInvalidateEndpoint() string {
138+
return TokenInvalidateEndpoint
139+
}
140+
121141
// GetBaseDomain returns the appropriate base domain for URL construction.
122142
// It uses OverrideBaseDomain if set, otherwise falls back to DefaultBaseDomain.
123143
func (j *JamfAPIHandler) GetBaseDomain() string {

internal/errors/http_error_handling.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import (
77
"fmt"
88
"net/http"
99

10+
"github.com/deploymenttheory/go-api-http-client/internal/logger"
1011
"go.uber.org/zap"
1112
)
1213

1314
// APIError represents a structured API error response.
1415
type APIError struct {
15-
StatusCode int
16-
Message string
16+
StatusCode int // HTTP status code
17+
Type string // A brief identifier for the type of error (e.g., "RateLimit", "BadRequest", etc.)
18+
Message string // Human-readable message
1719
}
1820

1921
// StructuredError represents a structured error response from the API.
@@ -24,19 +26,25 @@ type StructuredError struct {
2426
} `json:"error"`
2527
}
2628

29+
// Error returns a string representation of the APIError.
30+
func (e *APIError) Error() string {
31+
return fmt.Sprintf("API Error (Type: %s, Code: %d): %s", e.Type, e.StatusCode, e.Message)
32+
}
33+
2734
// HandleAPIError handles error responses from the API, converting them into a structured error if possible.
28-
func HandleAPIError(logger Logger, resp *http.Response) error {
35+
func HandleAPIError(resp *http.Response, log logger.Logger) error {
2936
var structuredErr StructuredError
3037
err := json.NewDecoder(resp.Body).Decode(&structuredErr)
3138
if err == nil && structuredErr.Error.Message != "" {
3239
// Using structured logging to log the structured error details
33-
c.Logger.Warn("API returned structured error",
40+
log.Warn("API returned structured error",
3441
zap.String("status", resp.Status),
3542
zap.String("error_code", structuredErr.Error.Code),
3643
zap.String("error_message", structuredErr.Error.Message),
3744
)
3845
return &APIError{
3946
StatusCode: resp.StatusCode,
47+
Type: structuredErr.Error.Code,
4048
Message: structuredErr.Error.Message,
4149
}
4250
}
@@ -46,29 +54,25 @@ func HandleAPIError(logger Logger, resp *http.Response) error {
4654
if err != nil || errMsg == "" {
4755
errMsg = fmt.Sprintf("Unexpected error with status code: %d", resp.StatusCode)
4856
// Logging with structured fields
49-
c.Logger.Warn("Failed to decode API error message, using default error message",
57+
log.Warn("Failed to decode API error message, using default error message",
5058
zap.String("status", resp.Status),
5159
zap.String("error_message", errMsg),
5260
)
5361
} else {
5462
// Logging non-structured error as a warning with structured fields
55-
c.Logger.Warn("API returned non-structured error",
63+
log.Warn("API returned non-structured error",
5664
zap.String("status", resp.Status),
5765
zap.String("error_message", errMsg),
5866
)
5967
}
6068

6169
return &APIError{
6270
StatusCode: resp.StatusCode,
71+
Type: "UnexpectedError",
6372
Message: errMsg,
6473
}
6574
}
6675

67-
// Error returns a string representation of the APIError.
68-
func (e *APIError) Error() string {
69-
return fmt.Sprintf("API Error (Code: %d): %s", e.StatusCode, e.Message)
70-
}
71-
7276
// TranslateStatusCode provides a human-readable message for HTTP status codes.
7377
func TranslateStatusCode(statusCode int) string {
7478
messages := map[int]string{

internal/httpclient/api_handler.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ type APIHandler interface {
2020
UnmarshalResponse(resp *http.Response, out interface{}, log logger.Logger) error
2121
GetContentTypeHeader(method string, log logger.Logger) string
2222
GetAcceptHeader() string
23+
GetDefaultBaseDomain() string
24+
GetOAuthTokenEndpoint() string
25+
GetBearerTokenEndpoint() string
26+
GetTokenRefreshEndpoint() string
27+
GetTokenInvalidateEndpoint() string
2328
}
2429

2530
// LoadAPIHandler returns an APIHandler based on the provided API type.

internal/httpclient/http_client_bearer_token_auth.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"net/http"
1010
"time"
1111

12+
"github.com/deploymenttheory/go-api-http-client/internal/errors"
1213
"github.com/deploymenttheory/go-api-http-client/internal/logger"
1314
"go.uber.org/zap"
1415
)
@@ -28,7 +29,9 @@ func (c *Client) SetBearerTokenAuthCredentials(credentials BearerTokenAuthCreden
2829

2930
// ObtainToken fetches and sets an authentication token using the stored basic authentication credentials.
3031
func (c *Client) ObtainToken(log logger.Logger) error {
31-
authenticationEndpoint := APIHandler.ConstructAPIAuthEndpoint(BearerTokenEndpoint)
32+
33+
bearerTokenEndpoint := c.APIHandler.GetBearerTokenEndpoint()
34+
authenticationEndpoint := c.APIHandler.ConstructAPIAuthEndpoint(bearerTokenEndpoint, c.Logger)
3235

3336
log.Debug("Attempting to obtain token for user", zap.String("Username", c.BearerTokenAuthCredentials.Username))
3437

@@ -48,7 +51,7 @@ func (c *Client) ObtainToken(log logger.Logger) error {
4851

4952
if resp.StatusCode != http.StatusOK {
5053
log.Warn("Received non-OK response while obtaining token", zap.Int("StatusCode", resp.StatusCode))
51-
return c.HandleAPIError(resp)
54+
return errors.HandleAPIError(resp, log)
5255
}
5356

5457
tokenResp := &TokenResponse{}
@@ -115,7 +118,9 @@ func (c *Client) RefreshToken(log logger.Logger) error {
115118
c.tokenLock.Lock()
116119
defer c.tokenLock.Unlock()
117120

118-
tokenRefreshEndpoint := c.ConstructAPIAuthEndpoint(TokenRefreshEndpoint)
121+
apiTokenRefreshEndpoint := c.APIHandler.GetTokenRefreshEndpoint()
122+
123+
tokenRefreshEndpoint := c.APIHandler.ConstructAPIAuthEndpoint(apiTokenRefreshEndpoint, c.Logger)
119124

120125
req, err := http.NewRequest("POST", tokenRefreshEndpoint, nil)
121126
if err != nil {
@@ -135,7 +140,7 @@ func (c *Client) RefreshToken(log logger.Logger) error {
135140

136141
if resp.StatusCode != http.StatusOK {
137142
log.Warn("Token refresh response status is not OK", zap.Int("StatusCode", resp.StatusCode))
138-
return c.HandleAPIError(resp)
143+
return errors.HandleAPIError(resp)
139144
}
140145

141146
tokenResp := &TokenResponse{}

internal/httpclient/http_client_oauth.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ func (c *Client) SetOAuthCredentials(credentials OAuthCredentials) {
4343
// ObtainOAuthToken fetches an OAuth access token using the provided OAuthCredentials (Client ID and Client Secret).
4444
// It updates the client's Token and Expiry fields with the obtained values.
4545
func (c *Client) ObtainOAuthToken(credentials AuthConfig, log logger.Logger) error {
46-
authenticationEndpoint := c.ConstructAPIAuthEndpoint(OAuthTokenEndpoint)
46+
47+
oauthTokenEndpoint := c.APIHandler.GetOAuthTokenEndpoint()
48+
authenticationEndpoint := c.APIHandler.ConstructAPIAuthEndpoint(oauthTokenEndpoint, c.Logger)
49+
4750
data := url.Values{}
4851
data.Set("client_id", credentials.ClientID)
4952
data.Set("client_secret", credentials.ClientSecret)
@@ -101,10 +104,13 @@ func (c *Client) ObtainOAuthToken(credentials AuthConfig, log logger.Logger) err
101104
return nil
102105
}
103106

107+
/*
104108
// InvalidateOAuthToken invalidates the current OAuth access token.
105109
// After invalidation, the token cannot be used for further API requests.
106110
func (c *Client) InvalidateOAuthToken(log logger.Logger) error {
107-
invalidateTokenEndpoint := c.ConstructAPIAuthEndpoint(TokenInvalidateEndpoint)
111+
112+
tokenInvalidateEndpoint := c.APIHandler.GetTokenInvalidateEndpoint()
113+
invalidateTokenEndpoint := APIHandler.ConstructAPIAuthEndpoint(tokenInvalidateEndpoint, log)
108114
109115
log.Debug("Attempting to invalidate OAuth token", zap.String("Endpoint", invalidateTokenEndpoint))
110116
@@ -132,3 +138,4 @@ func (c *Client) InvalidateOAuthToken(log logger.Logger) error {
132138
133139
return nil
134140
}
141+
*/

0 commit comments

Comments
 (0)