PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/atlassian/jira/plugins/bitbucket/spi/github/webwork/AddGithubRepository.java

https://bitbucket.org/atlassian/jira-bitbucket-connector/
Java | 302 lines | 246 code | 51 blank | 5 comment | 17 complexity | affa904e0bb79732721f524284b1dea8 MD5 | raw file
  1. package com.atlassian.jira.plugins.bitbucket.spi.github.webwork;
  2. import java.io.BufferedReader;
  3. import java.io.InputStreamReader;
  4. import java.net.HttpURLConnection;
  5. import java.net.MalformedURLException;
  6. import java.net.URL;
  7. import org.apache.commons.lang.StringUtils;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.beans.factory.annotation.Qualifier;
  11. import com.atlassian.jira.plugins.bitbucket.Synchronizer;
  12. import com.atlassian.jira.plugins.bitbucket.api.SourceControlException;
  13. import com.atlassian.jira.plugins.bitbucket.api.SourceControlRepository;
  14. import com.atlassian.jira.plugins.bitbucket.spi.CustomStringUtils;
  15. import com.atlassian.jira.plugins.bitbucket.spi.RepositoryManager;
  16. import com.atlassian.jira.plugins.bitbucket.spi.github.GithubOAuth;
  17. import com.atlassian.jira.plugins.bitbucket.spi.github.impl.GithubRepositoryManager;
  18. import com.atlassian.jira.security.xsrf.RequiresXsrfCheck;
  19. import com.atlassian.jira.web.action.JiraWebActionSupport;
  20. import com.atlassian.sal.api.ApplicationProperties;
  21. import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
  22. public class AddGithubRepository extends JiraWebActionSupport
  23. {
  24. private final Logger log = LoggerFactory.getLogger(AddGithubRepository.class);
  25. private String repositoryUrl;
  26. private String projectKey;
  27. private String isPrivate;
  28. private String addPostCommitService ;
  29. private String code;
  30. private final RepositoryManager globalRepositoryManager;
  31. private final Synchronizer synchronizer;
  32. private final ApplicationProperties ap;
  33. private final GithubOAuth githubOAuth;
  34. private String postCommitUrl;
  35. private String accessToken = "";
  36. private final PluginSettingsFactory pluginSettingsFactory;
  37. public AddGithubRepository(@Qualifier("globalRepositoryManager") RepositoryManager globalRepositoryManager, Synchronizer synchronizer,
  38. ApplicationProperties applicationProperties, GithubOAuth githubOAuth, PluginSettingsFactory pluginSettingsFactory)
  39. {
  40. this.globalRepositoryManager = globalRepositoryManager;
  41. this.synchronizer = synchronizer;
  42. this.ap = applicationProperties;
  43. this.githubOAuth = githubOAuth;
  44. this.pluginSettingsFactory = pluginSettingsFactory;
  45. }
  46. @Override
  47. protected void doValidation()
  48. {
  49. }
  50. @Override
  51. public String doDefault() throws Exception
  52. {
  53. if (oAuthIsNeeded()) {
  54. checkOAuthConfig();
  55. }
  56. return INPUT;
  57. }
  58. @Override
  59. @RequiresXsrfCheck
  60. protected String doExecute() throws Exception
  61. {
  62. if (oAuthIsNeeded()) {
  63. checkOAuthConfig();
  64. if (hasAnyErrors()) {
  65. return INPUT;
  66. }
  67. return redirectUserToGithub();
  68. }
  69. return doAddRepository();
  70. }
  71. private void checkOAuthConfig() {
  72. if (StringUtils.isBlank(githubOAuth.getClientId()))
  73. {
  74. String oAuthSetupUrl = ap.getBaseUrl() + "/secure/admin/ConfigureGithubOAuth!default.jspa";
  75. if (isPrivate())
  76. {
  77. addErrorMessage("OAuth needs to be <a href='"+oAuthSetupUrl+"' target='_blank'>configured</a> before adding private github repository.");
  78. } else
  79. {
  80. addErrorMessage("OAuth needs to be <a href='"+oAuthSetupUrl+"' target='_blank'>configured</a> before install postcommit service.");
  81. }
  82. }
  83. }
  84. private boolean oAuthIsNeeded()
  85. {
  86. return isPrivate() || addPostCommitService();
  87. }
  88. private String redirectUserToGithub()
  89. {
  90. String encodedRepositoryUrl = CustomStringUtils.encode(repositoryUrl);
  91. String redirectBackUrl = ap.getBaseUrl() + "/secure/admin/AddGithubRepository!finish.jspa?repositoryUrl=" + encodedRepositoryUrl
  92. + "&projectKey=" + projectKey + "&addPostCommitService=" + addPostCommitService() + "&atl_token=" + getXsrfToken();
  93. String encodedRedirectBackUrl = CustomStringUtils.encode(redirectBackUrl);
  94. String githubAuthorizeUrl = "https://github.com/login/oauth/authorize?scope=repo&client_id=" + githubOAuth.getClientId()
  95. + "&redirect_uri=" + encodedRedirectBackUrl;
  96. fixBackwardCompatibility();
  97. return getRedirect(githubAuthorizeUrl);
  98. }
  99. /**
  100. * TODO add detailed comment what is this for.
  101. * @param redirectBackUrl
  102. */
  103. private void fixBackwardCompatibility()
  104. {
  105. String encodedRepositoryUrl = CustomStringUtils.encode(repositoryUrl);
  106. String parameters = "repositoryUrl=" + encodedRepositoryUrl + "&projectKey=" + projectKey + "&addPostCommitService="
  107. + addPostCommitService() + "&atl_token=" + getXsrfToken();
  108. String redirectBackUrl = ap.getBaseUrl() + "/secure/admin/GitHubOAuth2.jspa?" + parameters;
  109. String encodedRedirectBackUrl = CustomStringUtils.encode(redirectBackUrl);
  110. String githubAuthorizeUrl = "https://github.com/login/oauth/authorize?scope=repo&client_id=" + githubOAuth.getClientId()
  111. + "&redirect_uri=" + encodedRedirectBackUrl;
  112. pluginSettingsFactory.createGlobalSettings().put("OAuthRedirectUrl", githubAuthorizeUrl);
  113. pluginSettingsFactory.createGlobalSettings().put("OAuthRedirectUrlParameters", parameters);
  114. }
  115. public String doFinish()
  116. {
  117. try
  118. {
  119. accessToken = requestAccessToken();
  120. } catch (SourceControlException sce)
  121. {
  122. addErrorMessage(sce.getMessage());
  123. return INPUT;
  124. }
  125. return doAddRepository();
  126. }
  127. private String doAddRepository()
  128. {
  129. SourceControlRepository repository;
  130. try
  131. {
  132. repository = globalRepositoryManager.addRepository(GithubRepositoryManager.GITHUB, projectKey, repositoryUrl, "", "",
  133. "", "", accessToken);
  134. synchronizer.synchronize(repository);
  135. } catch (SourceControlException e)
  136. {
  137. addErrorMessage("Failed adding the repository: ["+e.getMessage()+"]");
  138. log.debug("Failed adding the repository: ["+e.getMessage()+"]");
  139. return INPUT;
  140. }
  141. try
  142. {
  143. if (addPostCommitService())
  144. globalRepositoryManager.setupPostcommitHook(repository);
  145. } catch (SourceControlException e)
  146. {
  147. log.debug("Failed adding postcommit hook: ["+e.getMessage()+"]");
  148. postCommitUrl = ap.getBaseUrl() + "/rest/bitbucket/1.0/repository/" + repository.getId() + "/sync";
  149. return ERROR;
  150. }
  151. return getRedirect("ConfigureBitbucketRepositories.jspa?addedRepositoryId="+repository.getId()+"&atl_token=" + getXsrfToken());
  152. }
  153. // TODO rewrite this nicely (using RequestFactory)
  154. private String requestAccessToken()
  155. {
  156. URL url;
  157. HttpURLConnection conn;
  158. BufferedReader rd;
  159. String line;
  160. String result = "";
  161. if (StringUtils.isEmpty(code)) {
  162. throw new SourceControlException("Ops, no access code returned. Did you click Allow?");
  163. }
  164. try
  165. {
  166. log.debug("requestAccessToken() - " + "https://github.com/login/oauth/access_token?&client_id=" + githubOAuth.getClientId()
  167. + "&client_secret=" + githubOAuth.getClientSecret() + "&code=" + code);
  168. url = new URL("https://github.com/login/oauth/access_token?&client_id=" + githubOAuth.getClientId() + "&client_secret="
  169. + githubOAuth.getClientSecret() + "&code=" + code);
  170. conn = (HttpURLConnection) url.openConnection();
  171. conn.setInstanceFollowRedirects(true);
  172. conn.setRequestMethod("POST");
  173. rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  174. while ((line = rd.readLine()) != null)
  175. {
  176. log.debug("RESPONSE: " + line);
  177. result += line;
  178. }
  179. rd.close();
  180. } catch (MalformedURLException e)
  181. {
  182. log.error("Error obtain access token", e);
  183. } catch (Exception e)
  184. {
  185. log.error("Error obtain access token", e);
  186. }
  187. if (result.startsWith("error="))
  188. {
  189. String errorCode = result.replaceAll("error=", "");
  190. String error = errorCode;
  191. if (errorCode.equals("incorrect_client_credentials"))
  192. {
  193. error = "Incorrect client credentials";
  194. } else if (errorCode.equals("bad_verification_code"))
  195. {
  196. error = "Bad verification code";
  197. }
  198. throw new SourceControlException("Error obtaining access token: " + error);
  199. }
  200. result = result.replaceAll("access_token=(.*)&token_type.*", "$1");
  201. return result;
  202. }
  203. public String getRepositoryUrl()
  204. {
  205. return repositoryUrl;
  206. }
  207. public void setRepositoryUrl(String repositoryUrl)
  208. {
  209. this.repositoryUrl = repositoryUrl;
  210. }
  211. public String getProjectKey()
  212. {
  213. return projectKey;
  214. }
  215. public void setProjectKey(String projectKey)
  216. {
  217. this.projectKey = projectKey;
  218. }
  219. public boolean isPrivate()
  220. {
  221. return Boolean.parseBoolean(isPrivate);
  222. }
  223. public void setIsPrivate(String isPrivate)
  224. {
  225. this.isPrivate = isPrivate;
  226. }
  227. public String getCode()
  228. {
  229. return code;
  230. }
  231. public void setCode(String code)
  232. {
  233. this.code = code;
  234. }
  235. public boolean addPostCommitService()
  236. {
  237. return addPostCommitService != null && (addPostCommitService.toLowerCase().equals("on") || addPostCommitService.toLowerCase().equals("true"));
  238. }
  239. public void setAddPostCommitService(String addPostCommitService)
  240. {
  241. this.addPostCommitService = addPostCommitService;
  242. }
  243. public String getPostCommitUrl()
  244. {
  245. return postCommitUrl;
  246. }
  247. public void setPostCommitUrl(String postCommitUrl)
  248. {
  249. this.postCommitUrl = postCommitUrl;
  250. }
  251. }