Author: matthieu
Date: Mon Nov 2 14:45:36 2015
New Revision: 1712020
URL: http://svn.apache.org/viewvc?rev=1712020&view=rev
Log:
JAMES-1586 implement a cassandra user repository
Contributed by Antoine Duprat
Added:
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepositoryModule.java
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/tables/
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/tables/CassandraUserTable.java
james/project/trunk/server/data/data-cassandra/src/test/java/org/apache/james/user/
james/project/trunk/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/
james/project/trunk/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java
Added:
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java?rev=1712020&view=auto
==============================================================================
---
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
(added)
+++
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepository.java
Mon Nov 2 14:45:36 2015
@@ -0,0 +1,162 @@
+/****************************************************************
+ * 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.james.user.cassandra;
+
+import static com.datastax.driver.core.querybuilder.QueryBuilder.delete;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.set;
+import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
+import static
org.apache.james.user.cassandra.tables.CassandraUserTable.ALGORITHM;
+import static org.apache.james.user.cassandra.tables.CassandraUserTable.NAME;
+import static
org.apache.james.user.cassandra.tables.CassandraUserTable.PASSWORD;
+import static
org.apache.james.user.cassandra.tables.CassandraUserTable.REALNAME;
+import static
org.apache.james.user.cassandra.tables.CassandraUserTable.TABLE_NAME;
+
+import java.util.Iterator;
+import java.util.Optional;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.james.backends.cassandra.utils.CassandraConstants;
+import org.apache.james.backends.cassandra.utils.CassandraUtils;
+import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.james.user.api.model.User;
+import org.apache.james.user.lib.AbstractUsersRepository;
+import org.apache.james.user.lib.model.DefaultUser;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Session;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Ints;
+
+public class CassandraUsersRepository extends AbstractUsersRepository {
+
+ private static final String DEFAULT_ALGO_VALUE = "SHA1";
+
+ private Session session;
+
+ @Inject
+ @Resource
+ public void setSession(@Named("cassandra-session") Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public User getUserByName(String name){
+ ResultSet result = session.execute(
+ select(REALNAME, PASSWORD, ALGORITHM)
+ .from(TABLE_NAME)
+ .where(eq(REALNAME, name)));
+ return Optional.ofNullable(result.one())
+ .map(row -> new DefaultUser(row.getString(REALNAME),
row.getString(PASSWORD), row.getString(ALGORITHM)))
+ .orElse(null);
+ }
+
+ @Override
+ public void updateUser(User user) throws UsersRepositoryException {
+ Preconditions.checkArgument(user instanceof DefaultUser);
+ DefaultUser defaultUser = (DefaultUser) user;
+ boolean executed = session.execute(
+ update(TABLE_NAME)
+ .with(set(REALNAME, defaultUser.getUserName()))
+ .and(set(PASSWORD, defaultUser.getHashedPassword()))
+ .and(set(ALGORITHM, defaultUser.getHashAlgorithm()))
+ .where(eq(NAME, defaultUser.getUserName().toLowerCase()))
+ .ifExists())
+ .one()
+ .getBool(CassandraConstants.LIGHTWEIGHT_TRANSACTION_APPLIED);
+
+ if (!executed) {
+ throw new UsersRepositoryException("Unable to update user");
+ }
+ }
+
+ @Override
+ public void removeUser(String name) throws UsersRepositoryException {
+ boolean executed = session.execute(
+ delete()
+ .from(TABLE_NAME)
+ .where(eq(NAME, name))
+ .ifExists())
+ .one()
+ .getBool(CassandraConstants.LIGHTWEIGHT_TRANSACTION_APPLIED);
+
+ if (!executed) {
+ throw new UsersRepositoryException("unable to remove unknown user
" + name);
+ }
+ }
+
+ @Override
+ public boolean contains(String name) {
+ return getUserByName(name) != null;
+ }
+
+ @Override
+ public boolean test(String name, String password) throws
UsersRepositoryException {
+ return Optional.ofNullable(getUserByName(name))
+ .map(x -> x.verifyPassword(password))
+ .orElse(false);
+ }
+
+ @Override
+ public int countUsers() throws UsersRepositoryException {
+ ResultSet result =
session.execute(select().countAll().from(TABLE_NAME));
+ return Ints.checkedCast(result.one().getLong(0));
+ }
+
+ @Override
+ public Iterator<String> list() throws UsersRepositoryException {
+ ResultSet result = session.execute(
+ select(REALNAME)
+ .from(TABLE_NAME));
+ return CassandraUtils.convertToStream(result)
+ .map(row -> row.getString(REALNAME))
+ .iterator();
+ }
+
+ @Override
+ public void addUser(String username, String password) throws
UsersRepositoryException {
+ isValidUsername(username);
+ doAddUser(username, password);
+ }
+
+ @Override
+ protected void doAddUser(String username, String password) throws
UsersRepositoryException {
+ DefaultUser user = new DefaultUser(username, DEFAULT_ALGO_VALUE);
+ user.setPassword(password);
+ boolean executed = session.execute(
+ insertInto(TABLE_NAME)
+ .value(NAME, user.getUserName().toLowerCase())
+ .value(REALNAME, user.getUserName())
+ .value(PASSWORD, user.getHashedPassword())
+ .value(ALGORITHM, user.getHashAlgorithm())
+ .ifNotExists())
+ .one()
+ .getBool(CassandraConstants.LIGHTWEIGHT_TRANSACTION_APPLIED);
+
+ if (!executed) {
+ throw new UsersRepositoryException("User with username " +
username + " already exist!");
+ }
+ }
+}
Added:
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepositoryModule.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepositoryModule.java?rev=1712020&view=auto
==============================================================================
---
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepositoryModule.java
(added)
+++
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/CassandraUsersRepositoryModule.java
Mon Nov 2 14:45:36 2015
@@ -0,0 +1,75 @@
+/****************************************************************
+ * 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.james.user.cassandra;
+
+import static com.datastax.driver.core.DataType.text;
+
+import java.util.List;
+
+import org.apache.james.backends.cassandra.components.CassandraIndex;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.backends.cassandra.components.CassandraTable;
+import org.apache.james.backends.cassandra.components.CassandraType;
+import org.apache.james.user.cassandra.tables.CassandraUserTable;
+
+import com.datastax.driver.core.schemabuilder.SchemaBuilder;
+import com.google.common.collect.ImmutableList;
+
+public class CassandraUsersRepositoryModule implements CassandraModule {
+
+ private final List<CassandraTable> tables;
+ private final List<CassandraIndex> index;
+ private final List<CassandraType> types;
+
+ public CassandraUsersRepositoryModule() {
+ tables = ImmutableList.of(
+ new CassandraTable(CassandraUserTable.TABLE_NAME,
+ SchemaBuilder.createTable(CassandraUserTable.TABLE_NAME)
+ .ifNotExists()
+ .addPartitionKey(CassandraUserTable.NAME, text())
+ .addColumn(CassandraUserTable.REALNAME, text())
+ .addColumn(CassandraUserTable.PASSWORD, text())
+ .addColumn(CassandraUserTable.ALGORITHM, text()))
+ );
+ index = ImmutableList.of(
+ new CassandraIndex(
+ SchemaBuilder.createIndex(CassandraIndex.INDEX_PREFIX +
CassandraUserTable.TABLE_NAME + CassandraUserTable.REALNAME)
+ .ifNotExists()
+ .onTable(CassandraUserTable.TABLE_NAME)
+ .andColumn(CassandraUserTable.REALNAME))
+ );
+ types = ImmutableList.of();
+ }
+
+ @Override
+ public List<CassandraTable> moduleTables() {
+ return tables;
+ }
+
+ @Override
+ public List<CassandraIndex> moduleIndex() {
+ return index;
+ }
+
+ @Override
+ public List<CassandraType> moduleTypes() {
+ return types;
+ }
+}
Added:
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/tables/CassandraUserTable.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/tables/CassandraUserTable.java?rev=1712020&view=auto
==============================================================================
---
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/tables/CassandraUserTable.java
(added)
+++
james/project/trunk/server/data/data-cassandra/src/main/java/org/apache/james/user/cassandra/tables/CassandraUserTable.java
Mon Nov 2 14:45:36 2015
@@ -0,0 +1,29 @@
+/****************************************************************
+ * 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.james.user.cassandra.tables;
+
+public interface CassandraUserTable {
+ String TABLE_NAME = "user";
+
+ String ALGORITHM = "algorithm";
+ String NAME = "name";
+ String PASSWORD = "passwd";
+ String REALNAME = "realname";
+}
Added:
james/project/trunk/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java?rev=1712020&view=auto
==============================================================================
---
james/project/trunk/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java
(added)
+++
james/project/trunk/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java
Mon Nov 2 14:45:36 2015
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.james.user.cassandra;
+
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.lib.AbstractUsersRepositoryTest;
+import org.junit.After;
+
+public class CassandraUsersRepositoryTest extends AbstractUsersRepositoryTest {
+
+ private CassandraCluster cassandra;
+
+ @After
+ public void tearDown() {
+ cassandra.clearAllTables();
+ }
+
+ @Override
+ protected UsersRepository getUsersRepository() throws Exception {
+ cassandra = CassandraCluster.create(new
CassandraUsersRepositoryModule());
+ CassandraUsersRepository cassandraUsersRepository = new
CassandraUsersRepository();
+ cassandraUsersRepository.setSession(cassandra.getConf());
+ return cassandraUsersRepository;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]