summaryrefslogtreecommitdiff
path: root/buildscripts/idl/idl
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2021-03-01 15:28:37 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-02 01:01:01 +0000
commit5bc18e5edf382187c421ae23a5707a3207ef3204 (patch)
tree22f86edb736ad252a1044ca64fc4d7d2904a9216 /buildscripts/idl/idl
parent8c248bf16a781bd096f1829ab61bed9f5655ad41 (diff)
downloadmongo-5bc18e5edf382187c421ae23a5707a3207ef3204.tar.gz
SERVER-54520 Extend IDL for new access_check field and none value and generate code when api_version != “”
Diffstat (limited to 'buildscripts/idl/idl')
-rw-r--r--buildscripts/idl/idl/ast.py11
-rw-r--r--buildscripts/idl/idl/binder.py18
-rw-r--r--buildscripts/idl/idl/generator.py10
-rw-r--r--buildscripts/idl/idl/parser.py22
-rw-r--r--buildscripts/idl/idl/syntax.py13
5 files changed, 70 insertions, 4 deletions
diff --git a/buildscripts/idl/idl/ast.py b/buildscripts/idl/idl/ast.py
index 3b5e5e3d122..aa7e6a88ae1 100644
--- a/buildscripts/idl/idl/ast.py
+++ b/buildscripts/idl/idl/ast.py
@@ -225,6 +225,16 @@ class Field(common.SourceLocation):
super(Field, self).__init__(file_name, line, column)
+class AccessCheck(common.SourceLocation):
+ """IDL commmand access check information."""
+
+ def __init__(self, file_name, line, column):
+ # type: (str, int, int) -> None
+ """Construct an AccessCheck."""
+ self.placeholder = None # type: str
+ super(AccessCheck, self).__init__(file_name, line, column)
+
+
class Command(Struct):
"""
IDL commmand information.
@@ -244,6 +254,7 @@ class Command(Struct):
self.reply_type = None # type: Field
self.api_version = "" # type: str
self.is_deprecated = False # type: bool
+ self.access_checks = None # type: List[AccessCheck]
super(Command, self).__init__(file_name, line, column)
diff --git a/buildscripts/idl/idl/binder.py b/buildscripts/idl/idl/binder.py
index 582c63128cb..3ae92799d1c 100644
--- a/buildscripts/idl/idl/binder.py
+++ b/buildscripts/idl/idl/binder.py
@@ -31,7 +31,7 @@
import collections
import re
import typing
-from typing import Type, TypeVar, cast, List, Set, Union
+from typing import Type, TypeVar, cast, List, Set, Union, Optional
from . import ast
from . import bson
@@ -549,6 +549,20 @@ def _bind_command_reply_type(ctxt, parsed_spec, command):
return ast_field
+def _bind_access_check(command):
+ # type: (syntax.Command) -> Optional[List[ast.AccessCheck]]
+ """Bind the access_check field in a command."""
+ if not command.access_check:
+ return None
+
+ access_check = command.access_check
+
+ if access_check.none:
+ return []
+
+ return None
+
+
def _bind_command(ctxt, parsed_spec, command):
# type: (errors.ParserContext, syntax.IDLSpec, syntax.Command) -> ast.Command
"""
@@ -569,6 +583,8 @@ def _bind_command(ctxt, parsed_spec, command):
_bind_struct_common(ctxt, parsed_spec, command, ast_command)
+ ast_command.access_checks = _bind_access_check(command)
+
ast_command.namespace = command.namespace
if command.type:
diff --git a/buildscripts/idl/idl/generator.py b/buildscripts/idl/idl/generator.py
index b3b2d08fdf0..08aa024ee43 100644
--- a/buildscripts/idl/idl/generator.py
+++ b/buildscripts/idl/idl/generator.py
@@ -971,8 +971,8 @@ class _CppHeaderFileWriter(_CppFileWriterBase):
with self._block('%s {' % (fn_def), '}'):
self._writer.write_line('return %s;' % value)
- def gen_invocation_base_class_declaration(self):
- # type: () -> None
+ def gen_invocation_base_class_declaration(self, command):
+ # type: (ast.Command) -> None
"""Generate the InvocationBaseGen class for a command's base class."""
class_declaration = 'class InvocationBaseGen : public _TypedCommandInvocationBase {'
with writer.IndentedScopedBlock(self._writer, class_declaration, '};'):
@@ -987,6 +987,10 @@ class _CppHeaderFileWriter(_CppFileWriterBase):
self._writer.write_line('virtual Reply typedRun(OperationContext* opCtx) = 0;')
+ if command.access_checks == []:
+ self._writer.write_line(
+ 'void doCheckAuthorization(OperationContext* opCtx) const final {}')
+
def generate_versioned_command_base_class(self, command):
# type: (ast.Command) -> None
"""Generate a command's C++ base class to a stream."""
@@ -1028,7 +1032,7 @@ class _CppHeaderFileWriter(_CppFileWriterBase):
self.gen_api_version_fn(False, command.is_deprecated)
# Write InvocationBaseGen class.
- self.gen_invocation_base_class_declaration()
+ self.gen_invocation_base_class_declaration(command)
def generate(self, spec):
# type: (ast.IDLAST) -> None
diff --git a/buildscripts/idl/idl/parser.py b/buildscripts/idl/idl/parser.py
index ccc07d1b27f..eb09b454450 100644
--- a/buildscripts/idl/idl/parser.py
+++ b/buildscripts/idl/idl/parser.py
@@ -682,6 +682,27 @@ def _parse_enum(ctxt, spec, name, node):
spec.symbols.add_enum(ctxt, idl_enum)
+def _parse_access_checks(ctxt, node):
+ # type: (errors.ParserContext, yaml.nodes.MappingNode) -> syntax.AccessChecks
+ """Parse an access check section in a struct in the IDL file."""
+
+ access_checks = None
+
+ if not ctxt.is_mapping_node(node, "access_check"):
+ return None
+
+ access_checks = syntax.AccessChecks(ctxt.file_name, node.start_mark.line,
+ node.start_mark.column)
+
+ _generic_parser(ctxt, node, "access_check", access_checks, {
+ "none": _RuleDesc('bool_scalar'),
+ })
+
+ # TODO(SERVER-54522) TODO(SERVER-54523) - validate only one of none, simple or complex is set
+
+ return access_checks
+
+
def _parse_command(ctxt, spec, name, node):
# type: (errors.ParserContext, syntax.IDLSpec, str, Union[yaml.nodes.MappingNode, yaml.nodes.ScalarNode, yaml.nodes.SequenceNode]) -> None
"""Parse a command section in the IDL file."""
@@ -714,6 +735,7 @@ def _parse_command(ctxt, spec, name, node):
"generate_comparison_operators": _RuleDesc("bool_scalar"),
"allow_global_collection_name": _RuleDesc('bool_scalar'),
"non_const_getter": _RuleDesc('bool_scalar'),
+ "access_check": _RuleDesc('mapping', mapping_parser_func=_parse_access_checks),
})
valid_commands = [
diff --git a/buildscripts/idl/idl/syntax.py b/buildscripts/idl/idl/syntax.py
index 092bbd7228a..f6d973a442d 100644
--- a/buildscripts/idl/idl/syntax.py
+++ b/buildscripts/idl/idl/syntax.py
@@ -549,6 +549,18 @@ class Struct(common.SourceLocation):
super(Struct, self).__init__(file_name, line, column)
+class AccessChecks(common.SourceLocation):
+ """IDL access checks information."""
+
+ def __init__(self, file_name, line, column):
+ # type: (str, int, int) -> None
+ """Construct an AccessChecks."""
+
+ self.none = None # type: bool
+
+ super(AccessChecks, self).__init__(file_name, line, column)
+
+
class Command(Struct):
"""
IDL command information, a subtype of Struct.
@@ -568,6 +580,7 @@ class Command(Struct):
self.reply_type = None # type: str
self.api_version = None # type: str
self.is_deprecated = False # type: bool
+ self.access_check = None # type: AccessChecks
super(Command, self).__init__(file_name, line, column)