use of com.amplifyframework.api.ApiException.ApiAuthException in project amplify-android by aws-amplify.
the class AuthRuleRequestDecorator method decorate.
/**
* Decorate given GraphQL request instance with additional variables for owner-based or
* group-based authorization.
*
* This will only work if the request is compliant with the AppSync specifications.
* @param request an instance of {@link GraphQLRequest}.
* @param authType the mode of authorization being used to authorize the request
* @param <R> The type of data contained in the GraphQLResponse expected from this request.
* @return the input request with additional variables that specify model's owner and/or
* groups
* @throws ApiException If an error is encountered while processing the auth rules associated
* with the request or if the authorization fails
*/
public <R> GraphQLRequest<R> decorate(@NonNull GraphQLRequest<R> request, @NonNull AuthorizationType authType) throws ApiException {
if (!(request instanceof AppSyncGraphQLRequest)) {
return request;
}
AppSyncGraphQLRequest<R> appSyncRequest = (AppSyncGraphQLRequest<R>) request;
AuthRule ownerRuleWithReadRestriction = null;
Map<String, Set<String>> readAuthorizedGroupsMap = new HashMap<>();
// and it's not clear what a good solution would be until AppSync supports real time filters.
for (AuthRule authRule : appSyncRequest.getModelSchema().getAuthRules()) {
if (isReadRestrictingOwner(authRule)) {
if (ownerRuleWithReadRestriction == null) {
ownerRuleWithReadRestriction = authRule;
} else {
throw new ApiAuthException("Detected multiple owner type auth rules with a READ operation", "We currently do not support this use case. Please limit your type to just one owner " + "auth rule with a READ operation restriction.");
}
} else if (isReadRestrictingStaticGroup(authRule)) {
// Group read-restricting groups by the claim name
String groupClaim = authRule.getGroupClaimOrDefault();
List<String> groups = authRule.getGroups();
Set<String> readAuthorizedGroups = readAuthorizedGroupsMap.get(groupClaim);
if (readAuthorizedGroups != null) {
readAuthorizedGroups.addAll(groups);
} else {
readAuthorizedGroupsMap.put(groupClaim, new HashSet<>(groups));
}
}
}
// them.
if (ownerRuleWithReadRestriction != null && userNotInReadRestrictingGroups(readAuthorizedGroupsMap, authType)) {
String idClaim = ownerRuleWithReadRestriction.getIdentityClaimOrDefault();
String key = ownerRuleWithReadRestriction.getOwnerFieldOrDefault();
String value = getIdentityValue(idClaim, authType);
try {
return appSyncRequest.newBuilder().variable(key, "String!", value).build();
} catch (AmplifyException error) {
// This should not happen normally
throw new ApiAuthException("Failed to set owner field on AppSyncGraphQLRequest.", error, AmplifyException.REPORT_BUG_TO_AWS_SUGGESTION);
}
}
return request;
}
use of com.amplifyframework.api.ApiException.ApiAuthException in project amplify-android by aws-amplify.
the class IamRequestDecorator method decorate.
/**
* Adds the appropriate header to the provided HTTP request.
* @param req The request to be signed.
* @return A new instance of the request containing the signature headers.
* @throws ApiAuthException If the signing process fails.
*/
public final okhttp3.Request decorate(okhttp3.Request req) throws ApiAuthException {
// Clone the request into a new DefaultRequest object and populate it with credentials
final DefaultRequest<?> dr = new DefaultRequest<>(serviceName);
// set the endpoint
dr.setEndpoint(req.url().uri());
// copy all the headers
for (String headerName : req.headers().names()) {
dr.addHeader(headerName, req.header(headerName));
}
// set the http method
dr.setHttpMethod(HttpMethodName.valueOf(req.method()));
// set the request body
final byte[] bodyBytes;
RequestBody body = req.body();
boolean isEmptyRequestBody = false;
try {
if (body != null && body.contentLength() > 0) {
// write the body to a byte array.
final Buffer buffer = new Buffer();
body.writeTo(buffer);
bodyBytes = IOUtils.toByteArray(buffer.inputStream());
} else {
isEmptyRequestBody = true;
bodyBytes = "".getBytes();
}
dr.setParameters(splitQuery(req.url().url()));
} catch (IOException exception) {
throw new ApiAuthException("Unable to calculate SigV4 signature for the request", exception, "Check your application logs for details.");
}
dr.setContent(new ByteArrayInputStream(bodyBytes));
// set the query string parameters
v4Signer.sign(dr, credentialsProvider.getCredentials());
// Copy the signed/credentialed request back into an OKHTTP Request object.
okhttp3.Request.Builder okReqBuilder = new okhttp3.Request.Builder();
// set the headers from default request, since it contains the signed headers as well.
for (Map.Entry<String, String> e : dr.getHeaders().entrySet()) {
okReqBuilder.addHeader(e.getKey(), e.getValue());
}
// Set the URL and Method
okReqBuilder.url(req.url());
final RequestBody requestBody;
if (!isEmptyRequestBody) {
requestBody = RequestBody.create(bodyBytes, JSON_MEDIA_TYPE);
} else {
requestBody = null;
}
okReqBuilder.method(req.method(), requestBody);
// continue with chain.
return okReqBuilder.build();
}
Aggregations