Repository: CVEProject/cve-services
Pull request #1110 (2023-07-25 14:58:30)

Updating Int from Dev 
Updating Int from Dev with changes from Sprint-32


Patch:
diff --git a/package-lock.json b/package-lock.json
index 85fa1e23..f0a78272 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -130,9 +130,9 @@
             }
         },
         "node_modules/@babel/core/node_modules/semver": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver.js"
@@ -173,9 +173,9 @@
             }
         },
         "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver.js"
@@ -3277,9 +3277,9 @@
             }
         },
         "node_modules/eslint-plugin-import/node_modules/semver": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver.js"
@@ -3322,9 +3322,9 @@
             }
         },
         "node_modules/eslint-plugin-node/node_modules/semver": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver.js"
@@ -5141,9 +5141,9 @@
             }
         },
         "node_modules/istanbul-lib-instrument/node_modules/semver": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver.js"
@@ -5721,9 +5721,9 @@
             }
         },
         "node_modules/make-dir/node_modules/semver": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "version": "6.3.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+            "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
             "bin": {
                 "semver": "bin/semver.js"
             }
@@ -6504,9 +6504,9 @@
             }
         },
         "node_modules/nodemon/node_modules/semver": {
-            "version": "5.7.1",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-            "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+            "version": "5.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+            "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver"
@@ -6539,9 +6539,9 @@
             }
         },
         "node_modules/normalize-package-data/node_modules/semver": {
-            "version": "5.7.1",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-            "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+            "version": "5.7.2",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+            "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver"
@@ -8162,9 +8162,9 @@
             "dev": true
         },
         "node_modules/semver": {
-            "version": "7.5.1",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
-            "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+            "version": "7.5.4",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+            "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
             "dependencies": {
                 "lru-cache": "^6.0.0"
             },
@@ -10199,9 +10199,9 @@
             }
         },
         "node_modules/word-wrap": {
-            "version": "1.2.3",
-            "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-            "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
+            "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
             "dev": true,
             "engines": {
                 "node": ">=0.10.0"
@@ -10531,9 +10531,9 @@
             },
             "dependencies": {
                 "semver": {
-                    "version": "6.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
                     "dev": true
                 }
             }
@@ -10564,9 +10564,9 @@
             },
             "dependencies": {
                 "semver": {
-                    "version": "6.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
                     "dev": true
                 }
             }
@@ -12999,9 +12999,9 @@
                     }
                 },
                 "semver": {
-                    "version": "6.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
                     "dev": true
                 }
             }
@@ -13031,9 +13031,9 @@
             },
             "dependencies": {
                 "semver": {
-                    "version": "6.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
                     "dev": true
                 }
             }
@@ -14202,9 +14202,9 @@
             },
             "dependencies": {
                 "semver": {
-                    "version": "6.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
                     "dev": true
                 }
             }
@@ -14654,9 +14654,9 @@
             },
             "dependencies": {
                 "semver": {
-                    "version": "6.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
                 }
             }
         },
@@ -15256,9 +15256,9 @@
                     }
                 },
                 "semver": {
-                    "version": "5.7.1",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-                    "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+                    "version": "5.7.2",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+                    "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
                     "dev": true
                 }
             }
@@ -15284,9 +15284,9 @@
             },
             "dependencies": {
                 "semver": {
-                    "version": "5.7.1",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-                    "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+                    "version": "5.7.2",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+                    "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
                     "dev": true
                 }
             }
@@ -16475,9 +16475,9 @@
             }
         },
         "semver": {
-            "version": "7.5.1",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
-            "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+            "version": "7.5.4",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+            "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
             "requires": {
                 "lru-cache": "^6.0.0"
             },
@@ -18009,9 +18009,9 @@
             }
         },
         "word-wrap": {
-            "version": "1.2.3",
-            "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-            "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
+            "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
             "dev": true
         },
         "wordwrap": {
@@ -18224,4 +18224,4 @@
             "dev": true
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/constants/index.js b/src/constants/index.js
index 4675180b..eebae31b 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -92,6 +92,10 @@ function getConstants () {
     },
     MAX_SHORTNAME_LENGTH: 32,
     MIN_SHORTNAME_LENGTH: 2,
+    MAX_FIRSTNAME_LENGTH: 100,
+    MAX_LASTNAME_LENGTH: 100,
+    MAX_MIDDLENAME_LENGTH: 100,
+    MAX_SUFFIX_LENGTH: 100,
     CVE_ID_PATTERN: cveSchemaV5.definitions.cveId.pattern,
     // Ajv's pattern validation uses the "u" (unicode) flag:
     // https://ajv.js.org/json-schema.html#pattern
diff --git a/src/controller/cve.controller/cve.controller.js b/src/controller/cve.controller/cve.controller.js
index 8b50924b..de7d5237 100644
--- a/src/controller/cve.controller/cve.controller.js
+++ b/src/controller/cve.controller/cve.controller.js
@@ -690,7 +690,6 @@ async function insertAdp (req, res, next) {
 
     const providerMetadata = createProviderMetadata(orgUuid, req.ctx.org, dateUpdated)
     adpContainer.providerMetadata = providerMetadata
-    let adpCount = 0
     let dupeFound = 0
     let dupeIndex = -1
     let dupeStatus = 'new'
@@ -704,14 +703,9 @@ async function insertAdp (req, res, next) {
         }
       })
 
-      adpCount = cveRecord.containers.adp.length + 1
-      if (dupeFound === 1) {
-        adpCount = adpCount - 1
-      }
       logger.info('Number of ADP containers already: ' + cveRecord.containers.adp.length)
     } else {
       logger.info('There were previously zero ADP containers.')
-      adpCount = 1
       cveRecord.containers.adp = []
     }
 
