private boolean hasAccess(Field f, Operation op) { EntityAccess eaccess = md.getAccess(); switch (op) { case insert: return getEffAccess(f, INS_ACC, eaccess.getInsert()).hasAccess(roles); case update: return getEffAccess(f, UPD_ACC, eaccess.getUpdate()).hasAccess(roles); case insert_and_update: return getEffAccess(f, INS_ACC, eaccess.getInsert()).hasAccess(roles) && getEffAccess(f, UPD_ACC, eaccess.getUpdate()).hasAccess(roles); case find: return getEffAccess(f, FIND_ACC, eaccess.getFind()).hasAccess(roles); } return false; }
/** * Returns a list of fields in the doc inaccessible to the current user * during insertion. If the returned list is empty, the user can insert the * doc. */ public Set<Path> getInaccessibleFields_Insert(JsonDoc doc) { Set<Path> inaccessibleFields = getInaccessibleFields(Operation.insert); Set<Path> ret = new HashSet<>(inaccessibleFields.size()); for (Path x : inaccessibleFields) { KeyValueCursor<Path, JsonNode> cursor = doc.getAllNodes(x); if (cursor.hasNext()) { ret.add(x); } } return ret; }
/** * Returns whether the current caller has access to all the given fields * based on the operation */ public boolean hasAccess(Set<Path> fields, Operation op) { for (Path x : fields) { if (!hasAccess(x, op)) { return false; } } return true; }
/** * Returns a list of fields in the doc inaccessible to the current user * during update. * * @param newDoc The new version of the document * @param oldDoc The old version of the document */ public List<Path> getInaccessibleFields_Update(JsonDoc newDoc, JsonDoc oldDoc) { Set<Path> inaccessibleFields = getInaccessibleFields(Operation.update); List<Path> ret = new ArrayList<>(inaccessibleFields.size()); for (Path x : inaccessibleFields) { KeyValueCursor<Path, JsonNode> oldCursor = oldDoc.getAllNodes(x); KeyValueCursor<Path, JsonNode> newCursor = newDoc.getAllNodes(x); if (different(oldCursor, newCursor)) { ret.add(x); } } return ret; }
DocTranslator translator = new DocTranslator(ctx, ctx.getFactory().getNodeFactory()); try { FieldAccessRoleEvaluator roleEval = new FieldAccessRoleEvaluator(ctx.getEntityMetadata(ctx.getEntityName()), ctx.getCallerRoles()); LOGGER.debug("saveOrInsert: Translating docs"); DBCollection collection = db.getCollection(store.getCollectionName()); Projection combinedProjection = Projection.add(projection, roleEval.getExcludedFields(FieldAccessRoleEvaluator.Operation.find));
/** * Checks if the caller has access to all the query fields. Returns false if * not, and sets the error status in ctx */ private boolean checkQueryAccess(OperationContext ctx, QueryExpression query) { boolean ret = true; if (query != null) { CompositeMetadata md = ctx.getTopLevelEntityMetadata(); FieldAccessRoleEvaluator eval = new FieldAccessRoleEvaluator(md, ctx.getCallerRoles()); AnalyzeQuery analyzer=new AnalyzeQuery(md,null); analyzer.iterate(query,Path.EMPTY); List<QueryFieldInfo> fields=analyzer.getFieldInfo(); LOGGER.debug("Checking access for query fields {}", fields); for (QueryFieldInfo field : fields) { LOGGER.debug("Access checking field {}", field.getFullFieldName()); if (eval.hasAccess(field.getFullFieldName(), FieldAccessRoleEvaluator.Operation.find)) { LOGGER.debug("Field {} is readable", field.getFullFieldName()); } else { LOGGER.debug("Field {} is not readable", field.getFullFieldName()); ctx.addError(Error.get(CrudConstants.ERR_NO_ACCESS, field.getFullFieldName().toString())); ctx.setStatus(OperationStatus.ERROR); ret = false; } } } return ret; }
private boolean accessCheck(DocCtx doc, Measure measure) { measure.begin("accessCheck"); Set<Path> paths = roleEval.getInaccessibleFields_Update(doc, doc.getOriginalDocument()); measure.end("accessCheck"); LOGGER.debug("Inaccesible fields during update={}" + paths); if (paths != null && !paths.isEmpty()) { doc.addError(Error.get("update", CrudConstants.ERR_NO_FIELD_UPDATE_ACCESS, paths.toString())); return true; } return false; }
try { EntityMetadata md = ctx.getEntityMetadata(ctx.getEntityName()); FieldAccessRoleEvaluator roleEval = new FieldAccessRoleEvaluator(md, ctx.getCallerRoles()); LOGGER.debug("Translating query {}", query); DBObject mongoQuery = xtranslator.translate(md, ExpressionTranslator.appendObjectType(query,ctx.getEntityName()));
List<DocInfo> insertionAttemptList = new ArrayList<>(list.size()); for (DocInfo doc : list) { Set<Path> paths = roleEval.getInaccessibleFields_Insert(doc.inputDoc); LOGGER.debug("Inaccessible fields:{}", paths); if (paths == null || paths.isEmpty()) {
Translator translator = new Translator(ctx, ctx.getFactory().getNodeFactory()); try { FieldAccessRoleEvaluator roleEval = new FieldAccessRoleEvaluator(ctx.getEntityMetadata(ctx.getEntityName()), ctx.getCallerRoles()); LOGGER.debug("saveOrInsert: Translating docs"); DBCollection collection = db.getCollection(store.getCollectionName()); Projection combinedProjection = Projection.add(projection, roleEval.getExcludedFields(FieldAccessRoleEvaluator.Operation.find));
/** * Checks if the caller has access to all the query fields. Returns false if * not, and sets the error status in ctx */ private boolean checkQueryAccess(OperationContext ctx, QueryExpression query) { boolean ret = true; if (query != null) { CompositeMetadata md = ctx.getTopLevelEntityMetadata(); FieldAccessRoleEvaluator eval = new FieldAccessRoleEvaluator(md, ctx.getCallerRoles()); AnalyzeQuery analyzer=new AnalyzeQuery(md,null); analyzer.iterate(query,Path.EMPTY); List<QueryFieldInfo> fields=analyzer.getFieldInfo(); LOGGER.debug("Checking access for query fields {}", fields); for (QueryFieldInfo field : fields) { LOGGER.debug("Access checking field {}", field.getFullFieldName()); if (eval.hasAccess(field.getFullFieldName(), FieldAccessRoleEvaluator.Operation.find)) { LOGGER.debug("Field {} is readable", field.getFullFieldName()); } else { LOGGER.debug("Field {} is not readable", field.getFullFieldName()); ctx.addError(Error.get(CrudConstants.ERR_NO_ACCESS, field.getFullFieldName().toString())); ctx.setStatus(OperationStatus.ERROR); ret = false; } } } return ret; }
DocTranslator.TranslatedDoc oldDoc = translator.toJson(doc.oldDoc); doc.inputDoc.setOriginalDocument(oldDoc.doc); Set<Path> paths = roleEval.getInaccessibleFields_Update(doc.inputDoc, oldDoc.doc); if (paths == null || paths.isEmpty()) { try {
"insert:" + md.getName())); } else { List<Path> paths = roleEval.getInaccessibleFields_Insert(inputDoc); LOGGER.debug("Inaccessible fields:{}", paths); if (paths == null || paths.isEmpty()) {
EntityMetadata md = ctx.getEntityMetadata(ctx.getEntityName()); if (md.getAccess().getFind().hasAccess(ctx.getCallerRoles())) { FieldAccessRoleEvaluator roleEval = new FieldAccessRoleEvaluator(md, ctx.getCallerRoles()); LOGGER.debug("Translating query {}", query); DBObject mongoQuery = query==null?null:translator.translate(md, query); response.setSize(finder.find(ctx, coll, mongoQuery, mongoProjection, mongoSort, from, to)); Projector projector = Projector.getInstance(Projection.add(projection, roleEval.getExcludedFields(FieldAccessRoleEvaluator.Operation.find)), md); for (DocCtx document : ctx.getDocuments()) { document.setOutputDocument(projector.project(document, ctx.getFactory().getNodeFactory()));
/** * Returns whether the current caller has access to all the given fields * based on the operation */ public boolean hasAccess(Set<Path> fields, Operation op) { for (Path x : fields) { if (!hasAccess(x, op)) { return false; } } return true; }
/** * Returns a list of fields in the doc inaccessible to the current user * during insertion. If the returned list is empty, the user can insert the * doc. */ public Set<Path> getInaccessibleFields_Insert(JsonDoc doc) { Set<Path> inaccessibleFields = getInaccessibleFields(Operation.insert); Set<Path> ret = new HashSet<>(inaccessibleFields.size()); for (Path x : inaccessibleFields) { KeyValueCursor<Path, JsonNode> cursor = doc.getAllNodes(x); if (cursor.hasNext()) { ret.add(x); } } return ret; }
List<Path> paths = roleEval.getInaccessibleFields_Update(doc, doc.getOriginalDocument()); LOGGER.debug("Inaccesible fields during update={}" + paths); if (paths != null && !paths.isEmpty()) {
private boolean hasAccess(Field f, Operation op) { EntityAccess eaccess = md.getAccess(); switch (op) { case insert: return getEffAccess(f, INS_ACC, eaccess.getInsert()).hasAccess(roles); case update: return getEffAccess(f, UPD_ACC, eaccess.getUpdate()).hasAccess(roles); case insert_and_update: return getEffAccess(f, INS_ACC, eaccess.getInsert()).hasAccess(roles) && getEffAccess(f, UPD_ACC, eaccess.getUpdate()).hasAccess(roles); case find: return getEffAccess(f, FIND_ACC, eaccess.getFind()).hasAccess(roles); } return false; }
EntityMetadata md = ctx.getEntityMetadata(ctx.getEntityName()); if (md.getAccess().getFind().hasAccess(ctx.getCallerRoles())) { FieldAccessRoleEvaluator roleEval = new FieldAccessRoleEvaluator(md, ctx.getCallerRoles()); LOGGER.debug("Translating query {}", query); DBObject mongoQuery = xtranslator.translate(md, ExpressionTranslator.appendObjectType(query,ctx.getEntityName())); : Projection.add(projection, roleEval.getExcludedFields(FieldAccessRoleEvaluator.Operation.find)), md); ctx.setDocumentStream(DocumentStream.map(ctx.getDocumentStream(),d->{ ctx.measure.begin("projectFound");
/** * Returns whether the current caller has access to all the given fields * based on the operation */ public boolean hasAccess(Set<Path> fields, Operation op) { for (Path x : fields) { if (!hasAccess(x, op)) { return false; } } return true; }