{"action":"created","comment":{"url":"https://api.github.com/repos/rackerlabs/repose/pulls/comments/168302486","pull_request_review_id":96648151,"id":168302486,"diff_hunk":"@@ -0,0 +1,475 @@\n+/*\n+ * _=_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_=\n+ * Repose\n+ * _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-\n+ * Copyright (C) 2010 - 2015 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+ */\n+package features.filters.apivalidator\n+\n+import org.openrepose.framework.test.ReposeValveTest\n+import org.rackspace.deproxy.Deproxy\n+import org.rackspace.deproxy.MessageChain\n+import spock.lang.Unroll\n+\n+import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN\n+import static javax.servlet.http.HttpServletResponse.SC_OK\n+import static org.openrepose.commons.utils.http.OpenStackServiceHeader.ROLES\n+import static org.openrepose.commons.utils.http.PowerApiHeader.RELEVANT_ROLES\n+import static org.openrepose.commons.utils.string.Base64Helper.base64EncodeUtf8\n+\n+class ApiValidatorMultiTenantTest extends ReposeValveTest {\n+\n+    static def mapHeaderValue = base64EncodeUtf8(\"\"\"{\n+      |   \"1\" : [\"a:admin\",\"foo\",\"bar\"],\n+      |   \"2\" : [\"a:creator\", \"foo\", \"a:observer\"],\n+      |   \"3\" : [\"a:updater\", \"bar\", \"biz\", \"a:creator\"],\n+      |   \"4\" : [\"a:observer\"],\n+      |   \"5\" : [\"a:admin\", \"bar\", \"biz\", \"a:creator\"],\n+      |   \"6\" : [\"biz\", \"baz\"],\n+      |   \"7\" : [\"role with spaces\", \"biz\"],\n+      |   \"8\" : [\"a:patcher\"]\n+      |}\n+      |\"\"\".stripMargin())\n+\n+    static def observerRequests = [\n+        [\"GET\", \"/v1/resource\"]\n+    ]\n+\n+    static def creatorRequests = [\n+        [\"POST\", \"/v1/resource\"],\n+        [\"POST\", \"/v1/resource/other\"]\n+    ]\n+    static def updaterRequests = [\n+        [\"PUT\", \"/v1/resource\"],\n+        [\"PUT\", \"/v1/resource/other\"]\n+    ]\n+    static def adminOnlyRequests = [\n+        [\"DELETE\", \"/v1/resource\"],\n+        [\"DELETE\", \"/v1/resource/other\"]\n+    ]\n+\n+\n+    def setupSpec() {\n+        deproxy = new Deproxy()\n+        deproxy.addEndpoint(properties.targetPort)\n+\n+        def params = properties.getDefaultTemplateParams()\n+        repose.configurationProvider.applyConfigs(\"common\", params)\n+        repose.configurationProvider.applyConfigs(\"features/filters/apivalidator/multitenant\", params)\n+        repose.start()\n+\n+        repose.waitForNon500FromUrl(reposeEndpoint)\n+    }\n+\n+    @Unroll(\"Should succeed on GET /v1/resource/other when appropriate headers are set (#tenants)\")\n+    def \"Should succeed when appropriate headers are set\"() {\n+        when:\n+        MessageChain mc = deproxy.makeRequest(\n+            url: \"$reposeEndpoint/v1/resource/other\",\n+            method: \"GET\",\n+            headers: [\n+                \"X-Tenant\"   : tenants,\n+                \"X-Other\"    : \"other\",\n+                (ROLES)      : \"foo,bar\",\n+                \"X-Map-Roles\": mapHeaderValue])\n+\n+        then:\n+        mc.getReceivedResponse().getCode() as Integer == SC_OK\n+        mc.handlings.size() == 1\n+        List<String> relevantRolesValues = mc.handlings[0].request.headers.findAll(RELEVANT_ROLES)\n+        relevantRolesValues.containsAll([\"foo\", \"bar\"])\n+\n+        where:\n+        tenants << [\"1,5\", \"4\", \"4,2\", \"1,2,3\", \"5,2\", \"1,3\", \"5,3\", \"1\", \"1,5,7\", \"1,5,6\"]\n+    }\n+\n+    @Unroll(\"Should succeed on #method #url when appropriate headers are set (1, 5)\")\n+    def \"Should succeed when appropriate headers are set (1, 5)\"() {\n+        when:\n+        MessageChain mc = deproxy.makeRequest(\n+            url: \"$reposeEndpoint$url\",\n+            method: method,\n+            headers: [\n+                \"X-Tenant\"   : \"1,5\",\n+                \"X-Other\"    : \"other\",\n+                (ROLES)      : \"foo,bar\",\n+                \"X-Map-Roles\": mapHeaderValue])\n+\n+        then:\n+        mc.getReceivedResponse().getCode() as Integer == SC_OK\n+        mc.handlings.size() == 1\n+        List<String> relevantRolesValues = mc.handlings[0].request.headers.findAll(RELEVANT_ROLES)\n+        relevantRolesValues.contains(\"a:admin/{X-TENANT}\")\n+\n+        where:\n+        [method, url] << observerRequests + creatorRequests + updaterRequests + adminOnlyRequests\n+    }\n+\n+    def \"Should succeed on GET /v1/resource/other when appropriate headers are set (1,5)\"() {\n+        when:\n+        MessageChain mc = deproxy.makeRequest(\n+            url: \"$reposeEndpoint/v1/resource/other\",\n+            method: \"GET\",\n+            headers: [\n+                \"X-Tenant\"   : \"1,5\",\n+                \"X-Other\"    : \"other\",\n+                \"X-Map-Roles\": mapHeaderValue])\n+\n+        then:\n+        mc.getReceivedResponse().getCode() as Integer == SC_OK\n+        mc.handlings.size() == 1\n+        List<String> relevantRolesValues = mc.handlings[0].request.headers.findAll(RELEVANT_ROLES)\n+        relevantRolesValues.isEmpty()\n+    }\n+\n+    @Unroll(\"Should fail on #method #url when appropriate headers are set but there's no tenant access (#tenants)\")\n+    def \"Should fail on when appropriate headers are set but there's no tenant access\"() {","path":"repose-aggregator/tests/functional-tests/src/integrationTest/groovy/features/filters/apivalidator/ApiValidatorMultiTenantTest.groovy","position":139,"original_position":139,"commit_id":"662d112bb82d217ca3849591fac67f18aa2ac226","original_commit_id":"662d112bb82d217ca3849591fac67f18aa2ac226","user":{"login":"wdschei","id":7366196,"avatar_url":"https://avatars2.githubusercontent.com/u/7366196?v=4","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":"Yeah, I was just removing the variable parts of the `Unroll` name for the `def` name.","created_at":"2018-02-14T20:36:59Z","updated_at":"2018-02-14T20:36:59Z","html_url":"https://github.com/rackerlabs/repose/pull/1862#discussion_r168302486","pull_request_url":"https://api.github.com/repos/rackerlabs/repose/pulls/1862","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/rackerlabs/repose/pulls/comments/168302486"},"html":{"href":"https://github.com/rackerlabs/repose/pull/1862#discussion_r168302486"},"pull_request":{"href":"https://api.github.com/repos/rackerlabs/repose/pulls/1862"}},"in_reply_to_id":168286959},"pull_request":{"url":"https://api.github.com/repos/rackerlabs/repose/pulls/1862","id":168642707,"html_url":"https://github.com/rackerlabs/repose/pull/1862","diff_url":"https://github.com/rackerlabs/repose/pull/1862.diff","patch_url":"https://github.com/rackerlabs/repose/pull/1862.patch","issue_url":"https://api.github.com/repos/rackerlabs/repose/issues/1862","number":1862,"state":"open","locked":false,"title":"Updated API-Checker from v2.5.1 to v2.6.0.","user":{"login":"wdschei","id":7366196,"avatar_url":"https://avatars2.githubusercontent.com/u/7366196?v=4","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":"2018-02-12T17:35:14Z","updated_at":"2018-02-14T20:36:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"da3beed77ea45963cbd83438d04b89b869f79d53","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/rackerlabs/repose/pulls/1862/commits","review_comments_url":"https://api.github.com/repos/rackerlabs/repose/pulls/1862/comments","review_comment_url":"https://api.github.com/repos/rackerlabs/repose/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rackerlabs/repose/issues/1862/comments","statuses_url":"https://api.github.com/repos/rackerlabs/repose/statuses/662d112bb82d217ca3849591fac67f18aa2ac226","head":{"label":"rackerlabs:REP-6470_UpgradeApiCheckerV2-6-0","ref":"REP-6470_UpgradeApiCheckerV2-6-0","sha":"662d112bb82d217ca3849591fac67f18aa2ac226","user":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars1.githubusercontent.com/u/84293?v=4","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":1981821,"name":"repose","full_name":"rackerlabs/repose","owner":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars1.githubusercontent.com/u/84293?v=4","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/repose","description":"The powerful, programmable, API Middleware Platform","fork":false,"url":"https://api.github.com/repos/rackerlabs/repose","forks_url":"https://api.github.com/repos/rackerlabs/repose/forks","keys_url":"https://api.github.com/repos/rackerlabs/repose/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rackerlabs/repose/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rackerlabs/repose/teams","hooks_url":"https://api.github.com/repos/rackerlabs/repose/hooks","issue_events_url":"https://api.github.com/repos/rackerlabs/repose/issues/events{/number}","events_url":"https://api.github.com/repos/rackerlabs/repose/events","assignees_url":"https://api.github.com/repos/rackerlabs/repose/assignees{/user}","branches_url":"https://api.github.com/repos/rackerlabs/repose/branches{/branch}","tags_url":"https://api.github.com/repos/rackerlabs/repose/tags","blobs_url":"https://api.github.com/repos/rackerlabs/repose/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rackerlabs/repose/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rackerlabs/repose/git/refs{/sha}","trees_url":"https://api.github.com/repos/rackerlabs/repose/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rackerlabs/repose/statuses/{sha}","languages_url":"https://api.github.com/repos/rackerlabs/repose/languages","stargazers_url":"https://api.github.com/repos/rackerlabs/repose/stargazers","contributors_url":"https://api.github.com/repos/rackerlabs/repose/contributors","subscribers_url":"https://api.github.com/repos/rackerlabs/repose/subscribers","subscription_url":"https://api.github.com/repos/rackerlabs/repose/subscription","commits_url":"https://api.github.com/repos/rackerlabs/repose/commits{/sha}","git_commits_url":"https://api.github.com/repos/rackerlabs/repose/git/commits{/sha}","comments_url":"https://api.github.com/repos/rackerlabs/repose/comments{/number}","issue_comment_url":"https://api.github.com/repos/rackerlabs/repose/issues/comments{/number}","contents_url":"https://api.github.com/repos/rackerlabs/repose/contents/{+path}","compare_url":"https://api.github.com/repos/rackerlabs/repose/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rackerlabs/repose/merges","archive_url":"https://api.github.com/repos/rackerlabs/repose/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rackerlabs/repose/downloads","issues_url":"https://api.github.com/repos/rackerlabs/repose/issues{/number}","pulls_url":"https://api.github.com/repos/rackerlabs/repose/pulls{/number}","milestones_url":"https://api.github.com/repos/rackerlabs/repose/milestones{/number}","notifications_url":"https://api.github.com/repos/rackerlabs/repose/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rackerlabs/repose/labels{/name}","releases_url":"https://api.github.com/repos/rackerlabs/repose/releases{/id}","deployments_url":"https://api.github.com/repos/rackerlabs/repose/deployments","created_at":"2011-07-01T04:39:34Z","updated_at":"2018-02-01T00:16:43Z","pushed_at":"2018-02-14T17:46:23Z","git_url":"git://github.com/rackerlabs/repose.git","ssh_url":"git@github.com:rackerlabs/repose.git","clone_url":"https://github.com/rackerlabs/repose.git","svn_url":"https://github.com/rackerlabs/repose","homepage":"http://www.openrepose.org/","size":101064,"stargazers_count":300,"watchers_count":300,"language":"Groovy","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":88,"mirror_url":null,"archived":false,"open_issues_count":13,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":88,"open_issues":13,"watchers":300,"default_branch":"master"}},"base":{"label":"rackerlabs:master","ref":"master","sha":"e81bcc965f8d6cc65f529ca41d167c87fd56d3ed","user":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars1.githubusercontent.com/u/84293?v=4","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":1981821,"name":"repose","full_name":"rackerlabs/repose","owner":{"login":"rackerlabs","id":84293,"avatar_url":"https://avatars1.githubusercontent.com/u/84293?v=4","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/repose","description":"The powerful, programmable, API Middleware Platform","fork":false,"url":"https://api.github.com/repos/rackerlabs/repose","forks_url":"https://api.github.com/repos/rackerlabs/repose/forks","keys_url":"https://api.github.com/repos/rackerlabs/repose/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rackerlabs/repose/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rackerlabs/repose/teams","hooks_url":"https://api.github.com/repos/rackerlabs/repose/hooks","issue_events_url":"https://api.github.com/repos/rackerlabs/repose/issues/events{/number}","events_url":"https://api.github.com/repos/rackerlabs/repose/events","assignees_url":"https://api.github.com/repos/rackerlabs/repose/assignees{/user}","branches_url":"https://api.github.com/repos/rackerlabs/repose/branches{/branch}","tags_url":"https://api.github.com/repos/rackerlabs/repose/tags","blobs_url":"https://api.github.com/repos/rackerlabs/repose/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rackerlabs/repose/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rackerlabs/repose/git/refs{/sha}","trees_url":"https://api.github.com/repos/rackerlabs/repose/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rackerlabs/repose/statuses/{sha}","languages_url":"https://api.github.com/repos/rackerlabs/repose/languages","stargazers_url":"https://api.github.com/repos/rackerlabs/repose/stargazers","contributors_url":"https://api.github.com/repos/rackerlabs/repose/contributors","subscribers_url":"https://api.github.com/repos/rackerlabs/repose/subscribers","subscription_url":"https://api.github.com/repos/rackerlabs/repose/subscription","commits_url":"https://api.github.com/repos/rackerlabs/repose/commits{/sha}","git_commits_url":"https://api.github.com/repos/rackerlabs/repose/git/commits{/sha}","comments_url":"https://api.github.com/repos/rackerlabs/repose/comments{/number}","issue_comment_url":"https://api.github.com/repos/rackerlabs/repose/issues/comments{/number}","contents_url":"https://api.github.com/repos/rackerlabs/repose/contents/{+path}","compare_url":"https://api.github.com/repos/rackerlabs/repose/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rackerlabs/repose/merges","archive_url":"https://api.github.com/repos/rackerlabs/repose/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rackerlabs/repose/downloads","issues_url":"https://api.github.com/repos/rackerlabs/repose/issues{/number}","pulls_url":"https://api.github.com/repos/rackerlabs/repose/pulls{/number}","milestones_url":"https://api.github.com/repos/rackerlabs/repose/milestones{/number}","notifications_url":"https://api.github.com/repos/rackerlabs/repose/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rackerlabs/repose/labels{/name}","releases_url":"https://api.github.com/repos/rackerlabs/repose/releases{/id}","deployments_url":"https://api.github.com/repos/rackerlabs/repose/deployments","created_at":"2011-07-01T04:39:34Z","updated_at":"2018-02-01T00:16:43Z","pushed_at":"2018-02-14T17:46:23Z","git_url":"git://github.com/rackerlabs/repose.git","ssh_url":"git@github.com:rackerlabs/repose.git","clone_url":"https://github.com/rackerlabs/repose.git","svn_url":"https://github.com/rackerlabs/repose","homepage":"http://www.openrepose.org/","size":101064,"stargazers_count":300,"watchers_count":300,"language":"Groovy","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":88,"mirror_url":null,"archived":false,"open_issues_count":13,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":88,"open_issues":13,"watchers":300,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rackerlabs/repose/pulls/1862"},"html":{"href":"https://github.com/rackerlabs/repose/pull/1862"},"issue":{"href":"https://api.github.com/repos/rackerlabs/repose/issues/1862"},"comments":{"href":"https://api.github.com/repos/rackerlabs/repose/issues/1862/comments"},"review_comments":{"href":"https://api.github.com/repos/rackerlabs/repose/pulls/1862/comments"},"review_comment":{"href":"https://api.github.com/repos/rackerlabs/repose/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rackerlabs/repose/pulls/1862/commits"},"statuses":{"href":"https://api.github.com/repos/rackerlabs/repose/statuses/662d112bb82d217ca3849591fac67f18aa2ac226"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"wdschei"}}