summaryrefslogtreecommitdiffstats
path: root/auth/auth-service
diff options
context:
space:
mode:
Diffstat (limited to 'auth/auth-service')
-rw-r--r--auth/auth-service/pom.xml411
-rw-r--r--auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java32
-rw-r--r--auth/auth-service/src/test/java/org/onap/aaf/auth/service/test/JU_BaseServiceImpl.java190
-rw-r--r--auth/auth-service/src/test/java/org/onap/aaf/auth/service/test/JU_ServiceImpl_createUserCred.java148
4 files changed, 563 insertions, 218 deletions
diff --git a/auth/auth-service/pom.xml b/auth/auth-service/pom.xml
index ff334874..63585f94 100644
--- a/auth/auth-service/pom.xml
+++ b/auth/auth-service/pom.xml
@@ -1,214 +1,207 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- * ============LICENSE_START====================================================
- * org.onap.aaf * ===========================================================================
- * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. * ===========================================================================
- * Licensed 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.
- * ============LICENSE_END====================================================
- * -->
+ * org.onap.aaf * ===========================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ * -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.onap.aaf.authz</groupId>
- <artifactId>authparent</artifactId>
- <version>2.1.14-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>aaf-auth-service</artifactId>
- <name>AAF Auth Service</name>
- <description>Core API Component for AAF Auth</description>
-
- <properties>
- <maven.test.failure.ignore>true</maven.test.failure.ignore>
- <!-- <sonar.skip>true</sonar.skip> -->
- <!-- SONAR -->
- <jacoco.version>0.7.7.201606060606</jacoco.version>
- <sonar-jacoco-listeners.version>3.2</sonar-jacoco-listeners.version>
- <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
- <!-- Default Sonar configuration -->
- <sonar.jacoco.reportPaths>target/code-coverage/jacoco-ut.exec</sonar.jacoco.reportPaths>
- <sonar.jacoco.itReportPaths>target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPaths>
- <!-- Note: This list should match jacoco-maven-plugin's exclusion list
- below -->
- <sonar.exclusions>**/gen/**,**/generated-sources/**,**/yang-gen**,**/pax/**</sonar.exclusions>
- <nexusproxy>https://nexus.onap.org</nexusproxy>
- <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
- <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
- <stagingNexusPath>/content/repositories/staging/</stagingNexusPath>
- <sitePath>/content/sites/site/org/onap/aaf/authz/${project.artifactId}/${project.version}</sitePath>
-
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.onap.aaf.authz</groupId>
- <artifactId>aaf-auth-client</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.onap.aaf.authz</groupId>
- <artifactId>aaf-auth-core</artifactId>
- </dependency>
-
- <!-- Add the Organizations you wish to support. You can delete ONAP if
- you have something else Match with Property Entry: Organization.<root ns>,
- i.e. Organization.onap.org=org.onap.org.DefaultOrg -->
- <dependency>
- <groupId>org.onap.aaf.authz</groupId>
- <artifactId>aaf-auth-deforg</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.onap.aaf.authz</groupId>
- <artifactId>aaf-auth-cass</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.onap.aaf.authz</groupId>
- <artifactId>aaf-auth-oauth</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.onap.aaf.authz</groupId>
- <artifactId>aaf-misc-rosetta</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.onap.aaf.authz</groupId>
- <artifactId>aaf-cadi-aaf</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-servlet</artifactId>
- </dependency>
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>*.properties</exclude>
- </excludes>
- </configuration>
- <version>2.3.1</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-deploy-plugin</artifactId>
- <configuration>
- <skip>false</skip>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>appassembler-maven-plugin</artifactId>
- <configuration>
- <programs>
- <program>
- <mainClass>org.onap.aaf.auth.service.AAF_Service</mainClass>
- <name>service</name>
- <commandLineArguments>
- <commandLineArgument>cadi_prop_files=${project.ext_root_dir}/etc/org.osaaf.aaf.service.props</commandLineArgument>
- <commandLineArgument>cadi_log_dir=${project.ext_root_dir}/logs/service</commandLineArgument>
- <commandLineArgument>cadi_etc_dir=${project.ext_root_dir}/etc</commandLineArgument>
- </commandLineArguments>
- </program>
- </programs>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.jacoco</groupId>
- <artifactId>jacoco-maven-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>**/gen/**</exclude>
- <exclude>**/generated-sources/**</exclude>
- <exclude>**/yang-gen/**</exclude>
- <exclude>**/pax/**</exclude>
- </excludes>
- </configuration>
- <executions>
-
- <execution>
- <id>pre-unit-test</id>
- <goals>
- <goal>prepare-agent</goal>
- </goals>
- <configuration>
- <destFile>${project.build.directory}/code-coverage/jacoco-ut.exec</destFile>
- <propertyName>surefireArgLine</propertyName>
- </configuration>
- </execution>
-
-
- <execution>
- <id>post-unit-test</id>
- <phase>test</phase>
- <goals>
- <goal>report</goal>
- </goals>
- <configuration>
- <dataFile>${project.build.directory}/code-coverage/jacoco-ut.exec</dataFile>
- <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
- </configuration>
- </execution>
- <execution>
- <id>pre-integration-test</id>
- <phase>pre-integration-test</phase>
- <goals>
- <goal>prepare-agent</goal>
- </goals>
- <configuration>
- <destFile>${project.build.directory}/code-coverage/jacoco-it.exec</destFile>
- <propertyName>failsafeArgLine</propertyName>
- </configuration>
- </execution>
-
- <execution>
- <id>post-integration-test</id>
- <phase>post-integration-test</phase>
- <goals>
- <goal>report</goal>
- </goals>
- <configuration>
- <dataFile>${project.build.directory}/code-coverage/jacoco-it.exec</dataFile>
- <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <!-- plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId>
- </plugin -->
- </plugins>
- </build>
-
- <distributionManagement>
- <repository>
- <id>ecomp-releases</id>
- <name>AAF Release Repository</name>
- <url>${nexusproxy}${releaseNexusPath}</url>
- </repository>
- <snapshotRepository>
- <id>ecomp-snapshots</id>
- <name>AAF Snapshot Repository</name>
- <url>${nexusproxy}${snapshotNexusPath}</url>
- </snapshotRepository>
- <site>
- <id>ecomp-site</id>
- <url>dav:${nexusproxy}${sitePath}</url>
- </site>
- </distributionManagement>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>authparent</artifactId>
+ <version>2.1.16-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>aaf-auth-service</artifactId>
+ <name>AAF Auth Service</name>
+ <description>Core API Component for AAF Auth</description>
+
+ <properties>
+ <maven.test.failure.ignore>true</maven.test.failure.ignore>
+ <!-- <sonar.skip>true</sonar.skip> -->
+ <!-- SONAR -->
+ <jacoco.version>0.7.7.201606060606</jacoco.version>
+ <sonar-jacoco-listeners.version>3.2</sonar-jacoco-listeners.version>
+ <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
+ <!-- Default Sonar configuration -->
+ <sonar.jacoco.reportPaths>target/code-coverage/jacoco-ut.exec</sonar.jacoco.reportPaths>
+ <sonar.jacoco.itReportPaths>target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPaths>
+ <!-- Note: This list should match jacoco-maven-plugin's exclusion list
+ below -->
+ <sonar.exclusions>**/gen/**,**/generated-sources/**,**/yang-gen**,**/pax/**</sonar.exclusions>
+ <nexusproxy>https://nexus.onap.org</nexusproxy>
+ <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
+ <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
+ <stagingNexusPath>/content/repositories/staging/</stagingNexusPath>
+ <sitePath>/content/sites/site/org/onap/aaf/authz/${project.artifactId}/${project.version}</sitePath>
+
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-auth-client</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-auth-core</artifactId>
+ </dependency>
+
+ <!-- Add the Organizations you wish to support. You can delete ONAP if
+ you have something else Match with Property Entry: Organization.<root ns>,
+ i.e. Organization.onap.org=org.onap.org.DefaultOrg -->
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-auth-deforg</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-auth-cass</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-auth-oauth</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-misc-rosetta</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.authz</groupId>
+ <artifactId>aaf-cadi-aaf</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>*.properties</exclude>
+ </excludes>
+ </configuration>
+ <version>2.3.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>appassembler-maven-plugin</artifactId>
+ <configuration>
+ <programs>
+ <program>
+ <mainClass>org.onap.aaf.auth.service.AAF_Service</mainClass>
+ <name>service</name>
+ <commandLineArguments>
+ <commandLineArgument>cadi_prop_files=${project.ext_root_dir}/etc/org.osaaf.aaf.service.props</commandLineArgument>
+ <commandLineArgument>cadi_log_dir=${project.ext_root_dir}/logs/service</commandLineArgument>
+ <commandLineArgument>cadi_etc_dir=${project.ext_root_dir}/etc</commandLineArgument>
+ </commandLineArguments>
+ </program>
+ </programs>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/gen/**</exclude>
+ <exclude>**/generated-sources/**</exclude>
+ <exclude>**/yang-gen/**</exclude>
+ <exclude>**/pax/**</exclude>
+ </excludes>
+ </configuration>
+ <executions>
+
+ <execution>
+ <id>pre-unit-test</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ <configuration>
+ <destFile>${project.build.directory}/code-coverage/jacoco-ut.exec</destFile>
+ <propertyName>surefireArgLine</propertyName>
+ </configuration>
+ </execution>
+
+
+ <execution>
+ <id>post-unit-test</id>
+ <phase>test</phase>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ <configuration>
+ <dataFile>${project.build.directory}/code-coverage/jacoco-ut.exec</dataFile>
+ <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>pre-integration-test</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ <configuration>
+ <destFile>${project.build.directory}/code-coverage/jacoco-it.exec</destFile>
+ <propertyName>failsafeArgLine</propertyName>
+ </configuration>
+ </execution>
+
+ <execution>
+ <id>post-integration-test</id>
+ <phase>post-integration-test</phase>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ <configuration>
+ <dataFile>${project.build.directory}/code-coverage/jacoco-it.exec</dataFile>
+ <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId>
+ </plugin -->
+ </plugins>
+ </build>
+
+ <distributionManagement>
+ <repository>
+ <id>ecomp-releases</id>
+ <name>AAF Release Repository</name>
+ <url>${nexusproxy}${releaseNexusPath}</url>
+ </repository>
+ <snapshotRepository>
+ <id>ecomp-snapshots</id>
+ <name>AAF Snapshot Repository</name>
+ <url>${nexusproxy}${snapshotNexusPath}</url>
+ </snapshotRepository>
+ <site>
+ <id>ecomp-site</id>
+ <url>dav:${nexusproxy}${sitePath}</url>
+ </site>
+ </distributionManagement>
</project>
diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java
index 295db4ac..b57b0708 100644
--- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java
+++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java
@@ -42,6 +42,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
+import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
@@ -2442,8 +2443,14 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
return Result.err(rb);
} else if (rb.value){
return Result.err(Status.ERR_Policy, "Credential content cannot be reused.");
- } else if ((Chrono.dateOnlyStamp(curr.expires).equals(Chrono.dateOnlyStamp(rcred.value.expires)) && curr.type==rcred.value.type)) {
- return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists");
+ } else if(Chrono.dateOnlyStamp(curr.expires).equals(Chrono.dateOnlyStamp(rcred.value.expires))
+ && curr.type==rcred.value.type
+ ) {
+ // Allow if expiring differential is greater than 1 day (for TEMP)
+ // Unless expiring in 1 day
+ if(System.currentTimeMillis() - rcred.value.expires.getTime() > TimeUnit.DAYS.toMillis(1)) {
+ return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists");
+ }
}
}
}
@@ -2501,13 +2508,20 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
case Status.ACC_Now:
try {
if (firstID) {
- // && !nsr.value.get(0).isAdmin(trans.getUserPrincipal().getName())) {
- Result<List<String>> admins = func.getAdmins(trans, nsr.value.get(0).name, false);
- // OK, it's a first ID, and not by NS Admin, so let's set TempPassword length
- // Note, we only do this on First time, because of possibility of
- // prematurely expiring a production id
- if (admins.isOKhasData() && !admins.value.contains(trans.user())) {
- rcred.value.expires = org.expiration(null, Expiration.TempPassword).getTime();
+ // OK, it's a first ID, and not by NS Owner
+ if(!ques.isOwner(trans,trans.user(),cdd.ns)) {
+ // Admins are not allowed to set first Cred, but Org has already
+ // said entity MAY create, typically by Permission
+ // We can't know which reason they are allowed here, so we
+ // have to assume that any with Special Permission would not be
+ // an Admin.
+ if(ques.isAdmin(trans, trans.user(), cdd.ns)) {
+ return Result.err(Result.ERR_Denied,
+ "Only Owners may create first passwords in their Namespace. Admins may modify after one exists" );
+ } else {
+ // Allow IDs that AREN'T part of NS with Org Onboarding Permission (see Org object) to create Temp Passwords.
+ rcred.value.expires = org.expiration(null, Expiration.TempPassword).getTime();
+ }
}
}
} catch (Exception e) {
diff --git a/auth/auth-service/src/test/java/org/onap/aaf/auth/service/test/JU_BaseServiceImpl.java b/auth/auth-service/src/test/java/org/onap/aaf/auth/service/test/JU_BaseServiceImpl.java
new file mode 100644
index 00000000..5e6cfb62
--- /dev/null
+++ b/auth/auth-service/src/test/java/org/onap/aaf/auth/service/test/JU_BaseServiceImpl.java
@@ -0,0 +1,190 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.service.test;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.aaf.auth.common.Define;
+import org.onap.aaf.auth.dao.cached.CachedCertDAO;
+import org.onap.aaf.auth.dao.cached.CachedCredDAO;
+import org.onap.aaf.auth.dao.cached.CachedNSDAO;
+import org.onap.aaf.auth.dao.cached.CachedPermDAO;
+import org.onap.aaf.auth.dao.cached.CachedRoleDAO;
+import org.onap.aaf.auth.dao.cached.CachedUserRoleDAO;
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.dao.cass.CacheInfoDAO;
+import org.onap.aaf.auth.dao.cass.DelegateDAO;
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.dao.cass.HistoryDAO;
+import org.onap.aaf.auth.dao.cass.LocateDAO;
+import org.onap.aaf.auth.dao.cass.NsDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.hl.Question;
+import org.onap.aaf.auth.env.AuthzEnv;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.service.AuthzCassServiceImpl;
+import org.onap.aaf.auth.service.mapper.Mapper_2_0;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.org.DefaultOrg;
+import org.onap.aaf.org.DefaultOrgIdentity;
+
+import aaf.v2_0.Approvals;
+import aaf.v2_0.Certs;
+import aaf.v2_0.Delgs;
+import aaf.v2_0.Error;
+import aaf.v2_0.History;
+import aaf.v2_0.Keys;
+import aaf.v2_0.Nss;
+import aaf.v2_0.Perms;
+import aaf.v2_0.Pkey;
+import aaf.v2_0.Request;
+import aaf.v2_0.Roles;
+import aaf.v2_0.UserRoles;
+import aaf.v2_0.Users;
+
+@RunWith(MockitoJUnitRunner.class)
+public abstract class JU_BaseServiceImpl {
+ protected AuthzCassServiceImpl<Nss, Perms, Pkey, Roles, Users, UserRoles, Delgs, Certs, Keys, Request, History, Error, Approvals>
+ acsi;
+ protected Mapper_2_0 mapper;
+
+ @Mock
+ protected DefaultOrg org;
+ @Mock
+ protected DefaultOrgIdentity orgIdentity;
+
+//
+// NOTE: Annotation format (@Mock and @Spy) do NOT seem to always work as a Base Class,
+// so we construct manually.
+//
+// Mock Objects
+ protected HistoryDAO historyDAO = mock(HistoryDAO.class);
+ protected CacheInfoDAO cacheInfoDAO = mock(CacheInfoDAO.class);
+ protected CachedNSDAO nsDAO = mock(CachedNSDAO.class);
+ protected CachedPermDAO permDAO = mock(CachedPermDAO.class);
+ protected CachedRoleDAO roleDAO = mock(CachedRoleDAO.class);
+ protected CachedUserRoleDAO userRoleDAO = mock(CachedUserRoleDAO.class);
+ protected CachedCredDAO credDAO = mock(CachedCredDAO.class);
+ protected CachedCertDAO certDAO = mock(CachedCertDAO.class);
+ protected LocateDAO locateDAO = mock(LocateDAO.class);
+ protected FutureDAO futureDAO = mock(FutureDAO.class);
+ protected DelegateDAO delegateDAO = mock(DelegateDAO.class);
+ protected ApprovalDAO approvalDAO = mock(ApprovalDAO.class);
+
+ // Spy Objects
+ @Spy
+ protected static PropAccess access = new PropAccess();
+ @Spy
+ protected static AuthzEnv env = new AuthzEnv(access);
+ @Spy
+ protected static AuthzTrans trans = env.newTransNoAvg();
+
+ // @Spy doesn't seem to work on Question.
+ @Spy
+ protected Question question = spy(new Question(trans,
+ historyDAO,cacheInfoDAO,nsDAO,permDAO,
+ roleDAO,userRoleDAO,credDAO,certDAO,
+ locateDAO,futureDAO,delegateDAO,approvalDAO));
+
+ public void setUp() throws Exception {
+ when(trans.org()).thenReturn(org);
+ when(org.getDomain()).thenReturn("org.onap");
+ Define.set(access);
+ access.setProperty(Config.CADI_LATITUDE, "38.0");
+ access.setProperty(Config.CADI_LONGITUDE, "-72.0");
+
+ mapper = new Mapper_2_0(question);
+ acsi = new AuthzCassServiceImpl<>(trans, mapper, question);
+ }
+
+ //////////
+ // Common Data Objects
+ /////////
+ protected List<NsDAO.Data> nsData(String name) {
+ NsDAO.Data ndd = new NsDAO.Data();
+ ndd.name=name;
+ int dot = name.lastIndexOf('.');
+ if(dot<0) {
+ ndd.parent=".";
+ } else {
+ ndd.parent=name.substring(0,dot);
+ }
+ List<NsDAO.Data> rv = new ArrayList<NsDAO.Data>();
+ rv.add(ndd);
+ return rv;
+ }
+
+ /**
+ * Setup Role Data for Mock Usages
+ * @param trans
+ * @param user
+ * @param ns
+ * @param role
+ * @param exists
+ * @param days
+ */
+ protected void whenRole(AuthzTrans trans, String user, String ns, String role, boolean exists, int days) {
+ Result<List<UserRoleDAO.Data>> result;
+ if(exists) {
+ result = Result.ok(listOf(urData(user,ns,role,days)));
+ } else {
+ result = Result.ok(emptyList(UserRoleDAO.Data.class));
+ }
+ when(question.userRoleDAO().read(trans, user, ns+'.'+role)).thenReturn(result);
+ }
+
+ protected UserRoleDAO.Data urData(String user, String ns, String rname, int days) {
+ UserRoleDAO.Data urdd = new UserRoleDAO.Data();
+ urdd.user = user;
+ urdd.ns = ns;
+ urdd.rname = rname;
+ urdd.role = ns + '.' + rname;
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.add(GregorianCalendar.DAY_OF_YEAR, days);
+ urdd.expires = gc.getTime();
+ return urdd;
+ }
+
+
+ protected <T> List<T> listOf(T t) {
+ List<T> list = new ArrayList<>();
+ list.add(t);
+ return list;
+ }
+
+ protected <T> List<T> emptyList(Class<T> cls) {
+ return new ArrayList<>();
+ }
+
+}
diff --git a/auth/auth-service/src/test/java/org/onap/aaf/auth/service/test/JU_ServiceImpl_createUserCred.java b/auth/auth-service/src/test/java/org/onap/aaf/auth/service/test/JU_ServiceImpl_createUserCred.java
new file mode 100644
index 00000000..00da6b4c
--- /dev/null
+++ b/auth/auth-service/src/test/java/org/onap/aaf/auth/service/test/JU_ServiceImpl_createUserCred.java
@@ -0,0 +1,148 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.service.test;
+
+import static org.mockito.Mockito.*;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+
+import org.onap.aaf.auth.dao.hl.Question;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.cadi.Hash;
+import org.onap.aaf.cadi.util.FQI;
+
+import aaf.v2_0.CredRequest;
+import junit.framework.Assert;
+
+@RunWith(MockitoJUnitRunner.class)
+public class JU_ServiceImpl_createUserCred extends JU_BaseServiceImpl {
+ @Mock
+ private Result<CredDAO.Data> rcdd;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Test
+ public void validCreateNewIsOwner() throws OrganizationException {
+ CredRequest cr = credRequest1();
+ final String fqi = "bob@people.onap.org";
+ when(trans.user()).thenReturn(fqi);
+ when(org.isValidPassword(trans, cr.getId(),cr.getPassword())).thenReturn("");
+ when(org.isValidCred(trans, cr.getId())).thenReturn(true);
+ when(org.canHaveMultipleCreds(cr.getId())).thenReturn(true);
+ when(org.getIdentity(trans, cr.getId())).thenReturn(orgIdentity);
+ when(orgIdentity.isFound()).thenReturn(true);
+ final String ns = "org.onap.sample";
+ whenRole(trans, fqi, ns, "owner", false, 100);
+ when(question.nsDAO().read(trans, ns)).thenReturn(Result.ok(nsData(ns)));
+ when(question.credDAO().readID(trans, cr.getId())).thenReturn(Result.ok(emptyList(CredDAO.Data.class)));
+ when(question.credDAO().create(any(AuthzTrans.class), any(CredDAO.Data.class) )).thenReturn(Result.ok(credDataFound(cr,100)));
+ when(question.credDAO().readNS(trans, ns)).thenReturn(Result.ok(listOf(credDataFound(cr,100))));
+ Result<?> result = acsi.createUserCred(trans,cr);
+ // Owner may do FIRST Creds
+ Assert.assertEquals(Result.OK,result.status);
+ }
+
+ @Test
+ public void validCreateNewOnlyAdmin() throws OrganizationException {
+ CredRequest cr = credRequest1();
+ final String fqi = "bob@people.onap.org";
+ when(trans.user()).thenReturn(fqi);
+ when(org.isValidPassword(trans, cr.getId(),cr.getPassword())).thenReturn("");
+ when(org.isValidCred(trans, cr.getId())).thenReturn(true);
+ when(org.canHaveMultipleCreds(cr.getId())).thenReturn(true);
+ when(org.getIdentity(trans, cr.getId())).thenReturn(orgIdentity);
+ when(orgIdentity.isFound()).thenReturn(true);
+ final String ns = "org.onap.sample";
+ whenRole(trans,fqi,ns,"owner",false, 100);
+ whenRole(trans,fqi,ns,"admin",true, 100);
+ when(question.nsDAO().read(trans, ns)).thenReturn(Result.ok(nsData(ns)));
+ when(question.credDAO().readID(trans, cr.getId())).thenReturn(Result.ok(emptyList(CredDAO.Data.class)));
+ when(question.credDAO().create(any(AuthzTrans.class), any(CredDAO.Data.class) )).thenReturn(Result.ok(credDataFound(cr,100)));
+ when(question.credDAO().readNS(trans, ns)).thenReturn(Result.ok(listOf(credDataFound(cr,100))));
+ Result<?> result = acsi.createUserCred(trans,cr);
+ // Admins may not do FIRST Creds
+ Assert.assertEquals(Result.ERR_Denied,result.status);
+ }
+
+ @Test
+ public void validCreateExisting() throws OrganizationException {
+ CredRequest cr = credRequest1();
+ when(org.isValidPassword(trans, cr.getId(),cr.getPassword())).thenReturn("");
+ when(org.isValidCred(trans, cr.getId())).thenReturn(true);
+ when(org.canHaveMultipleCreds(cr.getId())).thenReturn(true);
+ when(org.getIdentity(trans, cr.getId())).thenReturn(orgIdentity);
+ when(orgIdentity.isFound()).thenReturn(true);
+ String ns = "org.onap.sample";
+ when(question.nsDAO().read(trans, ns)).thenReturn(Result.ok(nsData(ns)));
+
+ CredDAO.Data cdd = credDataFound(cr,100);
+ when(question.credDAO().create(any(AuthzTrans.class), any(CredDAO.Data.class) )).thenReturn(Result.ok(cdd));
+ when(question.credDAO().readID(trans, cr.getId())).thenReturn(Result.ok(listOf(cdd)));
+
+ Result<?> result = acsi.createUserCred(trans,cr);
+ Assert.assertEquals(Result.OK,result.status);
+ }
+
+ private CredRequest credRequest1() {
+ CredRequest cr = new CredRequest();
+ cr.setId("m12345@sample.onap.org");
+ cr.setPassword("BobAndWeave");
+ cr.setType(CredDAO.RAW);
+ return cr;
+ }
+
+ private CredDAO.Data credDataFound(CredRequest cr, int days) {
+ CredDAO.Data cdd = new CredDAO.Data();
+ cdd.id = cr.getId();
+ cdd.ns = FQI.reverseDomain(cr.getId());
+ cdd.other = 12345;
+ cdd.tag = "1355434";
+ cdd.type = CredDAO.BASIC_AUTH_SHA256;
+ try {
+ cdd.cred = ByteBuffer.wrap(Hash.hashSHA256(cr.getPassword().getBytes()));
+ } catch (NoSuchAlgorithmException e) {
+ Assert.fail(e.getMessage());
+ }
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.add(GregorianCalendar.DAY_OF_YEAR, days);
+ cdd.expires = gc.getTime();
+ return cdd;
+ }
+
+} \ No newline at end of file