This is an automated email from the ASF dual-hosted git repository.

Cole-Greer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/master by this push:
     new 29dd43fde4 CTR Docs Updates
29dd43fde4 is described below

commit 29dd43fde4e1834c94dcdddbb269f07c104b181f
Author: Cole Greer <[email protected]>
AuthorDate: Mon Jul 20 12:21:58 2026 -0700

    CTR Docs Updates
    
    - Update gremlin-socket-server tests dev for new HTTP format
    - Update gremlin-server security docs
    - Update docs/tinkeradoc-extension to Java 17+
---
 docs/src/dev/developer/for-committers.asciidoc   |  22 +-
 docs/src/reference/gremlin-applications.asciidoc | 263 ++---------------------
 docs/src/reference/gremlin-variants.asciidoc     |   2 +
 docs/tinkeradoc-extension/README.md              |   3 -
 docs/tinkeradoc-extension/pom.xml                |   3 +-
 5 files changed, 25 insertions(+), 268 deletions(-)

diff --git a/docs/src/dev/developer/for-committers.asciidoc 
b/docs/src/dev/developer/for-committers.asciidoc
index c905138353..dd9936a70f 100644
--- a/docs/src/dev/developer/for-committers.asciidoc
+++ b/docs/src/dev/developer/for-committers.asciidoc
@@ -705,23 +705,21 @@ configured by `CucumberOptions` on "*FeatureTest" setups.
 [[gremlin-socket-server-tests]]
 === Gremlin Socket Server Tests
 
-IMPORTANT: 4.0.0-beta.2 Release - Removes websockets. This section will be 
updated as the new HTTP test server falls into place.
-
-`gremlin-socket-server` is an included test server for driver tests which 
require predefined server
+`gremlin-socket-server` is an included HTTP test server for driver tests which 
require predefined server
 behavior. Typically, this is to test scenarios such as the server closing the 
connection or returning
 an error code but other response behavior can be added as needed for tests.
 
-Gremlin socket server uses the request id of incoming messages to determine 
how to respond.
-Request ids are defined in `gremlin-tools/gremlin-socket-server/conf/*.yaml`. 
The server side
-behavior for each request id is implemented in `TestWSGremlinInitializer`.
+Gremlin socket server uses the gremlin string of incoming requests to 
determine how to respond.
+These gremlin strings are defined as constants in `SocketServerConstants`. The 
server side
+behavior for each string is implemented in `TestHttpGremlinHandler`.
 
-To add new server side behavior, define a new request id in the config yaml, 
then add a corresponding
-field in `SocketServerSettings`. In `TestWSGremlinInitializer`, add a new 
block to the if else chain in the
-decode method which matches the request id. Define all server behavior and 
responses in this block.
+To add new server side behavior, define a new gremlin string constant in 
`SocketServerConstants`, then
+add a matching `case` to the switch statement in the `channelRead0` method of 
`TestHttpGremlinHandler`.
+Define all server behavior and responses in this block.
 
-To write the driver test, send a request message to the gremlin socket server 
port as if it were a normal
-gremlin server. Override the request id on the request with one defined in the 
config yaml and gremlin
-socket server will respond according to the defined behavior.
+To write the driver test, send an HTTP request to the gremlin socket server 
port as if it were a normal
+gremlin server, setting the `gremlin` field to one of the strings defined in 
`SocketServerConstants` and
+gremlin socket server will respond according to the defined behavior.
 
 Ensure that the socket server is running during driver tests. By default, a 
docker image for
 `gremlin-socket-server` is built during `mvn install`. The simplest way to use 
the socket server during
diff --git a/docs/src/reference/gremlin-applications.asciidoc 
b/docs/src/reference/gremlin-applications.asciidoc
index b2eb1435e6..1670e7748e 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1315,7 +1315,7 @@ Gremlin Server with the 
<<gremlin-java,`gremlin-driver`>>, set the `credentials`
 when constructing the `Cluster`.
 
 [source,java]
-Cluster cluster = Cluster.build().credentials("stephen", "password")
+Cluster cluster = Cluster.build().auth(Auth.basic("stephen", "password"))
                                  
.enableSsl(true).trustStore("server.jks").create();
 
 If connecting with Gremlin Console, which utilizes `gremlin-driver` for remote 
