You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2018/04/19 16:42:43 UTC

[1/2] tinkerpop git commit: TINKERPOP-1903 Migrated Credential DSL to annotation processor

Repository: tinkerpop
Updated Branches:
  refs/heads/tp33 6aa5f2ee3 -> 38b85d2f0


TINKERPOP-1903 Migrated Credential DSL to annotation processor

The old CredentialGraph approach to the Credential DSL has been deprecated in favor of the preferred method for DSL development which was published long after the original DSL was developed.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/bad59e50
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/bad59e50
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/bad59e50

Branch: refs/heads/tp33
Commit: bad59e50256604939394ec1bace299587db24422
Parents: d63638b
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Apr 5 11:51:49 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Mon Apr 16 08:26:11 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../src/reference/gremlin-applications.asciidoc |  31 ++--
 docs/src/upgrade/release-3.3.x.asciidoc         |  27 ++++
 .../jsr223/dsl/credential/CredentialGraph.java  |   2 +
 .../CredentialGraphGremlinPlugin.java           |   6 +-
 .../dsl/credential/CredentialTraversalDsl.java  |  74 ++++++++++
 .../CredentialTraversalSourceDsl.java           |  79 ++++++++++
 .../dsl/credential/CredentialGraphTest.java     |   4 +
 .../credential/CredentialTraversalDslTest.java  | 143 +++++++++++++++++++
 9 files changed, 354 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index a3512ec..45ac72c 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 This release also includes changes from <<release-3-2-9, 3.2.9>>.
 
 * Coerced `BulkSet` to `g:List` in GraphSON 3.0.
+* Deprecated `CredentialsGraph` DSL in favor of `CredentialsTraversalDsl` which uses the recommended method for Gremlin DSL development.
 
 [[release-3-3-2]]
 === TinkerPop 3.3.2 (Release Date: April 2, 2018)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 53a1642..f87499d 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1351,9 +1351,9 @@ the `Graph`, consider specifying a unique constraint as well.
 
 To aid with the management of a credentials graph, Gremlin Server provides a Gremlin Console plugin which can be
 used to add and remove users so as to ensure that the schema is adhered to, thus ensuring compatibility with Gremlin
- Server.  In addition, as it is a plugin, it works naturally in the Gremlin Console as an extension of its
- capabilities (though one could use it programmatically, if desired).  This plugin is distributed with the Gremlin
- Console so it does not have to be "installed".  It does however need to be activated:
+Server. In addition, as it is a plugin, it works naturally in the Gremlin Console as an extension of its
+capabilities (though one could use it programmatically, if desired). This plugin is distributed with the Gremlin
+Console so it does not have to be "installed". It does however need to be activated:
 
 [source,groovy]
 gremlin> :plugin use tinkerpop.credentials
@@ -1365,15 +1365,22 @@ Please see the example usage as follows:
 ----
 graph = TinkerGraph.open()
 graph.createIndex("username",Vertex.class)
-credentials = credentials(graph)
-credentials.createUser("stephen","password")
-credentials.createUser("daniel","better-password")
-credentials.createUser("marko","rainbow-dash")
-credentials.findUser("marko").properties()
-credentials.countUsers()
-credentials.removeUser("daniel")
-credentials.countUsers()
-----
+credentials = graph.traversal(CredentialTraversalSource.class)
+credentials.user("stephen","password")
+credentials.user("daniel","better-password")
+credentials.user("marko","rainbow-dash")
+credentials.users("marko").valueMap()
+credentials.users().count()
+credentials.users("daniel").drop()
+credentials.users().count()
+----
+
+NOTE: The Credentials DSL is built using TinkerPop's DSL Annotation Processor described <<gremlin-java-dsl,here>>.
+
+IMPORTANT: In the above example, an empty in-memory TinkerGraph was used for demonstrating the API of the DSL.
+Obviously, this data will not be retained and usable with Gremlin Server. It would be important to configure
+TinkerGraph to persist that data or to manually persist it (e.g. write the graph data to Gryo) once changes are
+complete. Alternatively, use a persistent graph to hold the credentials and configure Gremlin Server accordingly.
 
 [[krb5authenticator]]
 ===== Kerberos Authentication

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/docs/src/upgrade/release-3.3.x.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.3.x.asciidoc b/docs/src/upgrade/release-3.3.x.asciidoc
index 9ff7b4d..79b7ef5 100644
--- a/docs/src/upgrade/release-3.3.x.asciidoc
+++ b/docs/src/upgrade/release-3.3.x.asciidoc
@@ -23,6 +23,33 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 
 == TinkerPop 3.3.2
 
