{"action":"created","comment":{"url":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/comments/82595255","pull_request_review_id":3491286,"id":82595255,"diff_hunk":"@@ -0,0 +1,579 @@\n+/*\n+ * ################################################################\n+ *\n+ * ProActive Parallel Suite(TM): The Java(TM) library for\n+ *    Parallel, Distributed, Multi-Core Computing for\n+ *    Enterprise Grids & Clouds\n+ *\n+ * Copyright (C) 1997-2015 INRIA/University of\n+ *                 Nice-Sophia Antipolis/ActiveEon\n+ * Contact: proactive@ow2.org or contact@activeeon.com\n+ *\n+ * This library is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU Affero General Public License\n+ * as published by the Free Software Foundation; version 3 of\n+ * the License.\n+ *\n+ * This library is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ * Affero General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Affero General Public License\n+ * along with this library; if not, write to the Free Software\n+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307\n+ * USA\n+ *\n+ * If needed, contact us to obtain a release under GPL Version 2 or 3\n+ * or a different license than the AGPL.\n+ *\n+ *  Initial developer(s):               The ProActive Team\n+ *                        http://proactive.inria.fr/team_members.htm\n+ *  Contributor(s):\n+ *\n+ * ################################################################\n+ * $$PROACTIVE_INITIAL_DEV$$\n+ */\n+package org.ow2.proactive.scheduler.authentication;\n+\n+import com.google.common.base.Charsets;\n+import com.google.common.collect.Multimap;\n+import com.google.common.collect.TreeMultimap;\n+import org.apache.commons.cli.*;\n+import org.apache.commons.io.IOUtils;\n+import org.objectweb.proactive.utils.SecurityManagerConfigurator;\n+import org.ow2.proactive.authentication.FileLoginModule;\n+import org.ow2.proactive.authentication.crypto.CreateCredentials;\n+import org.ow2.proactive.authentication.crypto.Credentials;\n+import org.ow2.proactive.authentication.crypto.HybridEncryptionUtil;\n+import org.ow2.proactive.scheduler.core.properties.PASchedulerProperties;\n+import org.ow2.proactive.utils.Tools;\n+\n+import java.io.*;\n+import java.security.KeyException;\n+import java.security.PublicKey;\n+import java.util.ArrayList;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.Properties;\n+import java.util.TreeMap;\n+\n+\n+/**\n+ * Manage user accounts in login.cfg and group.cfg files\n+ *\n+ * @author The ProActive Team\n+ * @see org.ow2.proactive.authentication.crypto.Credentials\n+ */\n+public class ManageUsers {\n+\n+    private static final String newline = System.lineSeparator();\n+\n+    public static final String CREATE_OPTION = \"C\";\n+    public static final String CREATE_OPTION_NAME = \"create\";\n+    public static final String UPDATE_OPTION = \"U\";\n+    public static final String UPDATE_OPTION_NAME = \"update\";\n+    public static final String DELETE_OPTION = \"D\";\n+    public static final String DELETE_OPTION_NAME = \"delete\";\n+\n+    public static final String HELP_OPTION = \"h\";\n+    public static final String HELP_OPTION_NAME = \"help\";\n+    public static final String LOGIN_OPTION = \"l\";\n+    public static final String LOGIN_OPTION_NAME = \"login\";\n+    public static final String PWD_OPTION = \"p\";\n+    public static final String PWD_OPTION_NAME = \"password\";\n+    public static final String GROUPS_OPTION = \"g\";\n+    public static final String GROUPS_OPTION_NAME = \"groups\";\n+    public static final String KEYFILE_OPTION = \"kf\";\n+    public static final String KEYFILE_OPTION_NAME = \"keyfile\";\n+    public static final String LOGINFILE_OPTION = \"lf\";\n+    public static final String LOGINFILE_OPTION_NAME = \"loginfile\";\n+    public static final String GROUPFILE_OPTION = \"gf\";\n+    public static final String GROUPFILE_OPTION_NAME = \"groupfile\";\n+\n+\n+    /**\n+     * Entry point\n+     *\n+     * @param args arguments, try '-h' for help\n+     * @throws IOException\n+     * @throws ParseException\n+     * @see org.ow2.proactive.authentication.crypto.Credentials\n+     */\n+    public static void main(String[] args) {\n+\n+        try {\n+\n+            manageUsers(args);\n+\n+        } catch (ManageUsersException e) {\n+            System.err.println(\"ERROR : \" + e.getMessage());\n+            if (e.getCause() != null) {\n+                System.err.println(e.getCause().getMessage());\n+            }\n+            if (e.getAdditionalInfo() != null) {\n+                System.out.println(e.getAdditionalInfo());\n+            }\n+            System.exit(1);\n+        }\n+\n+        System.exit(0);\n+    }\n+\n+    public static void manageUsers(String[] args) throws ManageUsersException {\n+        SecurityManagerConfigurator.configureSecurityManager(CreateCredentials.class.getResource(\n+                \"/all-permissions.security.policy\").toString());\n+\n+        Console console = System.console();\n+        /**\n+         * default values\n+         */\n+        boolean nonInteractive = true;\n+        String pubKeyPath = null;\n+        PublicKey pubKey = null;\n+        UserInfo userInfo = new UserInfo();\n+        String loginFilePath = getLoginFilePath();\n+        String groupFilePath = getGroupFilePath();\n+        Action action = null;\n+\n+        Options options = new Options();\n+\n+        CommandLine cmd = getCommandLine(args, loginFilePath, groupFilePath, options);\n+\n+        if (cmd.hasOption(HELP_OPTION_NAME)) {\n+            displayHelp(options);\n+            return;\n+        }\n+\n+        action = Action.getAction(cmd);\n+\n+        if (cmd.hasOption(LOGIN_OPTION_NAME)) {\n+            userInfo.setLogin(cmd.getOptionValue(LOGIN_OPTION_NAME));\n+        }\n+        if (cmd.hasOption(PWD_OPTION_NAME)) {\n+            userInfo.setPassword(cmd.getOptionValue(PWD_OPTION_NAME));\n+        }\n+        if (cmd.hasOption(GROUPS_OPTION_NAME)) {\n+            String groupString = cmd.getOptionValue(GROUPS_OPTION_NAME);\n+            userInfo.setGroups(groupString.split(\",\"));\n+        }\n+\n+        if (cmd.hasOption(LOGINFILE_OPTION_NAME)) {\n+            loginFilePath = cmd.getOptionValue(LOGINFILE_OPTION_NAME);\n+        }\n+        if (cmd.hasOption(GROUPFILE_OPTION_NAME)) {\n+            groupFilePath = cmd.getOptionValue(GROUPFILE_OPTION_NAME);\n+        }\n+        if (cmd.hasOption(KEYFILE_OPTION_NAME)) {\n+            pubKeyPath = cmd.getOptionValue(KEYFILE_OPTION_NAME);\n+        }\n+\n+        if (pubKeyPath == null) {\n+            pubKeyPath = getPublicKeyFilePath();\n+        }\n+        try {\n+            pubKey = Credentials.getPublicKey(pubKeyPath);\n+        } catch (KeyException e) {\n+            exitWithErrorMessage(\"Could not retrieve public key from '\" + pubKeyPath, null, e);\n+        }\n+\n+        switch (action) {\n+            case CREATE:\n+                nonInteractive = (userInfo.getLogin() != null && userInfo.getPassword() != null && userInfo.getGroups() != null);\n+                break;\n+            case UPDATE:\n+                nonInteractive = (userInfo.getLogin() != null && userInfo.getPassword() != null) || (userInfo.getLogin() != null && userInfo.getGroups() != null);\n+                break;\n+            case DELETE:\n+                nonInteractive = userInfo.getLogin() != null;\n+                break;\n+        }\n+\n+        if (!nonInteractive) {\n+            askInteractively(console, userInfo, action);\n+        }\n+\n+        updateAccounts(pubKey, userInfo, loginFilePath, groupFilePath, action);\n+    }\n+\n+    /**\n+     * Ask the user for parameters missing on the command line\n+     */\n+    private static void askInteractively(Console console, UserInfo userInfo, Action action) {\n+        System.out.println(action);\n+        System.out.print(\"login: \");\n+        if (userInfo.getLogin() == null) {\n+            userInfo.setLogin(console.readLine());\n+        } else {\n+            System.out.println(userInfo.getLogin());\n+        }\n+        System.out.print(\"password: \");\n+        if ((action.isCreate() && userInfo.getPassword() == null) || (action.isUpdate() && userInfo.getPassword() == null && userInfo.getGroups() == null)) {\n+            userInfo.setPassword(new String(console.readPassword()));\n+        } else {\n+            System.out.println(\"*******\");\n+        }\n+\n+        if (action.isCreate() && userInfo.getGroups() == null) {\n+            System.out.print(\"groups for user \" + userInfo.getLogin() + \":\");\n+            String groupString = console.readLine();\n+            userInfo.setGroups(groupString.split(\",\"));\n+        }\n+    }\n+\n+    /**\n+     * Update the accounts in the login and config files\n+     *\n+     * @throws ManageUsersException\n+     */\n+    private static void updateAccounts(PublicKey pubKey, UserInfo userInfo, String loginFilePath, String groupFilePath, Action action) throws ManageUsersException {\n+        try {\n+            Properties props = new Properties();\n+            try {\n+                FileInputStream stream = new FileInputStream(new File(loginFilePath));\n+                props.load(stream);\n+                stream.close();\n+            } catch (Exception e) {\n+                exitWithErrorMessage(\"could not read login file : \" + loginFilePath, null, e);\n+            }\n+\n+            Multimap<String, String> groupsMap = loadGroups(groupFilePath);\n+\n+            switch (action) {\n+                case CREATE:\n+                    if (props.containsKey(userInfo.getLogin())) {\n+                        exitWithErrorMessage(\"USER already exists in login file : \" + loginFilePath, null, null);\n+                    }\n+                    updateUserPassword(pubKey, userInfo.getLogin(), userInfo.getPassword(), props);\n+                    System.out.println(\"Created user \" + userInfo.getLogin() + \" in \" + loginFilePath);\n+                    updateUserGroups(userInfo.getLogin(), userInfo.getGroups(), groupsMap);\n+                    break;\n+                case UPDATE:\n+                    if (!props.containsKey(userInfo.getLogin())) {\n+                        exitWithErrorMessage(\"USER does not exist in login file : \" + loginFilePath, null, null);\n+                    }\n+                    if (userInfo.getPassword() != null) {\n+                        updateUserPassword(pubKey, userInfo.getLogin(), userInfo.getPassword(), props);\n+                        System.out.println(\"Changed password for user \" + userInfo.getLogin() + \" in \" + loginFilePath);\n+                    }\n+                    if (userInfo.getGroups() != null) {\n+                        updateUserGroups(userInfo.getLogin(), userInfo.getGroups(), groupsMap);\n+                    }\n+                    break;\n+                case DELETE:\n+                    if (!props.containsKey(userInfo.getLogin())) {\n+                        exitWithErrorMessage(\"USER does not exist in login file : \" + loginFilePath, null, null);\n+                    }\n+                    props.remove(userInfo.getLogin());\n+                    groupsMap.removeAll(userInfo.getLogin());\n+                    System.out.println(\"Deleted user \" + userInfo.getLogin() + \" in \" + loginFilePath);\n+                    break;\n+            }\n+\n+            storeLoginFile(loginFilePath, props);\n+\n+            storeGroups(groupFilePath, groupsMap);\n+        } catch (Throwable t) {","path":"scheduler/scheduler-server/src/main/java/org/ow2/proactive/scheduler/authentication/ManageUsers.java","position":276,"original_position":276,"commit_id":"e14ad1d4d297cbb99a23fdf3a1163f9b64fbb8db","original_commit_id":"e14ad1d4d297cbb99a23fdf3a1163f9b64fbb8db","user":{"login":"sonarqube-activeeon","id":14940028,"avatar_url":"https://avatars.githubusercontent.com/u/14940028?v=3","gravatar_id":"","url":"https://api.github.com/users/sonarqube-activeeon","html_url":"https://github.com/sonarqube-activeeon","followers_url":"https://api.github.com/users/sonarqube-activeeon/followers","following_url":"https://api.github.com/users/sonarqube-activeeon/following{/other_user}","gists_url":"https://api.github.com/users/sonarqube-activeeon/gists{/gist_id}","starred_url":"https://api.github.com/users/sonarqube-activeeon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sonarqube-activeeon/subscriptions","organizations_url":"https://api.github.com/users/sonarqube-activeeon/orgs","repos_url":"https://api.github.com/users/sonarqube-activeeon/repos","events_url":"https://api.github.com/users/sonarqube-activeeon/events{/privacy}","received_events_url":"https://api.github.com/users/sonarqube-activeeon/received_events","type":"User","site_admin":false},"body":"![MINOR](https://raw.githubusercontent.com/SonarCommunity/sonar-github/master/images/severity-minor.png) Catch Exception instead of Throwable. [![rule](https://raw.githubusercontent.com/SonarCommunity/sonar-github/master/images/rule.png)](http://master.ci.activeeon.com:9000/coding_rules#rule_key=squid%3AS1181)\n","created_at":"2016-10-10T12:40:17Z","updated_at":"2016-10-10T12:40:17Z","html_url":"https://github.com/ow2-proactive/scheduling/pull/2679#discussion_r82595255","pull_request_url":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/2679","_links":{"self":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/comments/82595255"},"html":{"href":"https://github.com/ow2-proactive/scheduling/pull/2679#discussion_r82595255"},"pull_request":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/2679"}}},"pull_request":{"url":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/2679","id":87522185,"html_url":"https://github.com/ow2-proactive/scheduling/pull/2679","diff_url":"https://github.com/ow2-proactive/scheduling/pull/2679.diff","patch_url":"https://github.com/ow2-proactive/scheduling/pull/2679.patch","issue_url":"https://api.github.com/repos/ow2-proactive/scheduling/issues/2679","number":2679,"state":"open","locked":false,"title":"Encrypt credentials in login file","user":{"login":"fviale","id":3063713,"avatar_url":"https://avatars.githubusercontent.com/u/3063713?v=3","gravatar_id":"","url":"https://api.github.com/users/fviale","html_url":"https://github.com/fviale","followers_url":"https://api.github.com/users/fviale/followers","following_url":"https://api.github.com/users/fviale/following{/other_user}","gists_url":"https://api.github.com/users/fviale/gists{/gist_id}","starred_url":"https://api.github.com/users/fviale/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fviale/subscriptions","organizations_url":"https://api.github.com/users/fviale/orgs","repos_url":"https://api.github.com/users/fviale/repos","events_url":"https://api.github.com/users/fviale/events{/privacy}","received_events_url":"https://api.github.com/users/fviale/received_events","type":"User","site_admin":false},"body":"- created a manage-users command-line utility to create, update or delete users and store passwords encrypted with the scheduler public key\r\n\r\n- created a ManageUsersTest (unit) which tests creation, modification and deletion of several users\r\n\r\n- added two methods in HybridEncryptionUtil to encode and decode using base64 strings\r\n\r\n- Modified FileLoginModule to decrypt the content of login.cfg when checking for a user's password\r\n\r\n - modified the login.cfg file with the encrypted version of the password.","created_at":"2016-09-30T16:09:27Z","updated_at":"2016-10-10T12:40:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"76186db7d8e1de84af1b416766ba5cab2299336c","assignee":{"login":"fviale","id":3063713,"avatar_url":"https://avatars.githubusercontent.com/u/3063713?v=3","gravatar_id":"","url":"https://api.github.com/users/fviale","html_url":"https://github.com/fviale","followers_url":"https://api.github.com/users/fviale/followers","following_url":"https://api.github.com/users/fviale/following{/other_user}","gists_url":"https://api.github.com/users/fviale/gists{/gist_id}","starred_url":"https://api.github.com/users/fviale/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fviale/subscriptions","organizations_url":"https://api.github.com/users/fviale/orgs","repos_url":"https://api.github.com/users/fviale/repos","events_url":"https://api.github.com/users/fviale/events{/privacy}","received_events_url":"https://api.github.com/users/fviale/received_events","type":"User","site_admin":false},"assignees":[{"login":"fviale","id":3063713,"avatar_url":"https://avatars.githubusercontent.com/u/3063713?v=3","gravatar_id":"","url":"https://api.github.com/users/fviale","html_url":"https://github.com/fviale","followers_url":"https://api.github.com/users/fviale/followers","following_url":"https://api.github.com/users/fviale/following{/other_user}","gists_url":"https://api.github.com/users/fviale/gists{/gist_id}","starred_url":"https://api.github.com/users/fviale/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fviale/subscriptions","organizations_url":"https://api.github.com/users/fviale/orgs","repos_url":"https://api.github.com/users/fviale/repos","events_url":"https://api.github.com/users/fviale/events{/privacy}","received_events_url":"https://api.github.com/users/fviale/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/2679/commits","review_comments_url":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/2679/comments","review_comment_url":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ow2-proactive/scheduling/issues/2679/comments","statuses_url":"https://api.github.com/repos/ow2-proactive/scheduling/statuses/e14ad1d4d297cbb99a23fdf3a1163f9b64fbb8db","head":{"label":"fviale:master","ref":"master","sha":"e14ad1d4d297cbb99a23fdf3a1163f9b64fbb8db","user":{"login":"fviale","id":3063713,"avatar_url":"https://avatars.githubusercontent.com/u/3063713?v=3","gravatar_id":"","url":"https://api.github.com/users/fviale","html_url":"https://github.com/fviale","followers_url":"https://api.github.com/users/fviale/followers","following_url":"https://api.github.com/users/fviale/following{/other_user}","gists_url":"https://api.github.com/users/fviale/gists{/gist_id}","starred_url":"https://api.github.com/users/fviale/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fviale/subscriptions","organizations_url":"https://api.github.com/users/fviale/orgs","repos_url":"https://api.github.com/users/fviale/repos","events_url":"https://api.github.com/users/fviale/events{/privacy}","received_events_url":"https://api.github.com/users/fviale/received_events","type":"User","site_admin":false},"repo":{"id":36877569,"name":"scheduling","full_name":"fviale/scheduling","owner":{"login":"fviale","id":3063713,"avatar_url":"https://avatars.githubusercontent.com/u/3063713?v=3","gravatar_id":"","url":"https://api.github.com/users/fviale","html_url":"https://github.com/fviale","followers_url":"https://api.github.com/users/fviale/followers","following_url":"https://api.github.com/users/fviale/following{/other_user}","gists_url":"https://api.github.com/users/fviale/gists{/gist_id}","starred_url":"https://api.github.com/users/fviale/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fviale/subscriptions","organizations_url":"https://api.github.com/users/fviale/orgs","repos_url":"https://api.github.com/users/fviale/repos","events_url":"https://api.github.com/users/fviale/events{/privacy}","received_events_url":"https://api.github.com/users/fviale/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/fviale/scheduling","description":"Multi-platform Scheduling and Workflows engine","fork":true,"url":"https://api.github.com/repos/fviale/scheduling","forks_url":"https://api.github.com/repos/fviale/scheduling/forks","keys_url":"https://api.github.com/repos/fviale/scheduling/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fviale/scheduling/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fviale/scheduling/teams","hooks_url":"https://api.github.com/repos/fviale/scheduling/hooks","issue_events_url":"https://api.github.com/repos/fviale/scheduling/issues/events{/number}","events_url":"https://api.github.com/repos/fviale/scheduling/events","assignees_url":"https://api.github.com/repos/fviale/scheduling/assignees{/user}","branches_url":"https://api.github.com/repos/fviale/scheduling/branches{/branch}","tags_url":"https://api.github.com/repos/fviale/scheduling/tags","blobs_url":"https://api.github.com/repos/fviale/scheduling/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fviale/scheduling/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fviale/scheduling/git/refs{/sha}","trees_url":"https://api.github.com/repos/fviale/scheduling/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fviale/scheduling/statuses/{sha}","languages_url":"https://api.github.com/repos/fviale/scheduling/languages","stargazers_url":"https://api.github.com/repos/fviale/scheduling/stargazers","contributors_url":"https://api.github.com/repos/fviale/scheduling/contributors","subscribers_url":"https://api.github.com/repos/fviale/scheduling/subscribers","subscription_url":"https://api.github.com/repos/fviale/scheduling/subscription","commits_url":"https://api.github.com/repos/fviale/scheduling/commits{/sha}","git_commits_url":"https://api.github.com/repos/fviale/scheduling/git/commits{/sha}","comments_url":"https://api.github.com/repos/fviale/scheduling/comments{/number}","issue_comment_url":"https://api.github.com/repos/fviale/scheduling/issues/comments{/number}","contents_url":"https://api.github.com/repos/fviale/scheduling/contents/{+path}","compare_url":"https://api.github.com/repos/fviale/scheduling/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fviale/scheduling/merges","archive_url":"https://api.github.com/repos/fviale/scheduling/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fviale/scheduling/downloads","issues_url":"https://api.github.com/repos/fviale/scheduling/issues{/number}","pulls_url":"https://api.github.com/repos/fviale/scheduling/pulls{/number}","milestones_url":"https://api.github.com/repos/fviale/scheduling/milestones{/number}","notifications_url":"https://api.github.com/repos/fviale/scheduling/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fviale/scheduling/labels{/name}","releases_url":"https://api.github.com/repos/fviale/scheduling/releases{/id}","deployments_url":"https://api.github.com/repos/fviale/scheduling/deployments","created_at":"2015-06-04T15:07:00Z","updated_at":"2016-01-20T18:13:45Z","pushed_at":"2016-10-10T08:16:27Z","git_url":"git://github.com/fviale/scheduling.git","ssh_url":"git@github.com:fviale/scheduling.git","clone_url":"https://github.com/fviale/scheduling.git","svn_url":"https://github.com/fviale/scheduling","homepage":"http://www.activeeon.com/workflows-scheduling","size":65492,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"ow2-proactive:master","ref":"master","sha":"4d7b3faddac9ff8b00b95477f1e4ebc7e0b4b38c","user":{"login":"ow2-proactive","id":11553998,"avatar_url":"https://avatars.githubusercontent.com/u/11553998?v=3","gravatar_id":"","url":"https://api.github.com/users/ow2-proactive","html_url":"https://github.com/ow2-proactive","followers_url":"https://api.github.com/users/ow2-proactive/followers","following_url":"https://api.github.com/users/ow2-proactive/following{/other_user}","gists_url":"https://api.github.com/users/ow2-proactive/gists{/gist_id}","starred_url":"https://api.github.com/users/ow2-proactive/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ow2-proactive/subscriptions","organizations_url":"https://api.github.com/users/ow2-proactive/orgs","repos_url":"https://api.github.com/users/ow2-proactive/repos","events_url":"https://api.github.com/users/ow2-proactive/events{/privacy}","received_events_url":"https://api.github.com/users/ow2-proactive/received_events","type":"Organization","site_admin":false},"repo":{"id":35725079,"name":"scheduling","full_name":"ow2-proactive/scheduling","owner":{"login":"ow2-proactive","id":11553998,"avatar_url":"https://avatars.githubusercontent.com/u/11553998?v=3","gravatar_id":"","url":"https://api.github.com/users/ow2-proactive","html_url":"https://github.com/ow2-proactive","followers_url":"https://api.github.com/users/ow2-proactive/followers","following_url":"https://api.github.com/users/ow2-proactive/following{/other_user}","gists_url":"https://api.github.com/users/ow2-proactive/gists{/gist_id}","starred_url":"https://api.github.com/users/ow2-proactive/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ow2-proactive/subscriptions","organizations_url":"https://api.github.com/users/ow2-proactive/orgs","repos_url":"https://api.github.com/users/ow2-proactive/repos","events_url":"https://api.github.com/users/ow2-proactive/events{/privacy}","received_events_url":"https://api.github.com/users/ow2-proactive/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ow2-proactive/scheduling","description":"Multi-platform Scheduling and Workflows Engine","fork":false,"url":"https://api.github.com/repos/ow2-proactive/scheduling","forks_url":"https://api.github.com/repos/ow2-proactive/scheduling/forks","keys_url":"https://api.github.com/repos/ow2-proactive/scheduling/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ow2-proactive/scheduling/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ow2-proactive/scheduling/teams","hooks_url":"https://api.github.com/repos/ow2-proactive/scheduling/hooks","issue_events_url":"https://api.github.com/repos/ow2-proactive/scheduling/issues/events{/number}","events_url":"https://api.github.com/repos/ow2-proactive/scheduling/events","assignees_url":"https://api.github.com/repos/ow2-proactive/scheduling/assignees{/user}","branches_url":"https://api.github.com/repos/ow2-proactive/scheduling/branches{/branch}","tags_url":"https://api.github.com/repos/ow2-proactive/scheduling/tags","blobs_url":"https://api.github.com/repos/ow2-proactive/scheduling/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ow2-proactive/scheduling/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ow2-proactive/scheduling/git/refs{/sha}","trees_url":"https://api.github.com/repos/ow2-proactive/scheduling/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ow2-proactive/scheduling/statuses/{sha}","languages_url":"https://api.github.com/repos/ow2-proactive/scheduling/languages","stargazers_url":"https://api.github.com/repos/ow2-proactive/scheduling/stargazers","contributors_url":"https://api.github.com/repos/ow2-proactive/scheduling/contributors","subscribers_url":"https://api.github.com/repos/ow2-proactive/scheduling/subscribers","subscription_url":"https://api.github.com/repos/ow2-proactive/scheduling/subscription","commits_url":"https://api.github.com/repos/ow2-proactive/scheduling/commits{/sha}","git_commits_url":"https://api.github.com/repos/ow2-proactive/scheduling/git/commits{/sha}","comments_url":"https://api.github.com/repos/ow2-proactive/scheduling/comments{/number}","issue_comment_url":"https://api.github.com/repos/ow2-proactive/scheduling/issues/comments{/number}","contents_url":"https://api.github.com/repos/ow2-proactive/scheduling/contents/{+path}","compare_url":"https://api.github.com/repos/ow2-proactive/scheduling/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ow2-proactive/scheduling/merges","archive_url":"https://api.github.com/repos/ow2-proactive/scheduling/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ow2-proactive/scheduling/downloads","issues_url":"https://api.github.com/repos/ow2-proactive/scheduling/issues{/number}","pulls_url":"https://api.github.com/repos/ow2-proactive/scheduling/pulls{/number}","milestones_url":"https://api.github.com/repos/ow2-proactive/scheduling/milestones{/number}","notifications_url":"https://api.github.com/repos/ow2-proactive/scheduling/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ow2-proactive/scheduling/labels{/name}","releases_url":"https://api.github.com/repos/ow2-proactive/scheduling/releases{/id}","deployments_url":"https://api.github.com/repos/ow2-proactive/scheduling/deployments","created_at":"2015-05-16T13:38:55Z","updated_at":"2016-07-29T16:18:16Z","pushed_at":"2016-10-10T10:24:23Z","git_url":"git://github.com/ow2-proactive/scheduling.git","ssh_url":"git@github.com:ow2-proactive/scheduling.git","clone_url":"https://github.com/ow2-proactive/scheduling.git","svn_url":"https://github.com/ow2-proactive/scheduling","homepage":"http://www.activeeon.com/workflows-scheduling","size":66046,"stargazers_count":17,"watchers_count":17,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":20,"mirror_url":null,"open_issues_count":154,"forks":20,"open_issues":154,"watchers":17,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/2679"},"html":{"href":"https://github.com/ow2-proactive/scheduling/pull/2679"},"issue":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/issues/2679"},"comments":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/issues/2679/comments"},"review_comments":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/2679/comments"},"review_comment":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/pulls/2679/commits"},"statuses":{"href":"https://api.github.com/repos/ow2-proactive/scheduling/statuses/e14ad1d4d297cbb99a23fdf3a1163f9b64fbb8db"}}}}
{"actor":{"display_login":"sonarqube-activeeon"}}