|
| 1 | +package org.openhorizon.exchangeapi.route.administration |
| 2 | +import scala.collection.immutable.List |
| 3 | +import scala.collection.mutable.ListBuffer |
| 4 | +import org.openhorizon.exchangeapi.table.organization.OrgRow |
| 5 | +import org.openhorizon.exchangeapi.utility.{ApiTime, Configuration} |
| 6 | +import org.json4s.DefaultFormats |
| 7 | +import org.json4s.jackson.JsonMethods.parse |
| 8 | +import org.junit.runner.RunWith |
| 9 | +import org.scalatest.BeforeAndAfterAll |
| 10 | +import org.scalatest.funsuite.AnyFunSuite |
| 11 | +import org.scalatestplus.junit.JUnitRunner |
| 12 | +import org.openhorizon.exchangeapi.auth.{Password, Role} |
| 13 | +import org.openhorizon.exchangeapi.utility.{ApiUtils, HttpCode} |
| 14 | +import org.openhorizon.exchangeapi.route.administration.{AdminHashpwRequest, AdminHashpwResponse} |
| 15 | +import org.json4s.jackson.Serialization.write |
| 16 | +import scalaj.http.Http |
| 17 | +import org.openhorizon.exchangeapi.route.organization.PostPutOrgRequest |
| 18 | +import org.openhorizon.exchangeapi.route.service.PostPutServiceRequest |
| 19 | +import org.openhorizon.exchangeapi.route.node.PutNodesRequest |
| 20 | +import org.openhorizon.exchangeapi.route.agreementbot.PutAgbotsRequest |
| 21 | +import org.openhorizon.exchangeapi.route.deploymentpattern.PostPutPatternRequest |
| 22 | +import org.openhorizon.exchangeapi.route.user.PostPutUsersRequest |
| 23 | +import org.openhorizon.exchangeapi.table.deploymentpattern.{PServiceVersions, PServices} |
| 24 | +@RunWith(classOf[JUnitRunner]) |
| 25 | +class TestPostAdminHashpw extends AnyFunSuite with BeforeAndAfterAll { |
| 26 | + |
| 27 | + private val ACCEPT = ("Accept", "application/json") |
| 28 | + private val ACCEPTTEXT = ("Accept", "text/plain") |
| 29 | + private val AGBOT: String = "agbot" |
| 30 | + private val CONTENT = ("Content-Type", "application/json") |
| 31 | + private val NODE: String = "node" |
| 32 | + private val PATTERN: String = "pattern" |
| 33 | + private val ROOTAUTH = ("Authorization","Basic " + ApiUtils.encode(Role.superUser + ":" + (try Configuration.getConfig.getString("api.root.password") catch { case _: Exception => "" }))) |
| 34 | + private val SERVICE: String = "service" |
| 35 | + private val URL = sys.env.getOrElse("EXCHANGE_URL_ROOT", "http://localhost:8080") + "/v1" |
| 36 | + private val USERS: List[String] = List("admin", "user") |
| 37 | + private val ORGS: List[String] = List("adminsuite", "root") |
| 38 | + private val hubadmin = "AdminSuitTestsHubAdmin" |
| 39 | + private val urlRootOrg = URL + "/orgs/root" |
| 40 | + private val pw = "password" |
| 41 | + private val HUBADMINAUTH = ("Authorization", "Basic " + ApiUtils.encode("root/"+hubadmin+":"+pw)) |
| 42 | + private val orgsList = List(ORGS.head) |
| 43 | + private var resources = new ListBuffer[String]() |
| 44 | + |
| 45 | + implicit val FORMATS: DefaultFormats.type = DefaultFormats // Brings in default date formats etc. |
| 46 | + |
| 47 | + val TESTORGS: Seq[OrgRow] = |
| 48 | + Seq(OrgRow(description = "AdminSuite Test Organization", |
| 49 | + heartbeatIntervals = "", |
| 50 | + label = "", |
| 51 | + lastUpdated = ApiTime.nowUTC, |
| 52 | + limits = "", |
| 53 | + orgId = "admin", |
| 54 | + orgType = "", |
| 55 | + tags = None)) |
| 56 | + |
| 57 | + override def beforeAll(): Unit = { |
| 58 | + Http(URL + "/orgs/" + ORGS(0)).postData(write(PostPutOrgRequest(None, (ORGS(0)), "AdminSuite Test Organization", None, None, None))).method("post").headers(CONTENT).headers(ACCEPT).headers(ROOTAUTH).asString |
| 59 | + |
| 60 | + for (org <- ORGS) { |
| 61 | + for (user <- USERS) { |
| 62 | + val response = Http(URL + "/orgs/" + org + "/users/" + user).postData(write(PostPutUsersRequest(password="password", admin=user.endsWith("admin") && org!="root", hubAdmin=Some(org=="root"), email=user + "@host.domain"))).method("post").headers(CONTENT).headers(ACCEPT).headers(ROOTAUTH).asString |
| 63 | + assert(response.code == HttpCode.POST_OK.intValue) |
| 64 | + } |
| 65 | + var response = Http(URL + "/orgs/" + org + "/agbots/" + AGBOT).postData(write(PutAgbotsRequest("TokAbcDefGh1234", AGBOT, None, "password"))).method("put").headers(CONTENT).headers(ACCEPT).headers(ROOTAUTH).asString |
| 66 | + assert(response.code == HttpCode.PUT_OK.intValue) |
| 67 | + response = Http(URL + "/orgs/" + org + "/services").postData(write(PostPutServiceRequest(SERVICE, None, public = true, None, URL + "/orgs/" + org + "/services/" + SERVICE, "0.0.1", "test-arch", "multiple", None, None, None, None, None, None, None, None ))).method("post").headers(CONTENT).headers(ACCEPT).headers(ROOTAUTH).asString |
| 68 | + assert(response.code == HttpCode.POST_OK.intValue) |
| 69 | + response = Http(URL + "/orgs/" + org + "/patterns/" + PATTERN).postData(write(PostPutPatternRequest(PATTERN, Some("AdminSuite Test Pattern"), None, List(PServices(URL + "/orgs/" + org + "/services/" + SERVICE, org, "test-arch", None, List(PServiceVersions("0.0.1", None, None, None, None)), None, None)), None, None, None))).method("post").headers(CONTENT).headers(ACCEPT).headers(ROOTAUTH).asString |
| 70 | + assert(response.code == HttpCode.POST_OK.intValue) |
| 71 | + response = Http(URL + "/orgs/" + org + "/nodes/" + NODE).postData(write(PutNodesRequest("TokAbcDefGh1234", NODE, None, org + "/" + PATTERN, None, None, None, None, "password", None, None))).method("put").headers(CONTENT).headers(ACCEPT).headers(ROOTAUTH).asString |
| 72 | + assert(response.code == HttpCode.PUT_OK.intValue) |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + override def afterAll(): Unit = { |
| 77 | + for (org <- ORGS) { |
| 78 | + for (user <- USERS) { |
| 79 | + val response = Http(URL + "/orgs/" + org + "/users/" + user).method("delete").headers(ACCEPT).headers(ROOTAUTH).asString |
| 80 | + assert(response.code == HttpCode.DELETED.intValue) |
| 81 | + } |
| 82 | + |
| 83 | + var response = Http(URL + "/orgs/" + org + "/agbots/" + AGBOT).method("delete").headers(ACCEPT).headers(ROOTAUTH).asString |
| 84 | + assert(response.code == HttpCode.DELETED.intValue) |
| 85 | + response = Http(URL + "/orgs/" + org + "/nodes/" + NODE).method("delete").headers(ACCEPT).headers(ROOTAUTH).asString |
| 86 | + assert(response.code == HttpCode.DELETED.intValue) |
| 87 | + response = Http(URL + "/orgs/" + org + "/patterns/" + PATTERN).method("delete").headers(ACCEPT).headers(ROOTAUTH).asString |
| 88 | + assert(response.code == HttpCode.DELETED.intValue) |
| 89 | + response = Http(URL + "/orgs/" + org + "/services/" + ("/".r.replaceAllIn(("""(http[sS]{0,1}://(www.){0,1}){0,1}""".r.replaceFirstIn(URL, "")), "-")) + "-orgs-" + org + "-services-" + SERVICE + "_0.0.1_test-arch").method("delete").headers(ACCEPT).headers(ROOTAUTH).asString |
| 90 | + assert(response.code == HttpCode.DELETED.intValue) |
| 91 | + } |
| 92 | + |
| 93 | + val response = Http(URL + "/orgs/" + ORGS(0)).method("delete").headers(ACCEPT).headers(ROOTAUTH).asString |
| 94 | + assert(response.code == HttpCode.DELETED.intValue) |
| 95 | + } |
| 96 | + // =============== Hash a Password =============== |
| 97 | + for (org <- ORGS) { |
| 98 | + test("POST /admin/hashpw - " + org + "/" + AGBOT) { |
| 99 | + val input = AdminHashpwRequest("foobar") |
| 100 | + val response = Http(URL + "/admin/hashpw").postData(write(input)).headers(CONTENT).headers(ACCEPT).headers(("Authorization","Basic " + ApiUtils.encode(org + "/" + AGBOT + ":" + "TokAbcDefGh1234"))).asString |
| 101 | + info("http status code: " + response.code) |
| 102 | + info("body: " + response.body) |
| 103 | + assert(response.code === HttpCode.ACCESS_DENIED.intValue) |
| 104 | + } |
| 105 | + } |
| 106 | + |
| 107 | + for (org <- ORGS) { |
| 108 | + test("POST /admin/hashpw - " + org + "/" + NODE) { |
| 109 | + val input = AdminHashpwRequest("foobar") |
| 110 | + val response = Http(URL + "/admin/hashpw").postData(write(input)).headers(CONTENT).headers(ACCEPT).headers(("Authorization","Basic " + ApiUtils.encode(org + "/" + NODE + ":" + "TokAbcDefGh1234"))).asString |
| 111 | + info("http status code: " + response.code) |
| 112 | + info("body: " + response.body) |
| 113 | + assert(response.code === HttpCode.ACCESS_DENIED.intValue) |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + for (org <- ORGS) { |
| 118 | + for (user <- USERS) { |
| 119 | + test("POST /admin/hashpw - " + org + "/" + user) { |
| 120 | + val input = AdminHashpwRequest("foobar") |
| 121 | + val response = Http(URL + "/admin/hashpw").postData(write(input)).headers(CONTENT).headers(ACCEPT).headers(("Authorization","Basic " + ApiUtils.encode(org + "/" + user + ":" + "password"))).asString |
| 122 | + info("http status code: " + response.code) |
| 123 | + info("body: " + response.body) |
| 124 | + assert(response.code === HttpCode.POST_OK.intValue) |
| 125 | + val postResp = parse(response.body).extract[AdminHashpwResponse] |
| 126 | + assert(Password.check(input.password, postResp.hashedPassword)) |
| 127 | + } |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + test("POST /admin/hashpw - root/root") { |
| 132 | + val input = AdminHashpwRequest("foobar") |
| 133 | + val response = Http(URL + "/admin/hashpw").postData(write(input)).headers(CONTENT).headers(ACCEPT).headers(ROOTAUTH).asString |
| 134 | + info("http status code: " + response.code) |
| 135 | + info("body: " + response.body) |
| 136 | + assert(response.code === HttpCode.POST_OK.intValue) |
| 137 | + val postResp = parse(response.body).extract[AdminHashpwResponse] |
| 138 | + assert(Password.check(input.password, postResp.hashedPassword)) |
| 139 | + } |
| 140 | + |
| 141 | + test("POST /admin/hashpw - root/root - Invaild Credentials") { |
| 142 | + val input = AdminHashpwRequest("foobar") |
| 143 | + val response = Http(URL + "/admin/hashpw").postData(write(input)).headers(CONTENT).headers(ACCEPT).headers(("Authorization","Basic " + ApiUtils.encode(Role.superUser + ":" + "invaildcredentials"))).asString |
| 144 | + info("http status code: " + response.code) |
| 145 | + info("body: " + response.body) |
| 146 | + assert(response.code === HttpCode.BADCREDS.intValue) |
| 147 | + } |
| 148 | + |
| 149 | +} |
0 commit comments