{"action":"created","comment":{"url":"https://api.github.com/repos/rackerlabs/api-checker/pulls/comments/38166498","id":38166498,"diff_hunk":"@@ -0,0 +1,279 @@\n+/** *\n+  * Copyright 2014 Rackspace US, Inc.\n+  *\n+  * Licensed under the Apache License, Version 2.0 (the \"License\");\n+  * you may not use this file except in compliance with the License.\n+  * You may obtain a copy of the License at\n+  *\n+  * http://www.apache.org/licenses/LICENSE-2.0\n+  *\n+  * Unless required by applicable law or agreed to in writing, software\n+  * distributed under the License is distributed on an \"AS IS\" BASIS,\n+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+  * See the License for the specific language governing permissions and\n+  * limitations under the License.\n+  */\n+package com.rackspace.com.papi.components.checker\n+\n+import com.rackspace.cloud.api.wadl.Converters._\n+import org.junit.runner.RunWith\n+import org.scalatest.FlatSpec\n+import org.scalatest.junit.JUnitRunner\n+\n+@RunWith(classOf[JUnitRunner])\n+class GivenAWadlWithMetaTransforms extends FlatSpec with RaxRolesBehaviors {\n+\n+  val description = \"WADL With Meta-Transforms\"\n+\n+  val validator = Validator(\n+    (\n+      localWADLURI,\n+      <application xmlns=\"http://wadl.dev.java.net/2009/02\" xmlns:rax=\"http://docs.rackspace.com/api\">\n+        <resources base=\"https://resource.api.rackspace.com\">\n+          <resource id=\"standardResource\" path=\"standard\" rax:useMetadata=\"standardMeta\"/>\n+          <resource id=\"customResource\" path=\"custom\" rax:useMetadata=\"customMeta\"/>\n+          <!--resource id=\"customSubResource\" path=\"custom/sub\" rax:useMetadata=\"customSubMeta\"/-->\n+        </resources>\n+        <rax:metadata id=\"standardMeta\">\n+          <!-- I propose we support very simple patterns * and sameThing: (or anyOther string which will be prepended) -->\n+          <rax:metaRole name=\"admin\" pattern=\"*\"/>\n+          <rax:metaRole name=\"billing:role\" pattern=\"billing:\"/>\n+          <rax:metaRole name=\"service:role\" pattern=\"service:\"/>\n+        </rax:metadata>\n+        <rax:metadata id=\"customMeta\">\n+          <!-- at least one pattern with '*' is required, this is the admin role,\n+               multiple admins are allowed...-->\n+          <rax:metaRole name=\"admin\" pattern=\"*\"/>\n+          <rax:metaRole name=\"superAdmin\" pattern=\"*\"/>\n+          <!-- pattern is optional, if it is left off then the roleName followed by a colon is assumed.\n+               In this case the pattern is 'customer:role:' -->\n+          <rax:metaRole name=\"customer:role\"/>\n+          <!-- multiple roles are allowed as well with the same pattern.\n+               One role per metaRole, since this is an edge case...\n+           -->\n+          <rax:metaRole name=\"service:role\" pattern=\"service:\"/>\n+          <rax:metaRole name=\"another_role\" pattern=\"service:\"/>\n+          <!-- Another edge case regex stuff in the pattern should not mess things up.\n+               This silly combination of role name and pattern should work.\n+               The pattern is not a regEx |||: is simply treated as a string.\n+          -->\n+          <rax:metaRole name=\"???\" pattern=\"|||:\"/>\n+        </rax:metadata>\n+      </application>\n+      )\n+    , configWithRolesEnabled\n+  )\n+  val methodGet = \"GET\"\n+  val methodPut = \"PUT\"\n+  val methodDelete = \"DELETE\"\n+  val methodPost = \"POST\"\n+  val targetStandardFoo = \"/standard/metadata/foo\"\n+  val targetStandardBilling = \"/standard/metadata/billing:foo\"\n+  val targetStandardService = \"/standard/metadata/service:foo\"\n+  val targetCustomFoo = \"/custom/metadata/foo\"\n+  val targetCustomCustomer = \"/custom/metadata/customer:role:\"\n+  val targetCustomService = \"/custom/metadata/service:foo\"\n+  val putContent = <meta/>\n+\n+  val targetsStandard = List(\n+    \"\",\n+    \"billing:\",\n+    \"service:\"\n+  )\n+\n+  val targetsCustom = List(\n+    \"\",\n+    \"customer:role:\",\n+    \"service:\"\n+  )\n+\n+  // http://stackoverflow.com/questions/13109720/how-to-create-all-possible-combinations-from-the-elements-of-a-list\n+  val rolesSet = Set(\"admin\", \"billing:role\", \"service:role\", \"superAdmin\", \"customer:role\", \"another_role\")\n+  val rolesList = rolesSet.subsets.map(_.toList).toList\n+\n+  // Standard GET's are allowed regardless of roles.\n+  targetsStandard.foreach { target =>\n+    rolesList.foreach { roles =>\n+      it should behave like accessIsAllowed(validator, methodGet, s\"/standard/metadata/${target}foo\", roles, description)\n+    }\n+    it should behave like accessIsAllowedWhenNoXRoles(validator, methodGet, s\"/standard/metadata/${target}foo\", description)\n+  }\n+\n+//  // Standard PUT's and DELETE's are allowed or forbidden based on roles.\n+// @TODO: Original double loop with PUT's and DELETE's for Standard targets.\n+//  List(methodPut, methodDelete).foreach { method =>\n+//    targetsStandard.foreach { target =>\n+//      rolesList.foreach { roles =>\n+//        // IF the list of roles contains the target\n+//        // OR the list of roles contains admin,\n+//        // THEN access should be allowed;\n+//        // ELSE access should be forbidden.\n+//        if (targetInRoles(target, roles, List(\"admin\"))) {\n+//          it should behave like accessIsAllowedWithContent(validator, method, s\"/standard/metadata/${target}foo\", roles, putContent, description)\n+//        } else {\n+//          it should behave like accessIsForbidden(validator, method, s\"/standard/metadata/${target}foo\", roles, description)\n+//        }\n+//      }\n+//      it should behave like accessIsForbiddenWhenNoXRoles(validator, method, s\"/standard/metadata/${target}foo\", description)\n+//    }\n+//  }\n+\n+  targetsStandard.foreach { target =>\n+    rolesList.foreach { roles =>\n+      // IF the list of roles contains the target\n+      // OR the list of roles contains admin,\n+      // THEN access should be allowed;\n+      // ELSE access should be forbidden.\n+      if (targetInRoles(target, roles, List(\"admin\"))) {\n+        // @TODO: Huh???\n+        // @TODO: What should the content be?\n+        // @TODO: Do we need the new accessIsAllowedWithContent() method?\n+        // @TODO: Should we just keep the new badRequestWithStockContent() method since we know it made it all the way through?\n+        //it should behave like accessIsAllowed(validator, methodPut, s\"/standard/metadata/${target}foo\", roles, description)\n+        //it should behave like accessIsAllowedWithContent(validator, methodPut, s\"/standard/metadata/${target}foo\", roles, putContent, description)\n+        it should behave like badRequestWithStockContent(validator, methodPut, s\"/standard/metadata/${target}foo\", roles, description)","path":"core/src/test/scala/com/rackspace/com/papi/components/checker/GivenAWadlWithMetaTransforms.scala","position":134,"original_position":134,"commit_id":"77097be12912343f1f886e10a198abe8d1af7d8a","original_commit_id":"77097be12912343f1f886e10a198abe8d1af7d8a","user":{"login":"wdschei","id":7366196,"avatar_url":"https://avatars.githubusercontent.com/u/7366196?v=3","gravatar_id":"","url":"https://api.github.com/users/wdschei","html_url":"https://github.com/wdschei","followers_url":"https://api.github.com/users/wdschei/followers","following_url":"https://api.github.com/users/wdschei/following{/other_user}","gists_url":"https://api.github.com/users/wdschei/gists{/gist_id}","starred_url":"https://api.github.com/users/wdschei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wdschei/subscriptions","organizations_url":"https://api.github.com/users/wdschei/orgs","repos_url":"https://api.github.com/users/wdschei/repos","events_url":"https://api.github.com/users/wdschei/events{/privacy}","received_events_url":"https://api.github.com/users/wdschei/received_events","type":"User","site_admin":false},"body":"When using `accessIsAllowed()` it returns  400 with \"Bad Content: Expecting the root element to be: meta:meta\".","created_at":"2015-08-28T02:16:12Z","updated_at":"2015-08-28T02:16:12Z","html_url":"https://github.com/rackerlabs/api-checker/pull/274#discussion_r38166498","pull_request_url":"https://api.github.com/repos/rackerlabs/api-checker/pulls/274","_links":{"self":{"href":"https://api.github.com/repos/rackerlabs/api-checker/pulls/comments/38166498"},"html":{"href":"https://github.com/rackerlabs/api-checker/pull/274#discussion_r38166498"},"pull_request":{"href":"https://api.github.com/repos/rackerlabs/api-checker/pulls/274"}}},"pull_request":{"url":"https://api.github.com/repos/rackerlabs/api-checker/pulls/274","id":43587252,"html_url":"https://github.com/rackerlabs/api-checker/pull/274","diff_url":"https://github.com/rackerlabs/api-checker/pull/274.diff","patch_url":"https://github.com/rackerlabs/api-checker/pull/274.patch","issue_url":"https://api.github.com/repos/rackerlabs/api-checker/issues/274","number":274,"state":"open","locked":false,"title":"Rep 2604 metadata extension","user":{"login":"wdschei","id":7366196,"avatar_url":"https://avatars.githubusercontent.com/u/7366196?v=3","gravatar_id":"","url":"https://api.github.com/users/wdschei","html_url":"https://github.com/wdschei","followers_url":"https://api.github.com/users/wdschei/followers","following_url":"https://api.github.com/users/wdschei/following{/other_user}","gists_url":"https://api.github.com/users/wdschei/gists{/gist_id}","starred_url":"https://api.github.com/users/wdschei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wdschei/subscriptions","organizations_url":"https://api.github.com/users/wdschei/orgs","repos_url":"https://api.github.com/users/wdschei/repos","events_url":"https://api.github.com/users/wdschei/events{/privacy}","received_events_url":"https://api.github.com/users/wdschei/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-08-28T02:13:59Z","updated_at":"2015-08-28T02:16:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"eee4ff071a2ec7782f444751598fcd8c1124164b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rackerlabs/api-checker/pulls/274/commits","review_comments_url":"https://api.github.com/repos/rackerlabs/api-checker/pulls/274/comments","review_comment_url":"https://api.github.com/repos/rackerlabs/api-checker/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rackerlabs/api-checker/issues/274/comments","statuses_url":"https://api.github.com/repos/rackerlabs/api-checker/statuses/77097be12912343f1f886e10a198abe8d1af7d8a","head":{"label":"wdschei:REP-2604_MetadataExtension","ref":"REP-2604_MetadataExtension","sha":"77097be12912343f1f886e10a198abe8d1af7d8a","user":{"login":"wdschei","id":7366196,"avatar_url":"https://avatars.githubusercontent.com/u/7366196?v=3","gravatar_id":"","url":"https://api.github.com/users/wdschei","html_url":"https://github.com/wdschei","followers_url":"https://api.github.com/users/wdschei/followers","following_url":"https://api.github.com/users/wdschei/following{/other_user}","gists_url":"https://api.github.com/users/wdschei/gists{/gist_id}","starred_url":"https://api.github.com/users/wdschei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wdschei/subscriptions","organizations_url":"https://api.github.com/users/wdschei/orgs","repos_url":"https://api.github.com/users/wdschei/repos","events_url":"https://api.github.com/users/wdschei/events{/privacy}","received_events_url":"https://api.github.com/users/wdschei/received_events","type":"User","site_admin":false},"repo":{"id":33549489,"name":"api-checker","full_name":"wdschei/api-checker","owner":{"login":"wdschei","id":7366196,"avatar_url":"https://avatars.githubusercontent.com/u/7366196?v=3","gravatar_id":"","url":"https://api.github.com/users/wdschei","html_url":"https://github.com/wdschei","followers_url":"https://api.github.com/users/wdschei/followers","following_url":"https://api.github.com/users/wdschei/following{/other_user}","gists_url":"https://api.github.com/users/wdschei/gists{/gist_id}","starred_url":"https://api.github.com/users/wdschei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wdschei/subscriptions","organizations_url":"https://api.github.com/users/wdschei/orgs","repos_url":"https://api.github.com/users/wdschei/repos","events_url":"https://api.github.com/users/wdschei/events{/privacy}","received_events_url":"https://api.github.com/users/wdschei/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wdschei/api-checker","description":"The API Checker library allows checking a rest servlet against a contract written in WADL","fork":true,"url":"https://api.github.com/repos/wdschei/api-checker","forks_url":"https://api.github.com/repos/wdschei/api-checker/forks","keys_url":"https://api.github.com/repos/wdschei/api-checker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wdschei/api-checker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wdschei/api-checker/teams","hooks_url":"https://api.github.com/repos/wdschei/api-checker/hooks","issue_events_url":"https://api.github.com/repos/wdschei/api-checker/issues/events{/number}","events_url":"https://api.github.com/repos/wdschei/api-checker/events","assignees_url":"https://api.github.com/repos/wdschei/api-checker/assignees{/user}","branches_url":"https://api.github.com/repos/wdschei/api-checker/branches{/branch}","tags_url":"https://api.github.com/repos/wdschei/api-checker/tags","blobs_url":"https://api.github.com/repos/wdschei/api-checker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wdschei/api-checker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wdschei/api-checker/git/refs{/sha}","trees_url":"https://api.github.com/repos/wdschei/api-checker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wdschei/api-checker/statuses/{sha}","languages_url":"https://api.github.com/repos/wdschei/api-checker/languages","stargazers_url":"https://api.github.com/repos/wdschei/api-checker/stargazers","contributors_url":"https://api.github.com/repos/wdschei/api-checker/contributors","subscribers_url":"https://api.github.com/repos/wdschei/api-checker/subscribers","subscription_url":"https://api.github.com/repos/wdschei/api-checker/subscription","commits_url":"https://api.github.com/repos/wdschei/api-checker/commits{/sha}","git_commits_url":"https://api.github.com/repos/wdschei/api-checker/git/commits{/sha}","comments_url":"https://api.github.com/repos/wdschei/api-checker/comments{/number}","issue_comment_url":"https://api.github.com/repos/wdschei/api-checker/issues/comments{/number}","contents_url":"https://api.github.com/repos/wdschei/api-checker/contents/{+path}","compare_url":"https://api.github.com/repos/wdschei/api-checker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wdschei/api-checker/merges","archive_url":"https://api.github.com/repos/wdschei/api-checker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wdschei/api-checker/downloads","issues_url":"https://api.github.com/repos/wdschei/api-checker/issues{/number}","pulls_url":"https://api.github.com/repos/wdschei/api-checker/pulls{/number}","milestones_url":"https://api.github.com/repos/wdschei/api-checker/milestones{/number}","notifications_url":"https://api.github.com/repos/wdschei/api-checker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wdschei/api-checker/labels{/name}","releases_url":"https://api.github.com/repos/wdschei/api-checker/releases{/id}","created_at":"2015-04-07T14:50:59Z","updated_at":"2015-04-10T14:34:15Z","pushed_at":"2015-08-28T02:12:41Z","git_url":"git://github.com/wdschei/api-checker.git","ssh_url":"git@github.com:wdschei/api-checker.git","clone_url":"https://github.com/wdschei/api-checker.git","svn_url":"https://github.com/wdschei/api-checker","homepage":"www.openrepose.org","size":3868,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"rackerlabs:master","ref":"master","sha":"c79b2f290e64853a995a1360a5793723370c3a4f","user":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":3188519,"name":"api-checker","full_name":"rackerlabs/api-checker","owner":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars.githubusercontent.com/u/84293?v=3","gravatar_id":"","url":"https://api.github.com/users/rackerlabs","html_url":"https://github.com/rackerlabs","followers_url":"https://api.github.com/users/rackerlabs/followers","following_url":"https://api.github.com/users/rackerlabs/following{/other_user}","gists_url":"https://api.github.com/users/rackerlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/rackerlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rackerlabs/subscriptions","organizations_url":"https://api.github.com/users/rackerlabs/orgs","repos_url":"https://api.github.com/users/rackerlabs/repos","events_url":"https://api.github.com/users/rackerlabs/events{/privacy}","received_events_url":"https://api.github.com/users/rackerlabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rackerlabs/api-checker","description":"The API Checker library allows checking a rest servlet against a contract written in WADL","fork":false,"url":"https://api.github.com/repos/rackerlabs/api-checker","forks_url":"https://api.github.com/repos/rackerlabs/api-checker/forks","keys_url":"https://api.github.com/repos/rackerlabs/api-checker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rackerlabs/api-checker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rackerlabs/api-checker/teams","hooks_url":"https://api.github.com/repos/rackerlabs/api-checker/hooks","issue_events_url":"https://api.github.com/repos/rackerlabs/api-checker/issues/events{/number}","events_url":"https://api.github.com/repos/rackerlabs/api-checker/events","assignees_url":"https://api.github.com/repos/rackerlabs/api-checker/assignees{/user}","branches_url":"https://api.github.com/repos/rackerlabs/api-checker/branches{/branch}","tags_url":"https://api.github.com/repos/rackerlabs/api-checker/tags","blobs_url":"https://api.github.com/repos/rackerlabs/api-checker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rackerlabs/api-checker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rackerlabs/api-checker/git/refs{/sha}","trees_url":"https://api.github.com/repos/rackerlabs/api-checker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rackerlabs/api-checker/statuses/{sha}","languages_url":"https://api.github.com/repos/rackerlabs/api-checker/languages","stargazers_url":"https://api.github.com/repos/rackerlabs/api-checker/stargazers","contributors_url":"https://api.github.com/repos/rackerlabs/api-checker/contributors","subscribers_url":"https://api.github.com/repos/rackerlabs/api-checker/subscribers","subscription_url":"https://api.github.com/repos/rackerlabs/api-checker/subscription","commits_url":"https://api.github.com/repos/rackerlabs/api-checker/commits{/sha}","git_commits_url":"https://api.github.com/repos/rackerlabs/api-checker/git/commits{/sha}","comments_url":"https://api.github.com/repos/rackerlabs/api-checker/comments{/number}","issue_comment_url":"https://api.github.com/repos/rackerlabs/api-checker/issues/comments{/number}","contents_url":"https://api.github.com/repos/rackerlabs/api-checker/contents/{+path}","compare_url":"https://api.github.com/repos/rackerlabs/api-checker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rackerlabs/api-checker/merges","archive_url":"https://api.github.com/repos/rackerlabs/api-checker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rackerlabs/api-checker/downloads","issues_url":"https://api.github.com/repos/rackerlabs/api-checker/issues{/number}","pulls_url":"https://api.github.com/repos/rackerlabs/api-checker/pulls{/number}","milestones_url":"https://api.github.com/repos/rackerlabs/api-checker/milestones{/number}","notifications_url":"https://api.github.com/repos/rackerlabs/api-checker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rackerlabs/api-checker/labels{/name}","releases_url":"https://api.github.com/repos/rackerlabs/api-checker/releases{/id}","created_at":"2012-01-16T06:39:01Z","updated_at":"2015-06-02T12:44:42Z","pushed_at":"2015-08-28T02:13:59Z","git_url":"git://github.com/rackerlabs/api-checker.git","ssh_url":"git@github.com:rackerlabs/api-checker.git","clone_url":"https://github.com/rackerlabs/api-checker.git","svn_url":"https://github.com/rackerlabs/api-checker","homepage":"www.openrepose.org","size":5504,"stargazers_count":7,"watchers_count":7,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":14,"mirror_url":null,"open_issues_count":33,"forks":14,"open_issues":33,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rackerlabs/api-checker/pulls/274"},"html":{"href":"https://github.com/rackerlabs/api-checker/pull/274"},"issue":{"href":"https://api.github.com/repos/rackerlabs/api-checker/issues/274"},"comments":{"href":"https://api.github.com/repos/rackerlabs/api-checker/issues/274/comments"},"review_comments":{"href":"https://api.github.com/repos/rackerlabs/api-checker/pulls/274/comments"},"review_comment":{"href":"https://api.github.com/repos/rackerlabs/api-checker/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rackerlabs/api-checker/pulls/274/commits"},"statuses":{"href":"https://api.github.com/repos/rackerlabs/api-checker/statuses/77097be12912343f1f886e10a198abe8d1af7d8a"}}}}