@@ -730,7 +724,7 @@ async function insertAdp (req, res, next) {
 
     await cveRepo.updateByCveId(id, cveModel)
 
-    const outcome = id + ' record had ' + dupeStatus + ' ADP container ' + adpCount + ' successfully inserted. This submission should appear on ' + url + ' within 15 minutes.'
+    const outcome = id + ' record had ' + dupeStatus + ' ADP container for org ' + req.ctx.org + ' successfully inserted. This submission should appear on ' + url + ' within 15 minutes.'
     const responseMessage = {
       message: outcome,
       updated: cveModel.cve
diff --git a/src/controller/org.controller/error.js b/src/controller/org.controller/error.js
index bb83e2c3..4c4df5fd 100644
--- a/src/controller/org.controller/error.js
+++ b/src/controller/org.controller/error.js
@@ -84,6 +84,13 @@ class OrgControllerError extends idrErr.IDRError {
     err.message = 'Please have another admin user from your organization change your role.'
     return err
   }
+
+  userLimitReached () {
+    const err = {}
+    err.error = 'NUMBER_OF_USERS_IN_ORG_LIMIT_REACHED'
+    err.message = 'The requested user can not be created and added to the organization because the organization has hit its limit of 100 users. Contact the Secretariat.'
+    return err
+  }
 }
 
 module.exports = {
diff --git a/src/controller/org.controller/index.js b/src/controller/org.controller/index.js
index 2be6777a..b1630aa9 100644
--- a/src/controller/org.controller/index.js
+++ b/src/controller/org.controller/index.js
@@ -545,15 +545,15 @@ router.post('/org/:shortname/user',
   */
   mw.validateUser,
   mw.onlySecretariatOrAdmin,
-  mw.onlyOrgWithRole,
+  mw.onlyOrgWithPartnerRole,
   param(['shortname']).isString().trim().escape().notEmpty().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
   body(['username']).isString().trim().escape().notEmpty().custom(isValidUsername),
   body(['org_uuid']).optional().isString().trim().escape(),
   body(['uuid']).optional().isString().trim().escape(),
-  body(['name.first']).optional().isString().trim().escape(),
-  body(['name.last']).optional().isString().trim().escape(),
-  body(['name.middle']).optional().isString().trim().escape(),
-  body(['name.suffix']).optional().isString().trim().escape(),
+  body(['name.first']).optional().isString().trim().escape().isLength({ max: CONSTANTS.MAX_FIRSTNAME_LENGTH }).withMessage(errorMsgs.FIRSTNAME_LENGTH),
+  body(['name.last']).optional().isString().trim().escape().isLength({ max: CONSTANTS.MAX_LASTNAME_LENGTH }).withMessage(errorMsgs.LASTNAME_LENGTH),
+  body(['name.middle']).optional().isString().trim().escape().isLength({ max: CONSTANTS.MAX_MIDDLENAME_LENGTH }).withMessage(errorMsgs.MIDDLENAME_LENGTH),
+  body(['name.suffix']).optional().isString().trim().escape().isLength({ max: CONSTANTS.MAX_SUFFIX_LENGTH }).withMessage(errorMsgs.SUFFIX_LENGTH),
   body(['authority.active_roles']).optional()
     .custom(mw.isFlatStringArray)
     .customSanitizer(toUpperCaseArray)
@@ -712,7 +712,7 @@ router.put('/org/:shortname/user/:username',
   }
   */
   mw.validateUser,
-  mw.onlyOrgWithRole,
+  mw.onlyOrgWithPartnerRole,
   query().custom((query) => {
     return mw.validateQueryParameterNames(query, ['active', 'new_username', 'org_short_name', 'name.first', 'name.last', 'name.middle',
       'name.suffix', 'active_roles.add', 'active_roles.remove'])
@@ -722,10 +722,10 @@ router.put('/org/:shortname/user/:username',
   query(['active']).optional().isBoolean({ loose: true }),
   query(['new_username']).optional().isString().trim().escape().notEmpty().custom(isValidUsername),
   query(['org_short_name']).optional().isString().trim().escape().notEmpty().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
-  query(['name.first']).optional().isString().trim().escape(),
-  query(['name.last']).optional().isString().trim().escape(),
-  query(['name.middle']).optional().isString().trim().escape(),
-  query(['name.suffix']).optional().isString().trim().escape(),
+  body(['name.first']).optional().isString().trim().escape().isLength({ max: CONSTANTS.MAX_FIRSTNAME_LENGTH }).withMessage(errorMsgs.FIRSTNAME_LENGTH),
+  body(['name.last']).optional().isString().trim().escape().isLength({ max: CONSTANTS.MAX_LASTNAME_LENGTH }).withMessage(errorMsgs.LASTNAME_LENGTH),
+  body(['name.middle']).optional().isString().trim().escape().isLength({ max: CONSTANTS.MAX_MIDDLENAME_LENGTH }).withMessage(errorMsgs.MIDDLENAME_LENGTH),
+  body(['name.suffix']).optional().isString().trim().escape().isLength({ max: CONSTANTS.MAX_SUFFIX_LENGTH }).withMessage(errorMsgs.SUFFIX_LENGTH),
   query(['active_roles.add']).optional().toArray()
     .custom(isFlatStringArray)
     .customSanitizer(toUpperCaseArray)
@@ -806,7 +806,7 @@ router.put('/org/:shortname/user/:username/reset_secret',
   }
   */
   mw.validateUser,
-  mw.onlyOrgWithRole,
+  mw.onlyOrgWithPartnerRole,
   param(['shortname']).isString().trim().escape().notEmpty().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
   param(['username']).isString().trim().escape().notEmpty().custom(isValidUsername),
   parseError,
diff --git a/src/controller/org.controller/org.controller.js b/src/controller/org.controller/org.controller.js
index bf0ae657..62e38fe3 100644
--- a/src/controller/org.controller/org.controller.js
+++ b/src/controller/org.controller/org.controller.js
@@ -445,6 +445,12 @@ async function createUser (req, res, next) {
       return res.status(404).json(error.orgDnePathParam(orgShortName))
     }
 
+    const users = await userRepo.findUsersByOrgUUID(orgUUID)
+
+    if (users >= 100) {
+      return res.status(400).json(error.userLimitReached())
+    }
+
     Object.keys(req.ctx.body).forEach(k => {
       const key = k.toLowerCase()
 
diff --git a/src/middleware/error.js b/src/middleware/error.js
index 5d667328..afc658a1 100644
--- a/src/middleware/error.js
+++ b/src/middleware/error.js
@@ -63,6 +63,13 @@ class MiddlewareError extends idrErr.IDRError {
     return err
   }
 
+  orgHasNoPartnerRole (shortname) { // mw
+    const err = {}
+    err.error = 'ORG_HAS_NO_PARTNER_ROLE'
+    err.message = `The '${shortname}' organization designated by the shortname parameter does not have any partner roles.`
+    return err
+  }
+
   orgDoesNotOwnId (org, id) {
     const err = {
       error: 'ORG_DOES_NOT_OWN_ID',
diff --git a/src/middleware/errorMessages.js b/src/middleware/errorMessages.js
index 327850cf..6f6a1b91 100644
--- a/src/middleware/errorMessages.js
+++ b/src/middleware/errorMessages.js
@@ -9,5 +9,9 @@ module.exports = {
   CVE_FILTERED_STATES: 'Invalid record state. Valid states are: PUBLISHED, REJECTED',
   COUNT_ONLY: 'Invalid count_only value. Value should be 1, true, or yes to indicate true, or 0, false, or no to indicate false',
   TIMESTAMP_FORMAT: "Bad date, or invalid timestamp format: valid format is yyyy-MM-ddTHH:mm:ss or yyyy-MM-ddTHH:mm:ssZZZZ (to use '+' in timezone offset, encode as '%2B)",
-  CNA_MODIFIED: 'Invalid cna_modified value. Value should be 1, true, or yes to indicate true, or 0, false, or no to indicate false'
+  CNA_MODIFIED: 'Invalid cna_modified value. Value should be 1, true, or yes to indicate true, or 0, false, or no to indicate false',
+  FIRSTNAME_LENGTH: 'Invalid name.first. Name must be between 1 and 100 characters in length.',
+  LASTNAME_LENGTH: 'Invalid name.last. Name must be between 1 and 100 characters in length.',
+  MIDDLENAME_LENGTH: 'Invalid name.middle. Name must be between 1 and 100 characters in length.',
+  SUFFIX_LENGTH: 'Invalid name.suffix. Name must be between 1 and 100 characters in length.'
 }
diff --git a/src/middleware/middleware.js b/src/middleware/middleware.js
index babe8376..8e1ff53f 100644
--- a/src/middleware/middleware.js
+++ b/src/middleware/middleware.js
@@ -255,7 +255,7 @@ async function onlyAdps (req, res, next) {
   }
 }
 // Checks that an org has a role or any sort
-async function onlyOrgWithRole (req, res, next) {
+async function onlyOrgWithPartnerRole (req, res, next) {
   const shortName = req.ctx.org
   const orgRepo = req.ctx.repositories.getOrgRepository()
 
@@ -264,12 +264,15 @@ async function onlyOrgWithRole (req, res, next) {
     if (org === null) {
       logger.info({ uuid: req.ctx.uuid, message: shortName + ' does NOT exist ' })
       return res.status(404).json(error.orgDoesNotExist(shortName))
+    } else if (org.authority.active_roles.length === 1 && org.authority.active_roles[0] === 'BULK_DOWNLOAD') {
+      logger.info({ uuid: req.ctx.uuid, message: org.short_name + 'only has BULK_DOWNLOAD role ' })
+      return res.status(403).json(error.orgHasNoPartnerRole(shortName))
     } else if (org.authority.active_roles.length > 0) {
       logger.info({ uuid: req.ctx.uuid, message: org.short_name + ' has a role ' })
       next()
     } else {
       logger.info({ uuid: req.ctx.uuid, message: org.short_name + ' does NOT have a role ' })
-      return res.status(403).json(error.orgHasNoRole(shortName))
+      return res.status(403).json(error.orgHasNoPartnerRole(shortName))
     }
   } catch (err) {
     next(err)
@@ -445,7 +448,7 @@ module.exports = {
   onlySecretariatOrAdmin,
   onlyCnas,
   onlyAdps,
-  onlyOrgWithRole,
+  onlyOrgWithPartnerRole,
   validateQueryParameterNames,
   cnaMustOwnID,
   createCtxAndReqUUID,
diff --git a/src/model/user.js b/src/model/user.js
index b34f6b60..e536c07d 100644
--- a/src/model/user.js
+++ b/src/model/user.js
@@ -33,6 +33,10 @@ UserSchema.query.byUUID = function (uuid) {
   return this.where({ UUID: uuid })
 }
 
+UserSchema.query.byOrgUUID = function (orgUUID) {
+  return this.where({ org_UUID: orgUUID })
+}
+
 UserSchema.query.byUserNameAndOrgUUID = function (username, orgUUID) {
   return this.where({ username: username, org_UUID: orgUUID })
 }
diff --git a/src/repositories/userRepository.js b/src/repositories/userRepository.js
index 26204d9d..4aa255a4 100644
--- a/src/repositories/userRepository.js
+++ b/src/repositories/userRepository.js
@@ -23,6 +23,10 @@ class UserRepository extends BaseRepository {
     return this.collection.findOne().byUUID(UUID)
   }
 
+  async findUsersByOrgUUID (orgUUID) {
+    return this.collection.find().byOrgUUID(orgUUID).countDocuments().exec()
+  }
+
   async findOneByUserNameAndOrgUUID (userName, orgUUID) {
     return this.collection.findOne().byUserNameAndOrgUUID(userName, orgUUID)
   }
diff --git a/src/utils/utils.js b/src/utils/utils.js
index cebeeda9..2f0029f7 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -134,7 +134,7 @@ function booleanIsTrue (val) {
 // Sanitizer for dates
 function toDate (val) {
   val = val.toUpperCase()
-  let value = val.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(|Z|((-|\+)\d{2}:\d{2}))$/)
+  let value = val.match(/^\d{4}-\d{2}-\d{2}T(?:0?[0-9]|1[0-9]|2[0-3]):(?:0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]):(?:0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])(\.\d+)?(|Z|((-|\+)\d{2}:\d{2}))$/)
   let result = null
   if (value) {
     const dateStr = value[0]


Test patch:
diff --git a/test/integration-tests/cve/getCveDateTest.js b/test/integration-tests/cve/getCveDateTest.js
new file mode 100644
index 00000000..a8700158
--- /dev/null
+++ b/test/integration-tests/cve/getCveDateTest.js
@@ -0,0 +1,113 @@
+/* eslint-disable no-unused-expressions */
+
+const chai = require('chai')
+chai.use(require('chai-http'))
+const expect = chai.expect
+
+const constants = require('../constants.js')
+const app = require('../../../src/index.js')
+
+describe('Test time_modified for get CVE', () => {
+  context('Negative Tests', () => {
+    it('Get CVE should fail if time_modified.gt is given a date with an invalid month', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.gt=2022-13-01T00:00:00Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.lt is given a date with an invalid month', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.lt=2022-13-01T00:00:00Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.lt is given a date with an invalid day', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.lt=2022-01-32T00:00:00Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.gt is given a date with an invalid day', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.gt=2022-01-32T00:00:00Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.gt is given a date with invalid hours', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.gt=2022-01-01T25:00:00Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.lt is given a date with invalid hours', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.lt=2022-01-01T25:00:00Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.gt is given a date with invalid minutes', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.gt=2022-01-01T00:61:00Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.lt is given a date with invalid minutes', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.lt=2022-01-01T00:61:00Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.gt is given a date with invalid seconds', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.gt=2022-01-01T00:00:61Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+    it('Get CVE should fail if time_modified.lt is given a date with invalid seconds', async () => {
+      await chai.request(app)
+        .get('/api/cve?time_modified.lt=2022-01-01T00:00:61Z')
+        .set(constants.headers)
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.message).to.contain('Parameters were invalid')
+        })
+    })
+  })
+})
diff --git a/test/integration-tests/cve/insertAdpTest.js b/test/integration-tests/cve/insertAdpTest.js
index 1ef93f76..a389cfba 100644
--- a/test/integration-tests/cve/insertAdpTest.js
+++ b/test/integration-tests/cve/insertAdpTest.js
@@ -41,7 +41,7 @@ describe('Testing ADP insert Endpoint', () => {
     it('Reserve ADP ', async () => {
       await reserveAdp(cveId, constants.nonSecretariatUserHeaders, constants.testAdp).then((res, err) => {
         expect(err).to.be.undefined
-        const resMessage = cveId + ' record had new ADP container ' + adpLength + ' successfully inserted'
+        const resMessage = cveId + ' record had new ADP container for org ' + shortName + ' successfully inserted'
         expect(res.body.message).to.include(resMessage)
         expect(res.body.updated.containers.adp).to.have.length(adpLength)
 
diff --git a/test/integration-tests/org/postOrgUsersTest.js b/test/integration-tests/org/postOrgUsersTest.js
new file mode 100644
index 00000000..6ca02003
--- /dev/null
+++ b/test/integration-tests/org/postOrgUsersTest.js
@@ -0,0 +1,187 @@
+/* eslint-disable no-unused-expressions */
+const chai = require('chai')
+chai.use(require('chai-http'))
+const expect = chai.expect
+const { faker } = require('@faker-js/faker')
+
+const constants = require('../constants.js')
+const app = require('../../../src/index.js')
+const getConstants = require('../../../src/constants').getConstants
+const argon2 = require('argon2')
+const _ = require('lodash')
+const User = require('../../../src/model/user')
+const cryptoRandomString = require('crypto-random-string')
+
+const shortName = { shortname: 'win_5' }
+
+describe('Testing user post endpoint', () => {
+  let orgUuid
+  context('Positive Tests', () => {
+    it('Allows creation of user', async () => {
+      await chai.request(app)
+        .post('/api/org/win_5/user')
+        .set({ ...constants.headers, ...shortName })
+        .send({
+          username: 'fakeuser999',
+          name: {
+            first: 'Dave',
+            last: 'FakeLastName',
+            middle: 'Cool',
+            suffix: 'Mr.'
+          },
+          authority: {
+            active_roles: [
+              'ADMIN'
+            ]
+          }
+        })
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          orgUuid = res.body.created.org_UUID
+        })
+    })
+  })
+  context('Negitive Test', () => {
+    it('Fails creation of user for bad long first name', async () => {
+      await chai.request(app)
+        .post('/api/org/win_5/user')
+        .set({ ...constants.headers, ...shortName })
+        .send({
+          username: 'fakeuser9999',
+          name: {
+            first: 'VerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnm1',
+            last: 'FakeLastName',
+            middle: 'Cool',
+            suffix: 'Mr.'
+          },
+          authority: {
+            active_roles: [
+              'ADMIN'
+            ]
+          }
+        })
+        .then((res, err) => {
+          expect(res).to.have.status(400)
+          expect(_.some(res.body.details, { msg: 'Invalid name.first. Name must be between 1 and 100 characters in length.' })).to.be.true
+          expect(err).to.be.undefined
+        })
+    })
+    it('Fails creation of user for bad long last name', async () => {
+      await chai.request(app)
+        .post('/api/org/win_5/user')
+        .set({ ...constants.headers, ...shortName })
+        .send({
+          username: 'fakeuser1000',
+          name: {
+            first: 'FirstName',
+            last: 'VerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnm1',
+            middle: 'Cool',
+            suffix: 'Mr.'
+          },
+          authority: {
+            active_roles: [
+              'ADMIN'
+            ]
+          }
+        })
+        .then((res, err) => {
+          expect(res).to.have.status(400)
+          expect(_.some(res.body.details, { msg: 'Invalid name.last. Name must be between 1 and 100 characters in length.' })).to.be.true
+          expect(err).to.be.undefined
+        })
+    })
+    it('Fails creation of user for bad long middle name', async () => {
+      await chai.request(app)
+        .post('/api/org/win_5/user')
+        .set({ ...constants.headers, ...shortName })
+        .send({
+          username: 'fakeuser1001',
+          name: {
+            first: 'FirstName',
+            last: 'LastName',
+            middle: 'VerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnm1',
+            suffix: 'Mr.'
+          },
+          authority: {
+            active_roles: [
+              'ADMIN'
+            ]
+          }
+        })
+        .then((res, err) => {
+          expect(res).to.have.status(400)
+          expect(_.some(res.body.details, { msg: 'Invalid name.middle. Name must be between 1 and 100 characters in length.' })).to.be.true
+          expect(err).to.be.undefined
+        })
+    })
+    it('Fails creation of user for bad long suffix name', async () => {
+      await chai.request(app)
+        .post('/api/org/win_5/user')
+        .set({ ...constants.headers, ...shortName })
+        .send({
+          username: 'fakeuser1002',
+          name: {
+            first: 'FirstName',
+            last: 'LastName',
+            middle: 'MiddleName',
+            suffix: 'VerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnmVerylongnm1'
+          },
+          authority: {
+            active_roles: [
+              'ADMIN'
+            ]
+          }
+        })
+        .then((res, err) => {
+          expect(res).to.have.status(400)
+          expect(_.some(res.body.details, { msg: 'Invalid name.suffix. Name must be between 1 and 100 characters in length.' })).to.be.true
+          expect(err).to.be.undefined
+        })
+    })
+    it('Fails creation of user for trying to add the 101th user', async () => {
+      const numberOfUsers = await User.where({ org_UUID: orgUuid }).countDocuments().exec()
+      for (let i = 0; i < (100 - numberOfUsers); i++) {
+        const newUser = new User()
+
+        newUser.name.first = faker.name.firstName()
+        newUser.name.last = faker.name.lastName()
+        newUser.username = faker.internet.userName({ firstName: newUser.name.first, lastName: newUser.name.last })
+        newUser.org_UUID = orgUuid
+        newUser.UUID = faker.datatype.uuid()
+        const randomKey = cryptoRandomString({ length: getConstants().CRYPTO_RANDOM_STRING_LENGTH })
+        newUser.secret = await argon2.hash(randomKey)
+
+        newUser.authority = {
+          active_roles: [
+            'ADMIN'
+          ]
+        }
+
+        await User.findOneAndUpdate().byUserNameAndOrgUUID(newUser.userName, newUser.org_UUID).updateOne(newUser).setOptions({ upsert: true })
+      }
+
+      await chai.request(app)
+        .post('/api/org/win_5/user')
+        .set({ ...constants.headers, ...shortName })
+        .send({
+          username: 'Fake101User',
+          name: {
+            first: 'Dave',
+            last: 'FakeLastName',
+            middle: 'Cool',
+            suffix: 'Mr.'
+          },
+          authority: {
+            active_roles: [
+              'ADMIN'
+            ]
+          }
+        })
+        .then((res, err) => {
+          expect(err).to.be.undefined
+          expect(res).to.have.status(400)
+          expect(res.body.error).to.contain('NUMBER_OF_USERS_IN_ORG_LIMIT_REACHED')
+        })
+    })
+  })
+})
diff --git a/test/unit-tests/cve/insertAdpTest.js b/test/unit-tests/cve/insertAdpTest.js
index ca8c2f28..310b98ae 100644
--- a/test/unit-tests/cve/insertAdpTest.js
+++ b/test/unit-tests/cve/insertAdpTest.js
@@ -135,7 +135,7 @@ describe('Testing insertAdp function', () => {
     it('Should add an ADP container to an existing CVE record', async () => {
       const adpCount = cveCopy.containers.adp.length
 
-      const resMessage = cveIdPublished5 + ' record had new ADP container ' + (adpCount + 1) + ' successfully inserted'
+      const resMessage = cveIdPublished5 + ' record had new ADP container for org ' + stubAdpOrg.short_name + ' successfully inserted'
       await CVE_INSERT_ADP(req, res, next)
 
       expect(status.args[0][0]).to.equal(200)
@@ -172,7 +172,7 @@ describe('Testing insertAdp function', () => {
       }
 
       const adpCount = cveCopy.containers.adp.length
-      const resMessage = cveIdPublished5 + ' record had replacement ADP container ' + adpCount + ' successfully inserted'
+      const resMessage = cveIdPublished5 + ' record had replacement ADP container for org ' + stubAdpOrg.short_name + ' successfully inserted'
       await CVE_INSERT_ADP(req, res, next)
 
       expect(status.args[0][0]).to.equal(200)
diff --git a/test/unit-tests/middleware/onlyOrgWithPartnerRoleTest.js b/test/unit-tests/middleware/onlyOrgWithPartnerRoleTest.js
new file mode 100644
index 00000000..789588a3
--- /dev/null
+++ b/test/unit-tests/middleware/onlyOrgWithPartnerRoleTest.js
@@ -0,0 +1,189 @@
+/* eslint-disable no-unused-expressions */
+
+const chai = require('chai')
+const sinon = require('sinon')
+const { faker } = require('@faker-js/faker')
+const expect = chai.expect
+
+const OrgRepository = require('../../../src/repositories/orgRepository.js')
+const { onlyOrgWithPartnerRole } = require('../../../src/middleware/middleware.js')
+const errors = require('../../../src/middleware/error.js')
+const error = new errors.MiddlewareError()
+
+const stubAdpOrg = {
+  short_name: 'adpOrg',
+  name: 'test_adp',
+  UUID: faker.datatype.uuid(),
+  authority: {
+    active_roles: [
+      'ADP'
+    ]
+  }
+}
+
+const stubCnaOrg = {
+  short_name: 'cnaOrg',
+  name: 'test_cna',
+  UUID: faker.datatype.uuid(),
+  authority: {
+    active_roles: [
+      'CNA'
+    ]
+  }
+}
+
+const stubBulkDownloadOrg = {
+  short_name: 'bdOrg',
+  name: 'test_bd',
+  UUID: faker.datatype.uuid(),
+  authority: {
+    active_roles: [
+      'BULK_DOWNLOAD'
+    ]
+  }
+}
+
+const stubOrgNoRole = {
+  short_name: 'NoRole',
+  name: 'test_org',
+  UUID: faker.datatype.uuid(),
+  authority: {
+    active_roles: []
+  }
+}
+
+const stubSecretariat = {
+  short_name: 'secOrg',
+  name: 'test_sec',
+  UUID: faker.datatype.uuid(),
+  authority: {
+    active_roles: [
+      'SECRETARIAT'
+    ]
+  }
+}
+
+describe('Testing onlyOrgWithPartnerRole middleware', () => {
+  let status, json, res, next, getOrgRepository, orgRepo
+  beforeEach(() => {
+    status = sinon.stub()
+    json = sinon.spy()
+    res = { json, status }
+    next = sinon.spy()
+    status.returns(res)
+    orgRepo = new OrgRepository()
+    getOrgRepository = sinon.stub()
+    getOrgRepository.returns(orgRepo)
+  })
+  context('Negative Tests', () => {
+    it('Should return 403 for users from orgs without a partner role ', async () => {
+      const req = {
+        ctx: {
+          org: stubBulkDownloadOrg.short_name,
+          uuid: stubBulkDownloadOrg.UUID,
+          repositories: {
+            getOrgRepository
+          }
+        }
+      }
+      const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubBulkDownloadOrg)
+
+      await onlyOrgWithPartnerRole(req, res, next)
+      expect(stub.calledOnce).to.be.true
+      expect(status.calledOnce).to.be.true
+      expect(status.args[0][0]).to.equal(403)
+      expect(res.json.args[0][0].error).to.equal(error.orgHasNoPartnerRole().error)
+    })
+    it('Should return 403 for users from orgs without a role ', async () => {
+      const req = {
+        ctx: {
+          org: stubOrgNoRole.short_name,
+          uuid: stubOrgNoRole.UUID,
+          repositories: {
+            getOrgRepository
+          }
+        }
+      }
+      const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubOrgNoRole)
+
+      await onlyOrgWithPartnerRole(req, res, next)
+      expect(stub.calledOnce).to.be.true
+      expect(status.calledOnce).to.be.true
+      expect(status.args[0][0]).to.equal(403)
+      expect(res.json.args[0][0].error).to.equal(error.orgHasNoPartnerRole().error)
+    })
+
+    it('Should return 404 if the requester org does not exist', async () => {
+      const req = {
+        ctx: {
+          org: stubCnaOrg.short_name,
+          uuid: stubCnaOrg.UUID,
+          repositories: {
+            getOrgRepository
+          }
+        }
+      }
+      const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(null)
+
+      await onlyOrgWithPartnerRole(req, res, next)
+      expect(stub.calledOnce).to.be.true
+      expect(status.calledOnce).to.be.true
+      expect(status.args[0][0]).to.equal(404)
+      expect(res.json.args[0][0].error).to.equal(error.orgDoesNotExist(stubCnaOrg.short_name).error)
+    })
+  })
+
+  context('Positive Tests', () => {
+    it('Should allow orgs with ADP partner role through by calling next()  ', async () => {
+      const req = {
+        ctx: {
+          org: stubAdpOrg.short_name,
+          uuid: stubAdpOrg.UUID,
+          repositories: {
+            getOrgRepository
+          }
+        }
+      }
+      const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubAdpOrg)
+
+      await onlyOrgWithPartnerRole(req, res, next)
+      expect(stub.calledOnce).to.be.true
+      expect(status.calledOnce).to.be.false
+      expect(next.calledOnce).to.be.true
+    })
+    it('Should allow orgs with CNA partner role through by calling next()  ', async () => {
+      const req = {
+        ctx: {
+          org: stubCnaOrg.short_name,
+          uuid: stubCnaOrg.UUID,
+          repositories: {
+            getOrgRepository
+          }
+        }
+      }
+      const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubCnaOrg)
+
+      await onlyOrgWithPartnerRole(req, res, next)
+      expect(stub.calledOnce).to.be.true
+      expect(status.calledOnce).to.be.false
+      expect(next.calledOnce).to.be.true
+    })
+    it('Should allow orgs with Secretariat role through by calling next()  ', async () => {
+      const req = {
+        ctx: {
+          org: stubSecretariat.short_name,
+          uuid: stubSecretariat.UUID,
+          repositories: {
+            getOrgRepository
+          }
+        }
+      }
+      const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubSecretariat)
+
+      await onlyOrgWithPartnerRole(req, res, next)
+      expect(stub.calledOnce).to.be.true
+      expect(status.calledOnce).to.be.false
+      expect(next.calledOnce).to.be.true
+    })
+  })
+})
diff --git a/test/unit-tests/user/userCreateTest.js b/test/unit-tests/user/userCreateTest.js
index 7c527104..ea3b1fce 100644
--- a/test/unit-tests/user/userCreateTest.js
+++ b/test/unit-tests/user/userCreateTest.js
@@ -1,506 +1,89 @@
-const express = require('express')
-const app = express()
+
+const sinon = require('sinon')
 const chai = require('chai')
 const expect = chai.expect
-chai.use(require('chai-http'))
-
-// Body Parser Middleware
-app.use(express.json()) // Allows us to handle raw JSON data
-app.use(express.urlencoded({ extended: false })) // Allows us to handle url encoded data
-const middleware = require('../../../src/middleware/middleware')
-app.use(middleware.createCtxAndReqUUID)
-
-const getConstants = require('../../../src/constants').getConstants
-const errors = require('../../../src/controller/org.controller/error')
-const error = new errors.OrgControllerError()
-
-const userFixtures = require('./mockObjects.user')
-const orgController = require('../../../src/controller/org.controller/org.controller')
-const orgParams = require('../../../src/controller/org.controller/org.middleware')
-
-class NullUserRepo {
-  async getUserUUID () {
-    return null
-  }
-
-  async findOneByUserNameAndOrgUUID () {
-    return null
-  }
-
-  async isAdmin () {
-    return null
-  }
-}
-
-class OrgCreatedUserOrgUndefined {
-  async isSecretariatUUID () {
-    return true
-  }
-
-  async getOrgUUID () {
-    return userFixtures.existentOrg.UUID
-  }
-
-  async findOneByUUID () {
-    return userFixtures.existentOrg
-  }
-}
-
-class UserCreatedOrgUndefined {
-  async findOneByUserNameAndOrgUUID () {
-    return null
-  }
-
-  async updateByUserNameAndOrgUUID () {
-    return null
-  }
-
-  async getUserUUID () {
-    return null
-  }
-
-  async isAdminUUID () {
-    return false
-  }
-}
-
-class OrgCreatedUserWithRole {
-  async isSecretariatUUID () {
-    return true
-  }
-
-  async getOrgUUID () {
-    return userFixtures.existentOrgDummy.UUID
-  }
-
-  async findOneByUUID () {
-    return userFixtures.existentOrgDummy
-  }
-}
+const { faker } = require('@faker-js/faker')
 
-class UserCreatedAdminWithRole {
-  constructor () {
-    const CONSTANTS = getConstants()
+const { USER_CREATE_SINGLE } = require('../../../src/controller/org.controller/org.controller')
 
-    this.testRes1 = JSON.parse(JSON.stringify(userFixtures.userC))
-    this.testRes1.authority.active_roles[0] = CONSTANTS.USER_ROLE_ENUM.ADMIN
-  }
+const UserRepository = require('../../../src/repositories/userRepository')
+const OrgRepository = require('../../../src/repositories/orgRepository')
 
-  async findOneByUserNameAndOrgUUID () {
-    return null
-  }
-
-  async isAdminUUID () {
-    return true
-  }
-
-  async updateByUserNameAndOrgUUID () {
-    return null
-  }
-
-  async getUserUUID () {
-    return null
-  }
+const stubOrgUUID = faker.datatype.uuid()
 
-  async aggregate () {
-    return [this.testRes1]
+const stubOrg = {
+  short_name: 'stubOrg',
+  name: 'test_user',
+  UUID: stubOrgUUID,
+  authority: {
+    active_roles: ['ADMIN', 'CNA']
   }
 }
 
-class OrgCantCreateUserOrgDoesNotMatch {
-  async getOrgUUID () {
-    return userFixtures.existentOrg.UUID
-  }
+const stubUser = {
+  username: 'stubUser',
+  org_UUID: stubOrgUUID,
+  UUID: faker.datatype.uuid()
 }
 
 describe('Testing the POST /org/:shortname/user endpoint in Org Controller', () => {
-  context('Negative Tests', () => {
-    it('User is not created because org does not exist', (done) => {
-      class OrgCantCreateUserOrgDoesNotExist {
-        async getOrgUUID () {
-          return null
-        }
-      }
-
-      app.route('/user-not-created-org-does-not-exist/:shortname')
-        .post((req, res, next) => {
-          const factory = {
-            getOrgRepository: () => { return new OrgCantCreateUserOrgDoesNotExist() },
-            getUserRepository: () => { return new NullUserRepo() }
-          }
-          req.ctx.repositories = factory
-          next()
-        }, orgParams.parsePostParams, orgController.USER_CREATE_SINGLE)
-
-      chai.request(app)
-        .post(`/user-not-created-org-does-not-exist/${userFixtures.nonExistentOrg.short_name}`)
-        .set(userFixtures.secretariatHeader)
-        .send(userFixtures.nonExistentUser)
-        .end((err, res) => {
-          if (err) {
-            done(err)
-          }
-
-          expect(res).to.have.status(404)
-          expect(res).to.have.property('body').and.to.be.a('object')
-          const errObj = error.orgDnePathParam(userFixtures.nonExistentOrg.short_name)
-          expect(res.body.error).to.equal(errObj.error)
-          expect(res.body.message).to.equal(errObj.message)
-          done()
-        })
-    })
-
-    it('Param org\'s UUID is provided', (done) => {
-      app.route('/user-not-created-org-uuid-provided/:shortname')
-        .post((req, res, next) => {
-          const factory = {
-            getOrgRepository: () => { return new OrgCantCreateUserOrgDoesNotMatch() },
-            getUserRepository: () => { return new NullUserRepo() }
-          }
-          req.ctx.repositories = factory
-          next()
-        }, orgParams.parsePostParams, orgController.USER_CREATE_SINGLE)
-
-      chai.request(app)
-        .post(`/user-not-created-org-uuid-provided/${userFixtures.existentOrg.short_name}`)
-        .set(userFixtures.secretariatHeader)
-        .send(userFixtures.existentUser)
-        .end((err, res) => {
-          if (err) {
-            done(err)
-          }
-
-          expect(res).to.have.status(400)
-          expect(res).to.have.property('body').and.to.be.a('object')
-          const errObj = error.uuidProvided('user')
-          expect(res.body.error).to.equal(errObj.error)
-          expect(res.body.message).to.equal(errObj.message)
-          done()
-        })
-    })
-
-    it('Param user\'s UUID is provided', (done) => {
-      app.route('/user-not-created-user-uuid-provided/:shortname')
-        .post((req, res, next) => {
-          const factory = {
-            getOrgRepository: () => { return new OrgCantCreateUserOrgDoesNotMatch() },
-            getUserRepository: () => { return new UserCreatedOrgUndefined() }
-          }
-          req.ctx.repositories = factory
-          next()
-        }, orgParams.parsePostParams, orgController.USER_CREATE_SINGLE)
-
-      chai.request(app)
-        .post(`/user-not-created-user-uuid-provided/${userFixtures.existentOrg.short_name}`)
-        .set(userFixtures.secretariatHeader)
-        .send(userFixtures.nonExistentUser)
-        .end((err, res) => {
-          if (err) {
-            done(err)
-          }
-
-          expect(res).to.have.status(400)
-          expect(res).to.have.property('body').and.to.be.a('object')
-          const errObj = error.uuidProvided('user')
-          expect(res.body.error).to.equal(errObj.error)
-          expect(res.body.message).to.equal(errObj.message)
-          done()
-        })
-    })
-
-    it('User is not created because it already exists', (done) => {
-      class UserNotCreatedAlreadyExists {
-        async findOneByUserNameAndOrgUUID () {
-          return userFixtures.existentUser
-        }
-
-        async isAdminUUID () {
-          return false
-        }
-      }
-
-      app.route('/user-not-created-already-exists/:shortname')
-        .post((req, res, next) => {
-          const factory = {
-            getOrgRepository: () => { return new OrgCreatedUserOrgUndefined() },
-            getUserRepository: () => { return new UserNotCreatedAlreadyExists() }
-          }
-          req.ctx.repositories = factory
-          next()
-        }, orgParams.parsePostParams, orgController.USER_CREATE_SINGLE)
-
-      const testUser = Object.assign({}, userFixtures.existentUser)
-      delete testUser.UUID
-      delete testUser.org_UUID
-
-      chai.request(app)
-        .post(`/user-not-created-already-exists/${userFixtures.existentOrg.short_name}`)
-        .set(userFixtures.secretariatHeader)
-        .send(testUser)
-        .end((err, res) => {
-          if (err) {
-            done(err)
-          }
-
-          expect(res).to.have.status(400)
-          expect(res).to.have.property('body').and.to.be.a('object')
-          const errObj = error.userExists(userFixtures.existentUser.username)
-          expect(res.body.error).to.equal(errObj.error)
-          expect(res.body.message).to.equal(errObj.message)
-          done()
-        })
-    })
-
-    it('User is not created because the requester is not an Org Admin user from the same org and is not the secretariat', done => {
-      class UserNotCreated {
-        async isAdminUUID () {
-          return true
+  let status, json, res, next, orgRepo, getOrgRepository, getUserRepository, userRepo, req, getOrg
+
+  beforeEach(() => {
+    status = sinon.stub()
+    json = sinon.spy()
+    res = { json, status }
+    next = sinon.spy()
+    status.returns(res)
+
+    userRepo = new UserRepository()
+    getUserRepository = sinon.stub()
+    getUserRepository.returns(userRepo)
+
+    orgRepo = new OrgRepository()
+    getOrgRepository = sinon.stub()
+    getOrgRepository.returns(orgRepo)
+    // May have to replace this based on tests
+    getOrg = sinon.stub(orgRepo, 'getOrgUUID').returns(stubOrgUUID)
+    sinon.stub(userRepo, 'findUsersByOrgUUID').returns(1)
+    sinon.stub(orgRepo, 'isSecretariatUUID').returns(false)
+    sinon.stub(userRepo, 'isAdminUUID').returns(true)
+    sinon.stub(userRepo, 'findOneByUserNameAndOrgUUID').returns(null)
+    sinon.stub(userRepo, 'updateByUserNameAndOrgUUID').returns(true)
+    sinon.stub(userRepo, 'aggregate').returns([stubUser])
+    sinon.stub(userRepo, 'getUserUUID').returns(stubUser.UUID)
+
+    req = {
+      ctx: {
+        org: stubOrg.short_name,
+        uuid: stubOrg.UUID,
+        params: {
+
+        },
+        repositories: {
+          getOrgRepository,
+          getUserRepository
+        },
+        body: {
+          stubUser
         }
       }
-
-      class OrgCantCreateUserNotSecretariatOrAdmin {
-        async isSecretariatUUID () {
-          return false
-        }
-
-        async getOrgUUID (shortname) {
-          if (shortname === userFixtures.existentOrgDummy.short_name) {
-            return userFixtures.existentOrgDummy.UUID
-          }
-
-          return userFixtures.owningOrg.UUID
-        }
-
-        async findOneByUUID (orgUUID) {
-          if (orgUUID === userFixtures.existentOrgDummy.UUID) {
-            return userFixtures.existentOrgDummy
-          }
-
-          return userFixtures.owningOrg
-        }
-      }
-
-      app.route('/user-not-created-not-secretariat-not-same-org-admin/:shortname')
-        .post((req, res, next) => {
-          const factory = {
-            getOrgRepository: () => { return new OrgCantCreateUserNotSecretariatOrAdmin() },
-            getUserRepository: () => { return new UserNotCreated() }
-          }
-          req.ctx.repositories = factory
-          next()
-        }, orgParams.parsePostParams, orgController.USER_CREATE_SINGLE)
-
-      const testUser = Object.assign({}, userFixtures.userA)
-      delete testUser.UUID
-      delete testUser.org_UUID
-      testUser.authority = {
-        active_roles: ['ADMIN']
-      }
-
-      chai.request(app)
-        .post(`/user-not-created-not-secretariat-not-same-org-admin/${userFixtures.existentOrgDummy.short_name}`)
-        .set(userFixtures.owningOrgHeader)
-        .send(testUser)
-        .end((err, res) => {
-          if (err) {
-            done(err)
-          }
-
-          expect(res).to.have.status(403)
-          expect(res).to.have.property('body').and.to.be.a('object')
-          const errObj = error.notOrgAdminOrSecretariat()
-          expect(res.body.error).to.equal(errObj.error)
-          expect(res.body.message).to.equal(errObj.message)
-          done()
-        })
-    })
+    }
   })
-
   context('Positive Tests', () => {
-    it('Requester is secretariat and not Admin: User is created with the "ADMIN" role', done => {
-      class UserCreatedWithRole {
-        constructor () {
-          const CONSTANTS = getConstants()
-
-          this.testRes1 = JSON.parse(JSON.stringify(userFixtures.userA))
-          this.testRes1.authority.active_roles[0] = CONSTANTS.USER_ROLE_ENUM.ADMIN
-        }
-
-        async findOneByUserNameAndOrgUUID () {
-          return null
-        }
-
-        async isAdminUUID () {
-          return false
-        }
-
-        async updateByUserNameAndOrgUUID () {
-          return null
-        }
-
-        async getUserUUID () {
-          return null
-        }
-
-        async aggregate () {
-          return [this.testRes1]
-        }
-      }
-
-      app.route('/user-created-secretariat-not-admin/:shortname')
-        .post((req, res, next) => {
-          const factory = {
-            getOrgRepository: () => { return new OrgCreatedUserWithRole() },
-            getUserRepository: () => { return new UserCreatedWithRole() }
-          }
-          req.ctx.repositories = factory
-          next()
-        }, orgParams.parsePostParams, orgController.USER_CREATE_SINGLE)
-
-      const testUser = JSON.parse(JSON.stringify(userFixtures.userA))
-      delete testUser.UUID
-      delete testUser.org_UUID
-      testUser.authority = {
-        active_roles: ['ADMIN']
-      }
-
-      chai.request(app)
-        .post(`/user-created-secretariat-not-admin/${userFixtures.existentOrgDummy.short_name}`)
-        .set(userFixtures.secretariatHeader)
-        .send(testUser)
-        .end((err, res) => {
-          if (err) {
-            done(err)
-          }
-
-          expect(res).to.have.status(200)
-          expect(res).to.have.property('body').and.to.be.a('object')
-          expect(res.body).to.have.property('message').and.to.be.a('string')
-          expect(res.body.message).to.equal(testUser.username + ' was successfully created.')
-          expect(res.body).to.have.property('created').and.to.be.a('object')
-          expect(res.body.created).to.have.property('org_UUID').and.to.equal(userFixtures.existentOrgDummy.UUID)
-          expect(res.body.created).to.have.property('username').and.to.equal(testUser.username)
-          expect(res.body.created).to.have.nested.property('authority.active_roles').and.to.have.lengthOf(1)
-          expect(res.body.created.authority.active_roles[0]).to.equal(testUser.authority.active_roles[0])
-          done()
-        })
-    })
-
-    it('Requester is Admin and is not secretariat: User is created with the "ADMIN" role', done => {
-      class OrgCreatedUserAdminWithRole {
-        async isSecretariatUUID () {
-          return false
-        }
-
-        async getOrgUUID () {
-          return userFixtures.existentOrgDummy.UUID
-        }
-
-        async findOneByUUID () {
-          return userFixtures.existentOrgDummy
-        }
-      }
-
-      app.route('/user-created-not-secretariat-same-org-admin/:shortname')
-        .post((req, res, next) => {
-          const factory = {
-            getOrgRepository: () => { return new OrgCreatedUserAdminWithRole() },
-            getUserRepository: () => { return new UserCreatedAdminWithRole() }
-          }
-          req.ctx.repositories = factory
-          next()
-        }, orgParams.parsePostParams, orgController.USER_CREATE_SINGLE)
-
-      userFixtures.userA.authority.active_roles = ['ADMIN']
-
-      const testUser = JSON.parse(JSON.stringify(userFixtures.userC))
-      delete testUser.UUID
-      delete testUser.org_UUID
-      testUser.authority = {
-        active_roles: ['ADMIN']
-      }
-
-      chai.request(app)
-        .post(`/user-created-not-secretariat-same-org-admin/${userFixtures.existentOrgDummy.short_name}`)
-        .set(userFixtures.userAHeader)
-        .send(testUser)
-        .end((err, res) => {
-          if (err) {
-            done(err)
-          }
-
-          expect(res).to.have.status(200)
-          expect(res).to.have.property('body').and.to.be.a('object')
-          expect(res.body).to.have.property('message').and.to.be.a('string')
-          expect(res.body.message).to.equal(testUser.username + ' was successfully created.')
-          expect(res.body).to.have.property('created').and.to.be.a('object')
-          expect(res.body.created).to.have.property('org_UUID').and.to.equal(userFixtures.existentOrgDummy.UUID)
-          expect(res.body.created).to.have.property('username').and.to.equal(testUser.username)
-          expect(res.body.created).to.have.nested.property('authority.active_roles').and.to.have.lengthOf(1)
-          expect(res.body.created.authority.active_roles[0]).to.equal(testUser.authority.active_roles[0])
-          userFixtures.userA.authority.active_roles = []
-          done()
-        })
+    it('User is created', async () => {
+      await USER_CREATE_SINGLE(req, res, next)
+      expect(status.args[0][0]).to.equal(200)
+      expect(res.json.args[0][0].message).contains('was successfully created')
     })
-
-    it('Requester is secretariat and Admin: User is created without a user role', done => {
-      class UserCreatedAdminWithoutRole {
-        async findOneByUserNameAndOrgUUID () {
-          return null
-        }
-
-        async isAdminUUID () {
-          return true
-        }
-
-        async updateByUserNameAndOrgUUID () {
-          return null
-        }
-
-        async getUserUUID () {
-          return null
-        }
-
-        async aggregate () {
-          return [userFixtures.userA]
-        }
-      }
-
-      app.route('/user-created-secretariat-same-org-admin/:shortname')
-        .post((req, res, next) => {
-          const factory = {
-            getOrgRepository: () => { return new OrgCreatedUserWithRole() },
-            getUserRepository: () => { return new UserCreatedAdminWithoutRole() }
-          }
-          req.ctx.repositories = factory
-          next()
-        }, orgParams.parsePostParams, orgController.USER_CREATE_SINGLE)
-
-      userFixtures.existentUser.authority.active_roles = ['ADMIN']
-      const testUser = JSON.parse(JSON.stringify(userFixtures.userA))
-      delete testUser.UUID
-      delete testUser.org_UUID
-
-      chai.request(app)
-        .post(`/user-created-secretariat-same-org-admin/${userFixtures.existentOrgDummy.short_name}`)
-        .set(userFixtures.secretariatHeader)
-        .send(testUser)
-        .end((err, res) => {
-          if (err) {
-            done(err)
-          }
-
-          expect(res).to.have.status(200)
-          expect(res).to.have.property('body').and.to.be.a('object')
-          expect(res.body).to.have.property('message').and.to.be.a('string')
-          expect(res.body.message).to.equal(userFixtures.userA.username + ' was successfully created.')
-          expect(res.body).to.have.property('created').and.to.be.a('object')
-          expect(res.body.created).to.have.property('org_UUID').and.to.equal(userFixtures.existentOrgDummy.UUID)
-          expect(res.body.created).to.have.property('username').and.to.equal(userFixtures.userA.username)
-          expect(res.body.created).to.have.nested.property('authority.active_roles').and.to.have.lengthOf(0)
-          userFixtures.existentUser.authority.active_roles = []
-          done()
-        })
+  })
+  context('Negitive tests', () => {
+    it('User Fails to be created because not in the same org', async () => {
+      req.ctx.org = 'FakeShortName'
+      getOrg.withArgs('FakeShortName').returns('FAKEUUID')
+      await USER_CREATE_SINGLE(req, res, next)
+      expect(status.args[0][0]).to.equal(403)
+      expect(res.json.args[0][0].error).contains('NOT_ORG_ADMIN_OR_SECRETARIAT')
     })
   })
 })