diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f2f11a35d6c8d1f10b2240bc772ad1397c84b5..f7df3b7236360ac97cbd7d1fd2ede6e8f3add914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ IMPROVEMENTS BUG FIXES * Consumer API: multiple consumers from same group receive stream finished error +* Consumer API: return ServiceUnavailable instead of Unauthorized in case an authorization service is unreachable ## 21.03.3 diff --git a/broker/src/asapo_broker/server/authorizer.go b/broker/src/asapo_broker/server/authorizer.go index 4ff965d05b2e20d2860d319ecbb6809248accde1..66a01d31a8ac1866082ef8b4ce4810090ce59126 100644 --- a/broker/src/asapo_broker/server/authorizer.go +++ b/broker/src/asapo_broker/server/authorizer.go @@ -23,16 +23,15 @@ type HttpClient interface { Do(req *http.Request) (*http.Response, error) } -type HttpError struct{ +type AuthorizationError struct{ err error statusCode int } -func (m *HttpError) Error() string { +func (m AuthorizationError) Error() string { return m.err.Error() } - type AsapoAuthorizer struct { serverUrl string httpClient HttpClient @@ -83,13 +82,19 @@ func (a * AsapoAuthorizer) doRequest(req *http.Request) (token Token, err error) return token, err } - if resp.StatusCode != http.StatusOK { - return token, &HttpError{errors.New("authorizer returned " + resp.Status + ": " + string(body)),resp.StatusCode} + switch resp.StatusCode { + case http.StatusOK: + //do nothing + case http.StatusUnauthorized: + return token, &AuthorizationError{errors.New("authorizer rejected to authorize: " + string(body)),http.StatusUnauthorized} + default: + return token, errors.New("authorizer returned " + resp.Status + ": " + string(body)) } err = json.Unmarshal(body, &token) return } + func createIntrospectTokenRequest(tokenJWT string) (*http.Request, error) { path := "http://"+settings.AuthorizationServer + "/introspect" request := struct { diff --git a/broker/src/asapo_broker/server/process_request_test.go b/broker/src/asapo_broker/server/process_request_test.go index 5204c1c540f3ca2535f90a78ead3ebb0b72c0da9..4ac81cd3b1a979b4e2aa4878079758cba8bd091a 100644 --- a/broker/src/asapo_broker/server/process_request_test.go +++ b/broker/src/asapo_broker/server/process_request_test.go @@ -45,7 +45,7 @@ func (a *MockAuthServer) AuthorizeToken(tokenJWT string) (token Token, err error }, nil } - return Token{}, errors.New("wrong JWT token") + return Token{}, AuthorizationError{errors.New("wrong JWT token"),http.StatusUnauthorized} } func prepareTestAuth() { @@ -146,7 +146,7 @@ func (suite *ProcessRequestTestSuite) TestProcessRequestWithNoToken() { w := doRequest("/beamtime/" + expectedBeamtimeId + "/" + expectedSource + "/" + expectedStream + "/" + expectedGroupID + "/next" + wrongTokenSuffix) - suite.Equal(http.StatusUnauthorized, w.Code, "no token") + suite.Equal(http.StatusBadRequest, w.Code, "no token") } func (suite *ProcessRequestTestSuite) TestProcessRequestWithWrongDatabaseName() { diff --git a/broker/src/asapo_broker/server/request_common.go b/broker/src/asapo_broker/server/request_common.go index 49b65f86308c8ddb05e4b09f2f44cf1b206c84ef..17a4b30aedd417fd018b69382284ab5e305322f9 100644 --- a/broker/src/asapo_broker/server/request_common.go +++ b/broker/src/asapo_broker/server/request_common.go @@ -12,11 +12,11 @@ func writeAuthAnswer(w http.ResponseWriter, requestName string, db_name string, log_str := "processing " + requestName + " request in " + db_name + " at " + settings.GetDatabaseServer() logger.Error(log_str + " - " + err.Error()) - httpError, ok := err.(*HttpError) - if ok && httpError.statusCode != http.StatusUnauthorized { + switch er := err.(type) { + case AuthorizationError: + w.WriteHeader(er.statusCode) + default: w.WriteHeader(http.StatusInternalServerError) - } else { - w.WriteHeader(http.StatusUnauthorized) } w.Write([]byte(err.Error())) } @@ -54,7 +54,7 @@ func authorize(r *http.Request, beamtime_id string, needWriteAccess bool) error tokenJWT := r.URL.Query().Get("token") if len(tokenJWT) == 0 { - return errors.New("cannot extract token from request") + return AuthorizationError{errors.New("cannot extract token from request"),http.StatusBadRequest} } token, err := auth.AuthorizeToken(tokenJWT) @@ -72,18 +72,18 @@ func authorize(r *http.Request, beamtime_id string, needWriteAccess bool) error func checkSubject(subject string, beamtime_id string) error { if subject != utils.SubjectFromBeamtime(beamtime_id) { - return errors.New("wrong token subject") + return AuthorizationError{errors.New("wrong token subject"),http.StatusUnauthorized} } return nil } func checkAccessType(accessTypes []string, needWriteAccess bool) error { if needWriteAccess && !utils.StringInSlice("write",accessTypes) { - return errors.New("wrong token access type") + return AuthorizationError{errors.New("wrong token access type"),http.StatusUnauthorized} } if !utils.StringInSlice("read",accessTypes) { - return errors.New("wrong token access type") + return AuthorizationError{errors.New("wrong token access type"),http.StatusUnauthorized} } return nil }