{"action":"created","comment":{"url":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/comments/91723876","pull_request_review_id":12232616,"id":91723876,"diff_hunk":"@@ -26,32 +35,63 @@\n import java.security.AccessController;\n import java.security.PrivilegedActionException;\n import java.security.PrivilegedExceptionAction;\n-import java.util.Set;\n-import java.util.TreeSet;\n+import java.util.Collections;\n+import java.util.Map;\n \n /**\n  * Implements InternetManager.\n  */\n public class InternetManagerImpl implements InternetManager {\n+    /**\n+     * The module this InternetManager belongs to.\n+     */\n+    //@Nonnull\n     private final Name moduleId;\n \n-    private final Set<String> allowedHosts;\n+    /**\n+     * The allowed hosts.\n+     */\n+    //@Nonnull\n+    private final Map<String, TIntSet> allowedHosts;\n \n     /**\n      * Construct a new InternetManagerImpl with a shared \"permanent\" cache.\n      *\n      * @param moduleId The module ID.\n+     * @param context The current context.\n      */\n-    public InternetManagerImpl(Name moduleId) {\n+    public InternetManagerImpl(Name moduleId, Context context) {\n         this.moduleId = moduleId;\n-        allowedHosts = new TreeSet<>();\n-        allowedHosts.add(\"irc.freenode.net\");\n+        Config theConfig = context.get(Config.class);\n+        if (theConfig == null) {\n+            throw new IllegalStateException();\n+        }\n+        // TODO check if this could miss config updates, and make thread safe.\n+        InternetConfig.Hosts hosts = theConfig.getInternet().getTcpWhitelists().get(moduleId);\n+        if (hosts == null) {\n+            allowedHosts = Collections.emptyMap();\n+            return;\n+        }\n+        allowedHosts = Maps.transformValues(hosts.getHosts(), (x) -> x != null ? TCollections.unmodifiableSet(x.getPorts()) : null);\n     }\n \n     @Override\n     public TCPSocket openTCPConnection(String hostname, int port) throws IOException {\n-        if (!allowedHosts.contains(hostname)) {\n-            throw new IllegalArgumentException();\n+        Map<String, TIntSet> allowedHosts = this.allowedHosts;\n+        if (!(allowedHosts.containsKey(hostname) || allowedHosts.containsKey(\"*\"))) {\n+            // neither hostname nor wildcard in allowedHosts\n+            // TODO maybe use a different exception type? (SandboxException or something?)","path":"engine/src/main/java/org/terasology/internet/internal/InternetManagerImpl.java","position":null,"original_position":76,"commit_id":"6edad37cc5c933dc57c038a5236caac66333096a","original_commit_id":"c2c8939eee2578cf5880a3f89ef274ae21feca92","user":{"login":"rzats","id":13783592,"avatar_url":"https://avatars.githubusercontent.com/u/13783592?v=3","gravatar_id":"","url":"https://api.github.com/users/rzats","html_url":"https://github.com/rzats","followers_url":"https://api.github.com/users/rzats/followers","following_url":"https://api.github.com/users/rzats/following{/other_user}","gists_url":"https://api.github.com/users/rzats/gists{/gist_id}","starred_url":"https://api.github.com/users/rzats/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rzats/subscriptions","organizations_url":"https://api.github.com/users/rzats/orgs","repos_url":"https://api.github.com/users/rzats/repos","events_url":"https://api.github.com/users/rzats/events{/privacy}","received_events_url":"https://api.github.com/users/rzats/received_events","type":"User","site_admin":false},"body":"Sounds good - `IllegalArgumentException` is IMO best used in `Preconditions`-esque checks\r\n\r\n```java\r\npublic int foo (int a) {\r\n    if (a % 2 == 2) {\r\n        throw new IllegalArgumentException (\"wow you messed up\");\r\n    }\r\n    /* ... */\r\n}\r\n```\r\n\r\nand I can't find a good default exception for this usecase.","created_at":"2016-12-09T14:24:02Z","updated_at":"2016-12-09T14:28:01Z","html_url":"https://github.com/MovingBlocks/Terasology/pull/2618#discussion_r91723876","pull_request_url":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/2618","_links":{"self":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/comments/91723876"},"html":{"href":"https://github.com/MovingBlocks/Terasology/pull/2618#discussion_r91723876"},"pull_request":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/2618"}}},"pull_request":{"url":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/2618","id":94713076,"html_url":"https://github.com/MovingBlocks/Terasology/pull/2618","diff_url":"https://github.com/MovingBlocks/Terasology/pull/2618.diff","patch_url":"https://github.com/MovingBlocks/Terasology/pull/2618.patch","issue_url":"https://api.github.com/repos/MovingBlocks/Terasology/issues/2618","number":2618,"state":"open","locked":false,"title":"Add Internet","user":{"login":"SoniEx2","id":1779619,"avatar_url":"https://avatars.githubusercontent.com/u/1779619?v=3","gravatar_id":"","url":"https://api.github.com/users/SoniEx2","html_url":"https://github.com/SoniEx2","followers_url":"https://api.github.com/users/SoniEx2/followers","following_url":"https://api.github.com/users/SoniEx2/following{/other_user}","gists_url":"https://api.github.com/users/SoniEx2/gists{/gist_id}","starred_url":"https://api.github.com/users/SoniEx2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SoniEx2/subscriptions","organizations_url":"https://api.github.com/users/SoniEx2/orgs","repos_url":"https://api.github.com/users/SoniEx2/repos","events_url":"https://api.github.com/users/SoniEx2/events{/privacy}","received_events_url":"https://api.github.com/users/SoniEx2/received_events","type":"User","site_admin":false},"body":"<!-- Thanks for submitting a pull request for Terasology! :-)\r\nPlease fill in some brief details below about the PR.\r\nIf it contains source code please make sure to run Checkstyle on it first\r\nIf you add unit tests we'll love you forever! -->\r\n\r\n### Contains\r\n\r\nAdds Internet. Use\r\n\r\n```java\r\n@In\r\nInternetManager internet;\r\n```\r\n\r\nIn a System to get access to the Internet. It has TCP.\r\n\r\n### How to test\r\n\r\nThis is a badly written IRC client that just barely works: https://gist.github.com/SoniEx2/9845b9cd44a879bb517961a52ca4fc68 (warning: bad code, not thread-safe, may blow up)\r\n\r\n### Outstanding before merging\r\n\r\n- [x] Separate whitelists.\r\n- [x] Whitelists need to be user-configurable somehow.\r\n- [ ] Move DynamicInstanceProvider to a separate PR.\r\n- [ ] Disallow internet access on the client.\r\n- [x] ~~HTTP, with separate whitelists. Anything with TCP access also has HTTP access, but HTTP access does not give you TCP access.~~ Should be an external \"HTTP\" module, not part of this PR.\r\n- [ ] Global whitelist that any module can use? Unsure about this one.\r\n\r\nIt is *intentionally allowed* to hand your InternetManager (and thus your whitelist) to another module. After all, it's trivial to wrap InternetManager for cross-module use, with or without being able to share InternetManager itself.\r\n\r\nAlso, if I knew how, I'd use Netty for this. The idea was to make an implementation-agnostic API, maybe with events, but I'm not very good at that.","created_at":"2016-11-21T22:47:46Z","updated_at":"2016-12-09T14:28:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"136ddd39e311f68e3c7b3426a58cef1773e1ea57","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/2618/commits","review_comments_url":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/2618/comments","review_comment_url":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/comments{/number}","comments_url":"https://api.github.com/repos/MovingBlocks/Terasology/issues/2618/comments","statuses_url":"https://api.github.com/repos/MovingBlocks/Terasology/statuses/6edad37cc5c933dc57c038a5236caac66333096a","head":{"label":"SoniEx2:internet","ref":"internet","sha":"6edad37cc5c933dc57c038a5236caac66333096a","user":{"login":"SoniEx2","id":1779619,"avatar_url":"https://avatars.githubusercontent.com/u/1779619?v=3","gravatar_id":"","url":"https://api.github.com/users/SoniEx2","html_url":"https://github.com/SoniEx2","followers_url":"https://api.github.com/users/SoniEx2/followers","following_url":"https://api.github.com/users/SoniEx2/following{/other_user}","gists_url":"https://api.github.com/users/SoniEx2/gists{/gist_id}","starred_url":"https://api.github.com/users/SoniEx2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SoniEx2/subscriptions","organizations_url":"https://api.github.com/users/SoniEx2/orgs","repos_url":"https://api.github.com/users/SoniEx2/repos","events_url":"https://api.github.com/users/SoniEx2/events{/privacy}","received_events_url":"https://api.github.com/users/SoniEx2/received_events","type":"User","site_admin":false},"repo":{"id":69908657,"name":"Terasology","full_name":"SoniEx2/Terasology","owner":{"login":"SoniEx2","id":1779619,"avatar_url":"https://avatars.githubusercontent.com/u/1779619?v=3","gravatar_id":"","url":"https://api.github.com/users/SoniEx2","html_url":"https://github.com/SoniEx2","followers_url":"https://api.github.com/users/SoniEx2/followers","following_url":"https://api.github.com/users/SoniEx2/following{/other_user}","gists_url":"https://api.github.com/users/SoniEx2/gists{/gist_id}","starred_url":"https://api.github.com/users/SoniEx2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SoniEx2/subscriptions","organizations_url":"https://api.github.com/users/SoniEx2/orgs","repos_url":"https://api.github.com/users/SoniEx2/repos","events_url":"https://api.github.com/users/SoniEx2/events{/privacy}","received_events_url":"https://api.github.com/users/SoniEx2/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/SoniEx2/Terasology","description":"Terasology - open source voxel world","fork":true,"url":"https://api.github.com/repos/SoniEx2/Terasology","forks_url":"https://api.github.com/repos/SoniEx2/Terasology/forks","keys_url":"https://api.github.com/repos/SoniEx2/Terasology/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SoniEx2/Terasology/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SoniEx2/Terasology/teams","hooks_url":"https://api.github.com/repos/SoniEx2/Terasology/hooks","issue_events_url":"https://api.github.com/repos/SoniEx2/Terasology/issues/events{/number}","events_url":"https://api.github.com/repos/SoniEx2/Terasology/events","assignees_url":"https://api.github.com/repos/SoniEx2/Terasology/assignees{/user}","branches_url":"https://api.github.com/repos/SoniEx2/Terasology/branches{/branch}","tags_url":"https://api.github.com/repos/SoniEx2/Terasology/tags","blobs_url":"https://api.github.com/repos/SoniEx2/Terasology/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SoniEx2/Terasology/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SoniEx2/Terasology/git/refs{/sha}","trees_url":"https://api.github.com/repos/SoniEx2/Terasology/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SoniEx2/Terasology/statuses/{sha}","languages_url":"https://api.github.com/repos/SoniEx2/Terasology/languages","stargazers_url":"https://api.github.com/repos/SoniEx2/Terasology/stargazers","contributors_url":"https://api.github.com/repos/SoniEx2/Terasology/contributors","subscribers_url":"https://api.github.com/repos/SoniEx2/Terasology/subscribers","subscription_url":"https://api.github.com/repos/SoniEx2/Terasology/subscription","commits_url":"https://api.github.com/repos/SoniEx2/Terasology/commits{/sha}","git_commits_url":"https://api.github.com/repos/SoniEx2/Terasology/git/commits{/sha}","comments_url":"https://api.github.com/repos/SoniEx2/Terasology/comments{/number}","issue_comment_url":"https://api.github.com/repos/SoniEx2/Terasology/issues/comments{/number}","contents_url":"https://api.github.com/repos/SoniEx2/Terasology/contents/{+path}","compare_url":"https://api.github.com/repos/SoniEx2/Terasology/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SoniEx2/Terasology/merges","archive_url":"https://api.github.com/repos/SoniEx2/Terasology/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SoniEx2/Terasology/downloads","issues_url":"https://api.github.com/repos/SoniEx2/Terasology/issues{/number}","pulls_url":"https://api.github.com/repos/SoniEx2/Terasology/pulls{/number}","milestones_url":"https://api.github.com/repos/SoniEx2/Terasology/milestones{/number}","notifications_url":"https://api.github.com/repos/SoniEx2/Terasology/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SoniEx2/Terasology/labels{/name}","releases_url":"https://api.github.com/repos/SoniEx2/Terasology/releases{/id}","deployments_url":"https://api.github.com/repos/SoniEx2/Terasology/deployments","created_at":"2016-10-03T20:33:45Z","updated_at":"2016-10-05T18:04:33Z","pushed_at":"2016-12-08T22:26:44Z","git_url":"git://github.com/SoniEx2/Terasology.git","ssh_url":"git@github.com:SoniEx2/Terasology.git","clone_url":"https://github.com/SoniEx2/Terasology.git","svn_url":"https://github.com/SoniEx2/Terasology","homepage":"http://terasology.org","size":276552,"stargazers_count":0,"watchers_count":0,"language":"Java","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":"develop"}},"base":{"label":"MovingBlocks:develop","ref":"develop","sha":"61e54bb96e426e0369ab03f2230e5f468bc17c6f","user":{"login":"MovingBlocks","id":1292442,"avatar_url":"https://avatars.githubusercontent.com/u/1292442?v=3","gravatar_id":"","url":"https://api.github.com/users/MovingBlocks","html_url":"https://github.com/MovingBlocks","followers_url":"https://api.github.com/users/MovingBlocks/followers","following_url":"https://api.github.com/users/MovingBlocks/following{/other_user}","gists_url":"https://api.github.com/users/MovingBlocks/gists{/gist_id}","starred_url":"https://api.github.com/users/MovingBlocks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MovingBlocks/subscriptions","organizations_url":"https://api.github.com/users/MovingBlocks/orgs","repos_url":"https://api.github.com/users/MovingBlocks/repos","events_url":"https://api.github.com/users/MovingBlocks/events{/privacy}","received_events_url":"https://api.github.com/users/MovingBlocks/received_events","type":"Organization","site_admin":false},"repo":{"id":1438007,"name":"Terasology","full_name":"MovingBlocks/Terasology","owner":{"login":"MovingBlocks","id":1292442,"avatar_url":"https://avatars.githubusercontent.com/u/1292442?v=3","gravatar_id":"","url":"https://api.github.com/users/MovingBlocks","html_url":"https://github.com/MovingBlocks","followers_url":"https://api.github.com/users/MovingBlocks/followers","following_url":"https://api.github.com/users/MovingBlocks/following{/other_user}","gists_url":"https://api.github.com/users/MovingBlocks/gists{/gist_id}","starred_url":"https://api.github.com/users/MovingBlocks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MovingBlocks/subscriptions","organizations_url":"https://api.github.com/users/MovingBlocks/orgs","repos_url":"https://api.github.com/users/MovingBlocks/repos","events_url":"https://api.github.com/users/MovingBlocks/events{/privacy}","received_events_url":"https://api.github.com/users/MovingBlocks/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/MovingBlocks/Terasology","description":"Terasology - open source voxel world","fork":false,"url":"https://api.github.com/repos/MovingBlocks/Terasology","forks_url":"https://api.github.com/repos/MovingBlocks/Terasology/forks","keys_url":"https://api.github.com/repos/MovingBlocks/Terasology/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MovingBlocks/Terasology/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MovingBlocks/Terasology/teams","hooks_url":"https://api.github.com/repos/MovingBlocks/Terasology/hooks","issue_events_url":"https://api.github.com/repos/MovingBlocks/Terasology/issues/events{/number}","events_url":"https://api.github.com/repos/MovingBlocks/Terasology/events","assignees_url":"https://api.github.com/repos/MovingBlocks/Terasology/assignees{/user}","branches_url":"https://api.github.com/repos/MovingBlocks/Terasology/branches{/branch}","tags_url":"https://api.github.com/repos/MovingBlocks/Terasology/tags","blobs_url":"https://api.github.com/repos/MovingBlocks/Terasology/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MovingBlocks/Terasology/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MovingBlocks/Terasology/git/refs{/sha}","trees_url":"https://api.github.com/repos/MovingBlocks/Terasology/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MovingBlocks/Terasology/statuses/{sha}","languages_url":"https://api.github.com/repos/MovingBlocks/Terasology/languages","stargazers_url":"https://api.github.com/repos/MovingBlocks/Terasology/stargazers","contributors_url":"https://api.github.com/repos/MovingBlocks/Terasology/contributors","subscribers_url":"https://api.github.com/repos/MovingBlocks/Terasology/subscribers","subscription_url":"https://api.github.com/repos/MovingBlocks/Terasology/subscription","commits_url":"https://api.github.com/repos/MovingBlocks/Terasology/commits{/sha}","git_commits_url":"https://api.github.com/repos/MovingBlocks/Terasology/git/commits{/sha}","comments_url":"https://api.github.com/repos/MovingBlocks/Terasology/comments{/number}","issue_comment_url":"https://api.github.com/repos/MovingBlocks/Terasology/issues/comments{/number}","contents_url":"https://api.github.com/repos/MovingBlocks/Terasology/contents/{+path}","compare_url":"https://api.github.com/repos/MovingBlocks/Terasology/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MovingBlocks/Terasology/merges","archive_url":"https://api.github.com/repos/MovingBlocks/Terasology/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MovingBlocks/Terasology/downloads","issues_url":"https://api.github.com/repos/MovingBlocks/Terasology/issues{/number}","pulls_url":"https://api.github.com/repos/MovingBlocks/Terasology/pulls{/number}","milestones_url":"https://api.github.com/repos/MovingBlocks/Terasology/milestones{/number}","notifications_url":"https://api.github.com/repos/MovingBlocks/Terasology/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MovingBlocks/Terasology/labels{/name}","releases_url":"https://api.github.com/repos/MovingBlocks/Terasology/releases{/id}","deployments_url":"https://api.github.com/repos/MovingBlocks/Terasology/deployments","created_at":"2011-03-04T03:49:19Z","updated_at":"2016-12-09T12:36:34Z","pushed_at":"2016-12-09T13:42:48Z","git_url":"git://github.com/MovingBlocks/Terasology.git","ssh_url":"git@github.com:MovingBlocks/Terasology.git","clone_url":"https://github.com/MovingBlocks/Terasology.git","svn_url":"https://github.com/MovingBlocks/Terasology","homepage":"http://terasology.org","size":346122,"stargazers_count":1770,"watchers_count":1770,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":762,"mirror_url":null,"open_issues_count":323,"forks":762,"open_issues":323,"watchers":1770,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/2618"},"html":{"href":"https://github.com/MovingBlocks/Terasology/pull/2618"},"issue":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/issues/2618"},"comments":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/issues/2618/comments"},"review_comments":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/2618/comments"},"review_comment":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/pulls/2618/commits"},"statuses":{"href":"https://api.github.com/repos/MovingBlocks/Terasology/statuses/6edad37cc5c933dc57c038a5236caac66333096a"}}}}
{"actor":{"display_login":"rzats"}}