script execution, use the provided
@@ -1346,7 +1346,7 @@ $ bin/gremlin-server.sh 
conf/gremlin-server-rest-secure.yaml
 Once the server has started, issue a request passing the credentials with an 
`Authentication` header, as described in 
link:http://tools.ietf.org/html/rfc2617#section-2[RFC2617]. Here's a HTTP Basic 
authentication example with cURL:
 
 [source,text]
-curl -X POST --insecure -u stephen:password -d "{\"gremlin\":\"100-1\"}" 
"https://localhost:8182";
+curl -X POST --insecure -u stephen:password -d "{\"gremlin\":\"g.V()\"}" 
"https://localhost:8182";
 
 [[credentials-dsl]]
 ==== Credentials Graph DSL
@@ -1403,7 +1403,6 @@ presence of operations such as:
 
 * reading from a GraphTraversalSource
 * writing to a GraphTraversalSource
-* presence of lambdas in bytecode
 * script execution
 * `VertexProgram` execution (OLAP)
 * removal or modification of `TraversalStrategy` instances
@@ -1439,20 +1438,18 @@ on the requesting user or can seek externally.
 . Apart from passing or denying requests, an `Authorizer` implementation can 
actively modify the request, in particular
 add the `TraversalStrategy` instances mentioned in item 1.
 
-IMPORTANT: This section is written with gremlin bytecode requests in mind. 
Realizing authorization for script requests
-is hardly feasible, because such requests get full access to Gremlin Server's 
execution environment. Although the section
+IMPORTANT: Realizing authorization for Groovy script requests is hardly 
feasible, because such requests get full access
+to Gremlin Server's execution environment. Although the section
 <<script-execution>> explains how the client access to this environment can be 
restricted, it is not possible to deny
 execution of `GraphFactory.open()` or `GraphTraversalSource.getGraph()` 
methods without resorting to TinkerPop
 implementation details (that is, internal API's that can change without 
notice).
 
-IMPORTANT: 4.0.0-beta.2 Release - These authorization mechanisms don't 
currently apply due to the removal of Bytecode.
-
 The three mechanisms for authorization each have their merits in terms of 
simplicity and flexibility. The table below
 gives an overview.
 
 [width="95%",cols="5,2,2,4",options="header"]
 |=========================================================
-|Type (mechanism) |GraphTraversalSources |Groups |Bytecode analysis
+|Type (mechanism) |GraphTraversalSources |Groups |Request analysis
 |Implicit (YAML config or init script) | all accessible |one 
|`withStrategies()`
 |Passive (pass/deny) | selected access |few |hybrid
 |Active (inject) |selected access |many |hybrid
@@ -1477,256 +1474,20 @@ same graph can be reused with different 
`SubgraphStrategies`. Now, authorization
 accessible `GraphTraversalSources` and the authorizer can simply match the 
requested access to a `GraphTraversalSource`
 against the policies applicable to the authenticated user. Like for the active 
authorization solution, other restrictions
 such as read only access can be either applied at authorization time as policy 
in the authorizer itself or at request
-execution time as a result of an applied `Strategy` (denoted as 'hybrid' 
bytecode analysis in the table). A code
-example pursuing the former option is provided in the <<authz-code-example, 
next section>>.
+execution time as a result of an applied `Strategy` (denoted as 'hybrid' 
request analysis in the table).
 
-IMPORTANT: 4.0.0-beta.2 Release - passive and active authorization mechanisms 
are not supported in this beta
-because bytecode has been replaced with GremlinLang.
+IMPORTANT: The passive and active mechanisms described above are not currently 
implemented in 4.0.0-beta.3. They
+previously operated by analyzing Bytecode requests, which has been removed in 
favor of GremlinLang, and the `Authorizer`
+interface does not currently apply authorization logic to GremlinLang 
requests. Only the implicit mechanism (restricting
+`TraversalStrategy` instances configured via `traversalSources`, described 
above) is functional today. Client
+authentication such as HTTP Basic or SigV4 is handled separately through 
driver request interceptors. See
+<<gremlin-drivers-variants, Gremlin Drivers and Variants>>.
 
 NOTE: Gremlin Server is not shipped with `Authorizer` implementations, because 
these would heavily depend on the external
 systems to integrate with, e.g. link:https://ldap.com/directory-servers/[LDAP 
systems] or
 link:https://ranger.apache.org/[Apache Ranger ]. However, third-party 
