use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class AbstractOAuthAuthenticator method validateScopes.
/**
* @param message CXF message to be validate
* @param tokenInfo Token information associated with incoming request
* @return return true if we found matching scope in resource and token information
* else false(means scope validation failed).
*/
@MethodStats
public boolean validateScopes(Message message, OAuthTokenInfo tokenInfo) {
String basePath = (String) message.get(Message.BASE_PATH);
// path is obtained from Message.REQUEST_URI instead of Message.PATH_INFO, as Message.PATH_INFO contains
// decoded values of request parameters
String path = (String) message.get(Message.REQUEST_URI);
String verb = (String) message.get(Message.HTTP_REQUEST_METHOD);
String resource = path.substring(basePath.length() - 1);
String[] scopes = tokenInfo.getScopes();
String version = (String) message.get(RestApiConstants.API_VERSION);
// get all the URI templates of the REST API from the base path
Set<URITemplate> uriTemplates = RestApiUtil.getURITemplatesForBasePath(basePath + version);
if (uriTemplates.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("No matching scopes found for request with path: " + basePath + ". Skipping scope validation.");
}
return true;
}
for (Object template : uriTemplates.toArray()) {
org.wso2.uri.template.URITemplate templateToValidate = null;
Map<String, String> var = new HashMap<String, String>();
// check scopes with what we have
String templateString = ((URITemplate) template).getUriTemplate();
try {
templateToValidate = new org.wso2.uri.template.URITemplate(templateString);
} catch (URITemplateException e) {
log.error("Error while creating URI Template object to validate request. Template pattern: " + templateString, e);
}
if (templateToValidate != null && templateToValidate.matches(resource, var) && scopes != null && verb != null && verb.equalsIgnoreCase(((URITemplate) template).getHTTPVerb())) {
for (String scope : scopes) {
Scope scp = ((URITemplate) template).getScope();
if (scp != null) {
if (scope.equalsIgnoreCase(scp.getKey())) {
// we found scopes matches
if (log.isDebugEnabled()) {
log.debug("Scope validation successful for access token: " + message.get(RestApiConstants.MASKED_TOKEN) + " with scope: " + scp.getKey() + " for resource path: " + path + " and verb " + verb);
}
return true;
}
} else if (!((URITemplate) template).retrieveAllScopes().isEmpty()) {
List<Scope> scopesList = ((URITemplate) template).retrieveAllScopes();
for (Scope scpObj : scopesList) {
if (scope.equalsIgnoreCase(scpObj.getKey())) {
// we found scopes matches
if (log.isDebugEnabled()) {
log.debug("Scope validation successful for access token: " + message.get(RestApiConstants.MASKED_TOKEN) + " with scope: " + scpObj.getKey() + " for resource path: " + path + " and verb " + verb);
}
return true;
}
}
} else {
if (log.isDebugEnabled()) {
log.debug("Scope not defined in swagger for matching resource " + resource + " and verb " + verb + " . So consider as anonymous permission and let request to continue.");
}
return true;
}
}
}
}
return false;
}
use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class PublisherCommonUtils method getFieldOverriddenAPIDTO.
/**
* Get the API DTO object in which the API field values are overridden with the user passed new values.
*
* @throws APIManagementException
*/
private static APIDTO getFieldOverriddenAPIDTO(APIDTO apidto, API originalAPI, String[] tokenScopes) throws APIManagementException {
APIDTO originalApiDTO;
APIDTO updatedAPIDTO;
try {
originalApiDTO = APIMappingUtil.fromAPItoDTO(originalAPI);
Field[] fields = APIDTO.class.getDeclaredFields();
ObjectMapper mapper = new ObjectMapper();
String newApiDtoJsonString = mapper.writeValueAsString(apidto);
JSONParser parser = new JSONParser();
JSONObject newApiDtoJson = (JSONObject) parser.parse(newApiDtoJsonString);
String originalApiDtoJsonString = mapper.writeValueAsString(originalApiDTO);
JSONObject originalApiDtoJson = (JSONObject) parser.parse(originalApiDtoJsonString);
for (Field field : fields) {
Scope[] fieldAnnotatedScopes = field.getAnnotationsByType(Scope.class);
String originalElementValue = mapper.writeValueAsString(originalApiDtoJson.get(field.getName()));
String newElementValue = mapper.writeValueAsString(newApiDtoJson.get(field.getName()));
if (!StringUtils.equals(originalElementValue, newElementValue)) {
originalApiDtoJson = overrideDTOValues(originalApiDtoJson, newApiDtoJson, field, tokenScopes, fieldAnnotatedScopes);
}
}
updatedAPIDTO = mapper.readValue(originalApiDtoJson.toJSONString(), APIDTO.class);
} catch (IOException | ParseException e) {
String msg = "Error while processing API DTO json strings";
throw new APIManagementException(msg, e, ExceptionCodes.JSON_PARSE_ERROR);
}
return updatedAPIDTO;
}
use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class ApiProductsApiServiceImpl method importAPIProduct.
/**
* Import an API Product by uploading an archive file. All relevant API Product data will be included upon the creation of
* the API Product. Depending on the choice of the user, provider of the imported API Product will be preserved or modified.
*
* @param fileInputStream UploadedInputStream input stream from the REST request
* @param fileDetail File details as Attachment
* @param preserveProvider User choice to keep or replace the API Product provider
* @param rotateRevision If the maximum revision number reached, undeploy the earliest revision and create a
* new revision
* @param importAPIs Whether to import the dependent APIs or not.
* @param overwriteAPIProduct Whether to update the API Product or not. This is used when updating already existing API Products.
* @param overwriteAPIs Whether to update the dependent APIs or not. This is used when updating already existing dependent APIs of an API Product.
* @param messageContext Message Context
* @return API Product import response
* @throws APIManagementException
*/
@Override
public Response importAPIProduct(InputStream fileInputStream, Attachment fileDetail, Boolean preserveProvider, Boolean rotateRevision, Boolean importAPIs, Boolean overwriteAPIProduct, Boolean overwriteAPIs, MessageContext messageContext) throws APIManagementException {
// If importAPIs flag is not set, the default value is false
importAPIs = importAPIs == null ? false : importAPIs;
// Check if the URL parameter value is specified, otherwise the default value is true.
preserveProvider = preserveProvider == null || preserveProvider;
String organization = RestApiUtil.getValidatedOrganization(messageContext);
String[] tokenScopes = (String[]) PhaseInterceptorChain.getCurrentMessage().getExchange().get(RestApiConstants.USER_REST_API_SCOPES);
ImportExportAPI importExportAPI = APIImportExportUtil.getImportExportAPI();
// If the user need to import dependent APIs and the user has the required scope for that, allow the user to do it
if (tokenScopes == null) {
RestApiUtil.handleInternalServerError("Error occurred while importing the API Product", log);
return null;
} else {
Boolean isRequiredScopesAvailable = Arrays.asList(tokenScopes).contains(RestApiConstants.API_IMPORT_EXPORT_SCOPE);
if (!isRequiredScopesAvailable) {
log.info("Since the user does not have required scope: " + RestApiConstants.API_IMPORT_EXPORT_SCOPE + ", importAPIs will be set to false");
}
importAPIs = importAPIs && isRequiredScopesAvailable;
}
// Check whether to update the API Product. If not specified, default value is false.
overwriteAPIProduct = overwriteAPIProduct == null ? false : overwriteAPIProduct;
// Check whether to update the dependent APIs. If not specified, default value is false.
overwriteAPIs = overwriteAPIs == null ? false : overwriteAPIs;
// Check if the URL parameter value is specified, otherwise the default value is true.
preserveProvider = preserveProvider == null || preserveProvider;
importExportAPI.importAPIProduct(fileInputStream, preserveProvider, rotateRevision, overwriteAPIProduct, overwriteAPIs, importAPIs, tokenScopes, organization);
return Response.status(Response.Status.OK).entity("API Product imported successfully.").build();
}
use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class JWTUtil method handleScopeValidation.
/**
* Handle scope validation
*
* @param accessToken JWT token
* @param signedJWTInfo : Signed token info
* @param message : inbound message context
*/
public static boolean handleScopeValidation(HashMap<String, Object> message, SignedJWTInfo signedJWTInfo, String accessToken) throws APIManagementException, ParseException {
String maskedToken = message.get(RestApiConstants.MASKED_TOKEN).toString();
OAuthTokenInfo oauthTokenInfo = new OAuthTokenInfo();
oauthTokenInfo.setAccessToken(accessToken);
oauthTokenInfo.setEndUserName(signedJWTInfo.getJwtClaimsSet().getSubject());
String scopeClaim = signedJWTInfo.getJwtClaimsSet().getStringClaim(APIConstants.JwtTokenConstants.SCOPE);
if (scopeClaim != null) {
String orgId = (String) message.get(RestApiConstants.ORG_ID);
String[] scopes = scopeClaim.split(APIConstants.JwtTokenConstants.SCOPE_DELIMITER);
scopes = java.util.Arrays.stream(scopes).filter(s -> s.contains(orgId)).map(s -> s.replace(APIConstants.URN_CHOREO + orgId + ":", "")).toArray(size -> new String[size]);
oauthTokenInfo.setScopes(scopes);
if (validateScopes(message, oauthTokenInfo)) {
// Add the user scopes list extracted from token to the cxf message
message.put(RestApiConstants.USER_REST_API_SCOPES, oauthTokenInfo.getScopes());
// If scope validation successful then set tenant name and user name to current context
String tenantDomain = MultitenantUtils.getTenantDomain(oauthTokenInfo.getEndUserName());
int tenantId;
PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
RealmService realmService = (RealmService) carbonContext.getOSGiService(RealmService.class, null);
try {
String username = oauthTokenInfo.getEndUserName();
if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
// when the username is an email in supertenant, it has at least 2 occurrences of '@'
long count = username.chars().filter(ch -> ch == '@').count();
// in the case of email, there will be more than one '@'
boolean isEmailUsernameEnabled = Boolean.parseBoolean(CarbonUtils.getServerConfiguration().getFirstProperty("EnableEmailUserName"));
if (isEmailUsernameEnabled || (username.endsWith(SUPER_TENANT_SUFFIX) && count <= 1)) {
username = MultitenantUtils.getTenantAwareUsername(username);
}
}
if (log.isDebugEnabled()) {
log.debug("username = " + username + "masked token " + maskedToken);
}
tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
carbonContext.setTenantDomain(tenantDomain);
carbonContext.setTenantId(tenantId);
carbonContext.setUsername(username);
if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
APIUtil.loadTenantConfigBlockingMode(tenantDomain);
}
return true;
} catch (UserStoreException e) {
log.error("Error while retrieving tenant id for tenant domain: " + tenantDomain, e);
}
log.debug("Scope validation success for the token " + maskedToken);
return true;
}
log.error("scopes validation failed for the token" + maskedToken);
return false;
}
log.error("scopes validation failed for the token" + maskedToken);
return false;
}
use of org.wso2.carbon.apimgt.api.model.Scope in project carbon-apimgt by wso2.
the class SystemScopesMappingUtil method fromRoleScopeMapToRoleScopeDTOList.
/**
* Converts api scope-role mapping to RoleScopeDTO List.
*
* @param scopeRoleMapping Map of a Role Scope Mapping
* @return RoleScopeDTO list
*/
private static List<ScopeDTO> fromRoleScopeMapToRoleScopeDTOList(Map<String, String> scopeRoleMapping) throws APIManagementException {
List<ScopeDTO> scopeDTOs = new ArrayList<>(scopeRoleMapping.size());
if (portalScopeList.isEmpty()) {
synchronized (lock) {
if (portalScopeList.isEmpty()) {
portalScopeList = RestApiUtil.getScopesInfoFromAPIYamlDefinitions();
}
}
}
for (Map.Entry<String, List<String>> mapping : portalScopeList.entrySet()) {
// openid scope doesn't need a role mapping
if (APIConstants.OPEN_ID_SCOPE_NAME.equals(mapping.getKey())) {
continue;
}
if (scopeRoleMapping.containsKey(mapping.getKey())) {
ScopeDTO roleScopeDTO = new ScopeDTO();
roleScopeDTO.setName(mapping.getKey());
String roles = scopeRoleMapping.get(mapping.getKey());
List<String> roleList = new ArrayList<String>(Arrays.asList((roles.replaceAll("\\s+", "")).split(",")));
roleScopeDTO.setRoles(roleList);
roleScopeDTO.setDescription(mapping.getValue().get(0));
roleScopeDTO.setTag(mapping.getValue().get(1));
scopeDTOs.add(roleScopeDTO);
} else {
log.warn("The scope " + mapping.getKey() + " does not exist in tenant.conf");
}
}
return scopeDTOs;
}
Aggregations