+*Release Date: NOT OFFICIALLY RELEASED YET*
+
+Please see the link:https://github.com/apache/tinkerpop/blob/3.3.3/CHANGELOG.asciidoc#release-3-3-3[changelog] for a complete list of all the modifications that are part of this release.
+
+=== Upgrading for Users
+
+==== Credential DSL Changes
+
+The Credential DSL has been modified to work as a standard Java-based Gremlin DSL. The now deprecated old approach
+used a "graph wrapping" style that was developed long before the
+link:http://tinkerpop.apache.org/docs/current/reference/#gremlin-java-dsl[recommended method] for building DSLs was
+published. Under this new model, the DSL is initialized via traversal as follows:
+
+[source,java]
+----
+CredentialTraversalSource credentials = graph.traversal(CredentialTraversalSource.class)
+credentials.user("stephen","password").iterate()
+credentials.users("stephen").valueMap().next()
+credentials.users().count().next()
+credentials.users("stephen").drop().iterate()
+----
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1903[TINKERPOP-1903],
+link:http://tinkerpop.apache.org/docs/3.3.2/reference/#security[Reference Documentation - Security]
+
+== TinkerPop 3.3.2
+
 *Release Date: April 2, 2018*
 
 Please see the link:https://github.com/apache/tinkerpop/blob/3.3.2/CHANGELOG.asciidoc#release-3-3-2[changelog] for a complete list of all the modifications that are part of this release.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
index 9220282..0ae8e00 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
@@ -32,7 +32,9 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.drop;
  * {@link Graph} is transactional, new transactions will be started for each method call.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @deprecated As of release 3.3.3, replaced by {@link  CredentialTraversalDsl}.
  */