implementations can be
 offered as <<gremlin-plugins, gremlin plugins>>.
 
-[[authz-code-example]]
-===== Code example
-
-The two java classes below provide an example implementation of the 
`Authorizer` interface; they originate from
-link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/authz[Gremlin
 Server's test package].
-If you copy the files into a project, build them into a jar and add the jar to 
Gremlin Server's CLASSPATH, you can use
-them by adding the following to Gremlin Server's yaml configuration file:
-
-[source, yaml]
-----
-authentication: {
-  authenticator: org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator,
-  config: {
-    credentialsDb: conf/tinkergraph-credentials.properties}}
-authorization: {
-  authorizer: org.yourpackage.AllowListAuthorizer,
-  config: {
-    authorizationAllowList: your/path/allow-list.yaml}}
-----
-
-The `AllowListAuthorizer` supports granting groups of users access to 
statically configured `GraphTraversalSource`
-instances and to the "sandbox", where sandbox means that the group is allowed 
anything unless restricted by Gremlin
-Server's <<script-execution,sandbox>>. For denying mutating steps and OLAP 
operations in bytecode requests, the
-`AllowListAuthorizer` relies on the `ReadOnlyStrategy` and 
`VertexProgramRestrictionStrategy` being present in the
-`GraphTraversalSource`. However, it always denies the use of lambdas in 
bytecode requests unless the user has the
-"sandbox" grant. It uses the `BytecodeHelper.getLambdaLanguage()` method to 
detect these.
-
-The grants to groups of users can be configured in a simple yaml file. In 
addition to the special value "sandbox" for
-a grant for string based requests and lambdas, the special value "anonymous" 
can be used to denote any user.
-
-[source,java]
-----
-package org.yourpackage;
-
-import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
-import 
org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.verification.VertexProgramRestrictionStrategy;
-import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
-import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
-import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
-import org.apache.tinkerpop.gremlin.server.Settings.AuthorizationSettings;
-import org.apache.tinkerpop.gremlin.server.auth.AuthenticatedUser;
-
-import java.util.*;
-
-/**
- * Authorizes a user per request, based on a list that grants access to {@link 
TraversalSource} instances for
- * bytecode requests and to gremlin server's sandbox for string requests and 
lambdas. The {@link
- * AuthorizationSettings}.config must have an authorizationAllowList entry 
that contains the name of a YAML file.
- * This authorizer is for demonstration purposes only. It does not scale well 
in the number of users regarding
- * memory usage and administrative burden.
- */
-public class AllowListAuthorizer implements Authorizer {
-
-    public static final String SANDBOX = "sandbox";
-    public static final String REJECT_BYTECODE = "User not authorized for 
bytecode requests on %s";
-    public static final String REJECT_LAMBDA = "lambdas";
-    public static final String REJECT_MUTATE = "the ReadOnlyStrategy";
-    public static final String REJECT_OLAP = "the 
VertexProgramRestrictionStrategy";
-    public static final String REJECT_SUBGRAPH = "the SubgraphStrategy";
-    public static final String REJECT_STRING = "User not authorized for 
string-based requests.";
-    public static final String KEY_AUTHORIZATION_ALLOWLIST = 
"authorizationAllowList";
-
-    // Collections derived from the list with allowed users for fast lookups
-    private final Map<String, List<String>> usernamesByTraversalSource = new 
HashMap<>();
-    private final Set<String> usernamesSandbox = new HashSet<>();
-
-    /**
-     * This method is called once upon system startup to initialize the {@code 
AllowListAuthorizer}.
-     */
-    @Override
-    public void setup(final Map<String,Object> config) {
-        AllowList allowList;
-        final String file = (String) config.get(KEY_AUTHORIZATION_ALLOWLIST);
-
-        try {
-            allowList = AllowList.read(file);
-        } catch (Exception e) {
-            throw new IllegalArgumentException(String.format("Failed to read 
list with allowed users from %s", file));
-        }
-        for (Map.Entry<String, List<String>> entry : 
allowList.grants.entrySet()) {
-            if (!entry.getKey().equals(SANDBOX)) {
-                usernamesByTraversalSource.put(entry.getKey(), new 
ArrayList<>());
-            }
-            for (final String group : entry.getValue()) {
-                if (allowList.groups.get(group) == null) {
-                    throw new RuntimeException(String.format("Group '%s' not 
defined in file with allowed users.", group));
-                }
-                if (entry.getKey().equals(SANDBOX)) {
-                    usernamesSandbox.addAll(allowList.groups.get(group));
-                } else {
-                    
usernamesByTraversalSource.get(entry.getKey()).addAll(allowList.groups.get(group));
-                }
-            }
-        }
-    }
-
-    /**
-     * Checks whether a user is authorized to have a gremlin bytecode request 
from a client answered and raises an
-     * {@link AuthorizationException} if this is not the case. For a request 
to be authorized, the user must either
-     * have a grant for the requested {@link TraversalSource}, without using 
lambdas, mutating steps or OLAP, or have a
-     * sandbox grant.
-     *
-     * @param user {@link AuthenticatedUser} that needs authorization.
-     * @param bytecode The gremlin {@link Bytecode} request to authorize the 
user for.
-     * @param aliases A {@link Map} with a single key/value pair that maps the 
name of the {@link TraversalSource} in the
-     *                {@link Bytecode} request to name of one configured in 
Gremlin Server.
-     * @return The original or modified {@link Bytecode} to be used for 
further processing.
-     */
-    @Override
-    public Bytecode authorize(final AuthenticatedUser user, final Bytecode 
bytecode, final Map<String, String> aliases) throws AuthorizationException {
-        final Set<String> usernames = new HashSet<>();
-
-        for (final String resource: aliases.values()) {
-            usernames.addAll(usernamesByTraversalSource.get(resource));
-        }
-        final boolean userHasTraversalSourceGrant = 
usernames.contains(user.getName()) || 
usernames.contains(AuthenticatedUser.ANONYMOUS_USERNAME);
-        final boolean userHasSandboxGrant = 
usernamesSandbox.contains(user.getName()) || 
usernamesSandbox.contains(AuthenticatedUser.ANONYMOUS_USERNAME);
-        final boolean runsLambda = 
BytecodeHelper.getLambdaLanguage(bytecode).isPresent();
-        final boolean touchesReadOnlyStrategy = 
bytecode.toString().contains(ReadOnlyStrategy.class.getSimpleName());
-        final boolean touchesOLAPRestriction = 
bytecode.toString().contains(VertexProgramRestrictionStrategy.class.getSimpleName());
-        // This element becomes obsolete after resolving TINKERPOP-2473 for 
allowing only a single instance of each traversal strategy.
-        final boolean touchesSubgraphStrategy = 
bytecode.toString().contains(SubgraphStrategy.class.getSimpleName());
-
-        final List<String> rejections = new ArrayList<>();
-        if (runsLambda) {
-            rejections.add(REJECT_LAMBDA);
-        }
-        if (touchesReadOnlyStrategy) {
-            rejections.add(REJECT_MUTATE);
-        }
-        if (touchesOLAPRestriction) {
-            rejections.add(REJECT_OLAP);
-        }
-        if (touchesSubgraphStrategy) {
-            rejections.add(REJECT_SUBGRAPH);
-        }
-        String rejectMessage = REJECT_BYTECODE;
-        if (rejections.size() > 0) {
-            rejectMessage += " using " + String.join(", ", rejections);
-        }
-        rejectMessage += ".";
-
-        if ( (!userHasTraversalSourceGrant || runsLambda || 
touchesOLAPRestriction || touchesReadOnlyStrategy || touchesSubgraphStrategy) 
&& !userHasSandboxGrant) {
-            throw new AuthorizationException(String.format(rejectMessage, 
aliases.values()));
-        }
-        return bytecode;
-    }
-
-    /**
-     * Checks whether a user is authorized to have a script request from a 
gremlin client answered and raises an
-     * {@link AuthorizationException} if this is not the case.
-     *
-     * @param user {@link AuthenticatedUser} that needs authorization.
-     * @param msg {@link RequestMessage} in which the {@link 
org.apache.tinkerpop.gremlin.util.Tokens}.ARGS_GREMLIN argument can contain an 
arbitrary succession of script statements.
-     */
-    public void authorize(final AuthenticatedUser user, final RequestMessage 
msg) throws AuthorizationException {
-        if (!usernamesSandbox.contains(user.getName())) {
-            throw new AuthorizationException(REJECT_STRING);
-        }
-    }
-}
-----
-
-[source,java]
-----
-package org.yourpackage;
-
-import org.yaml.snakeyaml.TypeDescription;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-/**
- * AllowList for the AllowListAuthorizer as configured by a YAML file.
- */
-public class AllowList {
-
-    /**
-     * Holds lists of groups by grant. A grant is either a TraversalSource 
name or the "sandbox" value. With the
-     * sandbox grant users can access all TraversalSource instances and 
execute groovy scripts as string based
-     * requests or as lambda functions, only limited by Gremlin Server's 
sandbox definition.
-     */
-    public Map<String, List<String>> grants;
-
-    /**
-     * Holds lists of user names by groupname. The "anonymous" user name can 
be used to denote any user.
-     */
-    public Map<String, List<String>> groups;
-
-    /**
-     * Read a configuration from a YAML file into an {@link AllowList} object.
-     *
-     * @param file the location of a AllowList YAML configuration file
-     * @return An {@link Optional} object wrapping the created {@link 
AllowList}
-     */
-    public static AllowList read(final String file) throws Exception {
-        final InputStream stream = new FileInputStream(new File(file));
-
-        final Constructor constructor = new Constructor(AllowList.class);
-        final TypeDescription allowListDescription = new 
TypeDescription(AllowList.class);
-        allowListDescription.putMapPropertyType("grants", String.class, 
Object.class);
-        allowListDescription.putMapPropertyType("groups", String.class, 
Object.class);
-        constructor.addTypeDescription(allowListDescription);
-
-        final Yaml yaml = new Yaml(constructor);
-        return yaml.loadAs(stream, AllowList.class);
-    }
-}
-----
-
-
-allow-list.yaml:
-[source,yaml]
-----
-grants: {
-gclassic: [groupclassic],
-gmodern: [groupmodern],
-gcrew: [groupclassic, groupmodern],
-ggrateful: [groupgrateful],
-sandbox: [groupsandbox]
-}
-
-groups: {
-groupclassic: [userclassic],
-groupmodern: [usermodern, stephen],
-groupsink: [usersink],
-groupgrateful: [anonymous],
-groupsandbox: [usersandbox, marko]
-}
-----
-
-
 [[script-execution]]
 ==== Protecting Groovy Script Execution
 
diff --git a/docs/src/reference/gremlin-variants.asciidoc 
b/docs/src/reference/gremlin-variants.asciidoc
index 885e4866c4..c853aacb67 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -1266,6 +1266,8 @@ Gremlin Server roughly uses this same approach when it 
configures its serializer
 ensure compatibility when making requests.
 
 [[gremlin-java-streaming]]
+==== Streaming Deserialization
+
 The driver streams and deserializes a response incrementally as it arrives 
only when `GraphBinaryMessageSerializerV4`
 is configured, which is the default. Any other `MessageSerializer`, such as a 
GraphSON serializer, causes the driver to
 buffer the full response body before deserializing it.
diff --git a/docs/tinkeradoc-extension/README.md 
b/docs/tinkeradoc-extension/README.md
index 6903e2bfe7..d0e685b318 100644
--- a/docs/tinkeradoc-extension/README.md
+++ b/docs/tinkeradoc-extension/README.md
@@ -70,9 +70,6 @@ even though the code now lives in 
`org.apache.tinkerpop.tinkeradoc`.
 
     mvn clean install -f docs/tinkeradoc-extension/pom.xml
 
-Requires Java 11 or later, as AsciidoctorJ 2.5.x does. `asciidoctorj` is a 
`provided` dependency because the
-`asciidoctor-maven-plugin` supplies it at documentation build time.
-
 ## Generating the Docs
 
 Do not invoke this project directly to build documentation. 
`bin/process-docs.sh` is the entrypoint: it validates the
diff --git a/docs/tinkeradoc-extension/pom.xml 
b/docs/tinkeradoc-extension/pom.xml
index ee4a6491b2..d095d8b994 100644
--- a/docs/tinkeradoc-extension/pom.xml
+++ b/docs/tinkeradoc-extension/pom.xml
@@ -62,8 +62,7 @@ limitations under the License.
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>3.14.0</version>
                 <configuration>
-                    <!-- AsciidoctorJ 2.5.x requires Java 11+ -->
-                    <release>11</release>
+                    <release>17</release>
                 </configuration>
             </plugin>
             <plugin>

Reply via email to