blob: 0ae8e00a8cfca05418e342c221dccbf71539519c [file] [log] [blame]
/*
* 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.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.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.mindrot.jbcrypt.BCrypt;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.drop;
/**
* A DSL for managing a "credentials graph" used by Gremlin Server for simple authentication functions. If the
* {@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;
private final Graph graph;
private final GraphTraversalSource g;
private final boolean supportsTransactions;
public CredentialGraph(final Graph graph) {
this.graph = graph;
g = graph.traversal();
supportsTransactions = graph.features().graph().supportsTransactions();
}
/**
* Finds a user by username and return {@code null} if one could not be found.
*
* @throws IllegalStateException if there is more than one user with a particular username.
*/
public Vertex findUser(final String username) {
if (supportsTransactions) g.tx().rollback();
final GraphTraversal<Vertex,Vertex> t = g.V().has(CredentialGraphTokens.PROPERTY_USERNAME, username);
final Vertex v = t.hasNext() ? t.next() : null;
if (t.hasNext()) throw new IllegalStateException(String.format("Multiple users with username %s", username));
return v;
}
/**
* Creates a new user.
*
* @return the newly created user vertex
*/
public Vertex createUser(final String username, final String password) {
if (findUser(username) != null) throw new IllegalStateException("User with this name already exists");
if (supportsTransactions) graph.tx().rollback();
try {
final Vertex v = graph.addVertex(T.label, CredentialGraphTokens.VERTEX_LABEL_USER,
CredentialGraphTokens.PROPERTY_USERNAME, username,
CredentialGraphTokens.PROPERTY_PASSWORD, BCrypt.hashpw(password, BCrypt.gensalt(BCRYPT_ROUNDS)));
if (supportsTransactions) graph.tx().commit();
return v;
} catch (Exception ex) {
if (supportsTransactions) graph.tx().rollback();
throw new RuntimeException(ex);
}
}
/**
* Removes a user by name.
*
* @return the number of users removed (which should be one or zero)
*/
public long removeUser(final String username) {
if (supportsTransactions) graph.tx().rollback();
try {
final long count = g.V().has(CredentialGraphTokens.PROPERTY_USERNAME, username).sideEffect(drop()).count().next();
if (supportsTransactions) graph.tx().commit();
return count;
} catch (Exception ex) {
if (supportsTransactions) graph.tx().rollback();
throw new RuntimeException(ex);
}
}
/**
* Get a count of the number of users in the database.
*/
public long countUsers() {
if (supportsTransactions) graph.tx().rollback();
return g.V().hasLabel(CredentialGraphTokens.VERTEX_LABEL_USER).count().next();
}
@Override
public String toString() {
return "CredentialGraph{" +
"graph=" + graph +
'}';
}
/**
* Wrap up any {@link Graph} instance in the {@code CredentialGraph} DSL.
*/
public static CredentialGraph credentials(final Graph graph) {
return new CredentialGraph(graph);
}
}