+@Deprecated
 public class CredentialGraph {
 
     private final int BCRYPT_ROUNDS = 4;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
index 7b6bd64..e36dff9 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
@@ -24,7 +24,8 @@ import org.apache.tinkerpop.gremlin.jsr223.ImportCustomizer;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 
 /**
- * Plugin for the "credentials graph".  This plugin imports the {@link CredentialGraph} to its environment.
+ * Plugin for the Credentials DSL that helps maintain a list of users and passwords in a graph for use with Gremlin
+ * Server authentication.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
@@ -38,6 +39,9 @@ public class CredentialGraphGremlinPlugin extends AbstractGremlinPlugin {
         try {
             imports = DefaultImportCustomizer.build()
                     .addClassImports(CredentialGraph.class)
+                    .addClassImports(CredentialTraversalDsl.class)
+                    .addClassImports(CredentialTraversal.class)
+                    .addClassImports(CredentialTraversalSource.class)
                     .addMethodImports(CredentialGraph.class.getMethod("credentials", Graph.class))
                     .create();
         } catch (Exception ex) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDsl.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDsl.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDsl.java
new file mode 100644
index 0000000..e94720a
--- /dev/null
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDsl.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.GremlinDsl;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.mindrot.jbcrypt.BCrypt;
+
+import java.util.Arrays;
+
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_PASSWORD;
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_USERNAME;
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.VERTEX_LABEL_USER;
+
+/**
+ * A DSL for managing a "credentials graph" used by Gremlin Server for simple authentication functions.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@GremlinDsl(traversalSource = "org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialTraversalSourceDsl")
+public interface CredentialTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> {
+    static final int BCRYPT_ROUNDS = 4;
+
+    /**
+     * Finds all users.
+     */
+    public default GraphTraversal<S, Vertex> users() {
+        return (CredentialTraversal<S, Vertex>) hasLabel(VERTEX_LABEL_USER);
+    }
+
+    /**
+     * Finds users by name.
+     */
+    public default GraphTraversal<S, Vertex> users(final String username, final String... more) {
+        if (more.length == 0) {
+            return (CredentialTraversal<S, Vertex>) has(VERTEX_LABEL_USER, PROPERTY_USERNAME, username);
+        }
+
+        final int lastIndex;
+        final String[] usernames = Arrays.copyOf(more, (lastIndex = more.length) + 1);
+        usernames[lastIndex] = username;
+        return (CredentialTraversal<S, Vertex>)has(VERTEX_LABEL_USER, PROPERTY_USERNAME, P.within(usernames));
+    }
+
+    /**
+     * Creates or updates a user.
+     */
+    public default GraphTraversal<S, Vertex> user(final String username, final String password) {
+        return has(VERTEX_LABEL_USER, PROPERTY_USERNAME, username).
+               fold().
+               coalesce(__.unfold(),
+                        __.addV(VERTEX_LABEL_USER).property(PROPERTY_USERNAME, username)).
+               property(PROPERTY_PASSWORD, BCrypt.hashpw(password, BCrypt.gensalt(CredentialTraversalDsl.BCRYPT_ROUNDS)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalSourceDsl.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalSourceDsl.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalSourceDsl.java
new file mode 100644
index 0000000..68b24b2
--- /dev/null
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalSourceDsl.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.mindrot.jbcrypt.BCrypt;
+
+import java.util.Arrays;
+
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_PASSWORD;
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_USERNAME;
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.VERTEX_LABEL_USER;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class CredentialTraversalSourceDsl extends GraphTraversalSource {
+    public CredentialTraversalSourceDsl(final Graph graph, final TraversalStrategies traversalStrategies) {
+        super(graph, traversalStrategies);
+    }
+
+    public CredentialTraversalSourceDsl(final Graph graph) {
+        super(graph);
+    }
+
+    /**
+     * Finds all users.
+     */
+    public GraphTraversal<Vertex, Vertex> users() {
+        return this.clone().V().hasLabel(VERTEX_LABEL_USER);
+    }
+
+    /**
+     * Finds users by name.
+     */
+    public GraphTraversal<Vertex, Vertex> users(final String username, final String... more) {
+        if (more.length == 0) {
+            return this.clone().V().has(VERTEX_LABEL_USER, PROPERTY_USERNAME, username);
+        }
+
+        final int lastIndex;
+        final String[] usernames = Arrays.copyOf(more, (lastIndex = more.length) + 1);
+        usernames[lastIndex] = username;
+        return this.clone().V().has(VERTEX_LABEL_USER, PROPERTY_USERNAME, P.within(usernames));
+    }
+
+    /**
+     * Creates or updates a user.
+     */
+    public GraphTraversal<Vertex, Vertex> user(final String username, final String password) {
+        return this.clone().V().
+                has(VERTEX_LABEL_USER, PROPERTY_USERNAME, username).
+                fold().
+                coalesce(__.unfold(),
+                         __.addV(VERTEX_LABEL_USER).property(PROPERTY_USERNAME, username)).
+                property(PROPERTY_PASSWORD, BCrypt.hashpw(password, BCrypt.gensalt(CredentialTraversalDsl.BCRYPT_ROUNDS)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
index 3fef17e..7e054ce 100644
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
@@ -33,8 +33,12 @@ import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
 
 /**
+ * These tests cover old functionality prior to the new method for DSL implementation.
+ *
  * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @deprecated As for release 3.3.3, replaced by {@link CredentialTraversalDslTest}.
  */
+@Deprecated
 public class CredentialGraphTest {
 
     @Test

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDslTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDslTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDslTest.java
new file mode 100644
index 0000000..8c5a6bd
--- /dev/null
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDslTest.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential;
+
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.junit.Test;
+
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_USERNAME;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class CredentialTraversalDslTest {
+
+    @Test
+    public void shouldCreateUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        final Vertex v = g.user("stephen", "secret").next();
+        assertEquals("stephen", v.value("username"));
+        assertEquals("user", v.label());
+        assertNotEquals("secret", v.value("password"));  // hashed to something
+        assertThat(v.value("password").toString().length(), greaterThan(0));
+    }
+
+    @Test
+    public void shouldRemoveUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        g.users("stephen").drop().iterate();
+        assertThat(graph.vertices().hasNext(), is(false));
+    }
+
+    @Test
+    public void shouldNotRemoveUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        g.users("stephanie").drop().iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+    }
+
+    @Test
+    public void shouldFindUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("marko", "secret").iterate();
+        final Vertex stephen = g.user("stephen", "secret").next();
+        g.user("daniel", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        assertEquals(stephen, g.users("stephen").next());
+    }
+
+    @Test
+    public void shouldFindSeveralUsers() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("marko", "secret").iterate();
+        g.user("daniel", "secret").iterate();
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        assertThat(g.users("stephen", "marko").values(PROPERTY_USERNAME).toList(), containsInAnyOrder("stephen", "marko"));
+    }
+
+    @Test
+    public void shouldNotFindUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("marko", "secret").iterate();
+        g.user("daniel", "secret").iterate();
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        assertThat(g.users("stephanie").hasNext(), is(false));
+    }
+
+    @Test
+    public void shouldCountUsers() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("marko", "secret").iterate();
+        g.user("daniel", "secret").iterate();
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        assertEquals(3, g.users().count().next().intValue());
+    }
+
+    @Test
+    public void shouldUpdateUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        final Vertex v = g.user("stephen", "secret").next();
+        assertEquals("stephen", v.value("username"));
+        assertEquals("user", v.label());
+        assertNotEquals("secret", v.value("password"));  // hashed to something
+        assertThat(v.value("password").toString().length(), greaterThan(0));
+
+        final String hashOfSecret = v.value("password").toString();
+
+        g.user("stephen", "new-secret").iterate();
+
+        assertNotEquals(hashOfSecret, g.users("stephen").values("password").next());
+        assertEquals(1, g.users("stephen").count().next().intValue());
+    }
+}


[2/2] tinkerpop git commit: Merge branch 'TINKERPOP-1903' into tp33

Posted by sp...@apache.org.
Merge branch 'TINKERPOP-1903' into tp33


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/38b85d2f
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/38b85d2f
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/38b85d2f

Branch: refs/heads/tp33
Commit: 38b85d2f03c3ea0808a086e38ca51f0b5d74410f
Parents: 6aa5f2e bad59e5
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Apr 19 12:42:04 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Apr 19 12:42:04 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../src/reference/gremlin-applications.asciidoc |  31 ++--
 docs/src/upgrade/release-3.3.x.asciidoc         |  27 ++++
 .../jsr223/dsl/credential/CredentialGraph.java  |   2 +
 .../CredentialGraphGremlinPlugin.java           |   6 +-
 .../dsl/credential/CredentialTraversalDsl.java  |  74 ++++++++++
 .../CredentialTraversalSourceDsl.java           |  79 ++++++++++
 .../dsl/credential/CredentialGraphTest.java     |   4 +
 .../credential/CredentialTraversalDslTest.java  | 143 +++++++++++++++++++
 9 files changed, 354 insertions(+), 13 deletions(-)
----------------------------------------------------------------------