Unable to run check class com.adobe.platform.experience.selfservice.cqrules.checks.java.PotentiallyDangerousFunctionCheck - CWE-676
package org.uc.news.core.services;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.jcr.*;
import javax.jcr.query.*;
//Jackrabbit User APIs
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.uc.base.core.cacher.services.CachingService;
import org.uc.news.core.NewsConstants;
import org.uc.news.core.models.Author;
@Component(
service = PersonService.class
)
@Designate(ocd = PersonServiceImpl.Configuration.class)
public class PersonServiceImpl implements PersonService {
@ObjectClassDefinition(name="UC News - Person Service")
public @interface Configuration {}
@Reference
ResourceResolverFactory rrf;
@Reference
NewsSettingsService settings;
@OSGiService
@Reference
CachingService cachingService;
private static final Logger log = LoggerFactory.getLogger(PersonServiceImpl.class);
/**
* @param id the id of the author (usually 6+2)
* @return An {@link Author} object, as modelled by the class, or null if the author does not exist, or there is an exception (See logs if null)
*/
public Author getAuthor(String id) {
try(ResourceResolver resourceResolver = rrf.getServiceResourceResolver(NewsConstants.getReadAuthInfo())){
UserManager um = resourceResolver.adaptTo(UserManager.class);
Authorizable u = um.getAuthorizable(id);
Resource authorResource;
if(u == null) {
//try to get it from the info node
String lookupPath = settings.getInfoNodePath() + "/userinfo/" + id;
authorResource = resourceResolver.getResource(lookupPath);
} else {
authorResource = resourceResolver.getResource(u.getPath());
}
if(authorResource == null) {
log.info("Unable to get authorizable from " + id);
return null;
}
return authorResource.adaptTo(Author.class);
} catch(RepositoryException e) {
log.error("Exception getting user",e);
} catch(LoginException e) {
log.error("Exception getting resolver",e);
}
return null;
}
/**
* Gets the list of all authors by querying all articles (as opposed to members of the news author group
* @return An {@link java.util.ArrayList} of {@link Author Authors}, may be empty (indicates an error)
*/
public List<Author> getAuthorsList() {
//the paths list we will build along the way, which will eventually be resolved into the resources at that location and converted to author objects
List<String> authorPaths = new ArrayList<String>();
//we'll return this list
List<Author> authorList = new ArrayList<Author>();
Date start = new Date();
//we only want authors with stories
// String query = "SELECT DISTINCT user.* from [rep:User] AS user "
// + "INNER JOIN [cq:Page] AS story "
// + "ON user.[rep:authorizableId] = story.[jcr:content/author] "
// + "WHERE isdescendantnode(story,[" + settings.getArticlesPath() + "])
// + order by user.[rep:authorizableId]";
//that ^^^^ query works but takes a long time
//get all the stories
String cacheID = "NEWS-AUTHORS";
String serviceName = "authorslist";
boolean hasCache = false;
try {
hasCache = cachingService.hasFreshCache(serviceName,cacheID);
} catch (LoginException e) {
//issue with caching service, will try without cache
}
try(ResourceResolver resourceResolver = rrf.getServiceResourceResolver(NewsConstants.getReadAuthInfo())) {
if(hasCache) {
//check the cache first for a fresh copy, this cache is cleared regularly, so no need to check freshness
log.debug("getting author list from cache");
Node cachedNode = cachingService.getCachedNode(serviceName,cacheID,resourceResolver);
String authors = cachingService.getNodeData(cachedNode);
authorPaths = Arrays.asList(authors.split(","));
log.debug("end cache:" + ((new Date()).getTime() - start.getTime()));
}
if(!hasCache) {
//select the authors from stories where we aren't using a display author--aka, it's an author based on a user
String statement = "SELECT story.[jcr:content/author] AS author FROM [cq:Page] AS story " +
" WHERE ISDESCENDANTNODE(story,[" + settings.getArticlesPath() + "]) " +
" AND story.[jcr:content/sling:resourceType] LIKE '%storyTemplates%' " +
" AND (story.[jcr:content/useDisplayAuthor] IS NULL OR story.[jcr:content/useDisplayAuthor] = false) " +
" order by story.[jcr:content/author]";
log.debug(statement);
Session session = resourceResolver.adaptTo(Session.class);
QueryManager queryManager = session.getWorkspace().getQueryManager();
UserManager userManager = resourceResolver.adaptTo(UserManager.class);
Query query = queryManager.createQuery(statement,Query.JCR_SQL2);
QueryResult result = query.execute();
RowIterator ri = result.getRows();
while(ri.hasNext()) {
Row row = ri.nextRow();
if(row.getValue("author") == null) {
continue;
}
String lookupAuthorName = row.getValue("author").getString();
Authorizable a = userManager.getAuthorizable(lookupAuthorName);
//only add distinct entries
if(a != null) {
if(!authorPaths.contains(a.getPath())) {
authorPaths.add(a.getPath());
}
} else {
//a is null, try to adapt from a userinfo node
String userInfoAuthorPath = settings.getInfoNodePath() + "/userinfo/" + lookupAuthorName;
if(resourceResolver.getResource(userInfoAuthorPath) != null) {
if(!authorPaths.contains(userInfoAuthorPath)) {
authorPaths.add(userInfoAuthorPath);
}
}
}
}
//select the authors from where we're using a display author but not a custom one -- aka its an author based on a user, not a custom display author. we do this check just in case someone on this list is not in the first list (aka they are a display author but have not authored any stroes on their own. we filter out stories where search display authors = settings.getArticlesPath so that we don't duplicate entries
statement = "SELECT story.[jcr:content/searchDisplayAuthor] as searchAuthor FROM [cq:Page] AS story " +
" WHERE ISDESCENDANTNODE(story,[" + settings.getArticlesPath() + "]) " +
" AND story.[jcr:content/sling:resourceType] LIKE '%storyTemplates%' " +
" AND (story.[jcr:content/useDisplayAuthor] = true " +
" AND (" +
" story.[jcr:content/searchDisplayAuthor] IS NOT NULL " +
" AND story.[jcr:content/searchDisplayAuthor] <> 'custom' " +
" AND NOT(story.[jcr:content/searchDisplayAuthor] LIKE '%" + settings.getArticlesPath() + "%') " +
" ) " +
" ) " +
" order by story.[jcr:content/author] ";
query = queryManager.createQuery(statement,Query.JCR_SQL2);
result = query.execute();
ri = result.getRows();
while(ri.hasNext()) {
Row row = ri.nextRow();
if(row.getValue("searchAuthor") == null) {
continue;
}
String lookupAuthorName = row.getValue("searchAuthor").getString();
Authorizable a = userManager.getAuthorizable(lookupAuthorName);
//only add distinct entries
if(a != null && !authorPaths.contains(a.getPath())) {
authorPaths.add(a.getPath());
}
}
//select the authors from stories where we're using a custom display author
statement = "SELECT story.* FROM [cq:Page] AS story " +
" WHERE ISDESCENDANTNODE(story,[" + settings.getArticlesPath() + "]) " +
" AND story.[jcr:content/sling:resourceType] LIKE '%storyTemplates%' " +
" AND ( " +
" story.[jcr:content/useDisplayAuthor] = true " +
" AND story.[jcr:content/searchDisplayAuthor] = 'custom' " +
" ) " +
" order by story.[jcr:content/author]";
query = queryManager.createQuery(statement,Query.JCR_SQL2);
result = query.execute();
ri = result.getRows();
while(ri.hasNext()) {
Row row = ri.nextRow();
String lookupPath = row.getPath() + "/jcr:content/displayAuthor";
if(resourceResolver.getResource(lookupPath) != null && !authorPaths.contains(lookupPath)) {
authorPaths.add(lookupPath);
}
}
}
//now we have a list of paths, return the actual authors (convert paths to Authors)
Iterator<String> authorPathsIterator = authorPaths.iterator();
while(authorPathsIterator.hasNext()) {
String nextPath = authorPathsIterator.next();
log.debug(nextPath);
//if the path isn't a path, continue -- probably an author
//record that isn't in the system (not likely to happen)
//TODO: Do we really want to skip?
if(!(nextPath.contains("/home") || nextPath.contains("/content"))) {
continue;
}
Resource authorResource = resourceResolver.getResource(nextPath);
if(authorResource != null) {
Author author = authorResource.adaptTo(Author.class);
if(author != null){
authorList.add(author);
} else {
log.debug("unable to create author from node at " + nextPath);
}
} else {
log.debug("no node at " + nextPath);
}
}
log.debug("end authors:" + ((new Date()).getTime() - start.getTime()));
} catch (LoginException e) {
log.debug("error getting resource resolver",e);
} catch (UnsupportedRepositoryOperationException e) {
log.debug("error getting resource resolver",e);
} catch (ValueFormatException e) {
log.debug("error getting resource resolver",e);
} catch (InvalidQueryException e) {
log.debug("error getting resource resolver",e);
} catch (ItemNotFoundException e) {
log.debug("error getting resource resolver",e);
} catch (RepositoryException e) {
log.debug("error getting resource resolver",e);
}
return authorList;
}
/**
* Check if an author with a given ID is a member of a specified group. Essentially a helper function
* @param id The Id of an Author (usually 6+2)
* @param group The group to see if they are a member
* @param declared If true, only check the containing group. If false, check membership in transitive groups (see {@link Authorizable the member of method on the Authorizable class}
*
* @return true if the user with the specified is a member of the specified group
*/
public boolean authorInGroup(String id, String group, Boolean declared) {
// Get the Service resource resolver
try(ResourceResolver editResourceResolver = rrf.getServiceResourceResolver(NewsConstants.getEditAuthInfo())) {
UserManager um = editResourceResolver.adaptTo(UserManager.class);
//get all the groups they are in (declared or undeclared basd on parameter)
Iterator<Group> ig = declared ? um.getAuthorizable(id).declaredMemberOf(): um.getAuthorizable(id).memberOf();
while(ig.hasNext()) {
String t = ig.next().getID();
if(t.equals(group)) {
editResourceResolver.close();
return true;
}
}
} catch (RepositoryException e) {
log.error("Exception getting user list",e);
} catch (LoginException e) {
log.error("Error getting service resovler: ", e);
}
return false;
}
}