private ApplicationLink getAppLink(final URI pageUri) { // TODO sort by length to cover case where mulitple base URLs match, e.g. something.com and // something.com/confluence for (final ApplicationLink appLink : getConfluenceAppLinks()) { if (UriMatcher.isBaseEqual(appLink.getDisplayUrl(), pageUri)) { return appLink; } } return null; }
@Override public void issueSharedSecret(@Nonnull ApplicationLink applicationLink, @Nonnull String path) throws JwtRegistrationFailedException { // generate secure shared secret String sharedSecret = SecretGenerator.generateUrlSafeSharedSecret(SigningAlgorithm.HS256); Object addOnKey = applicationLink.getProperty(ADD_ON_ID_PROPERTY_NAME); if (null == addOnKey) { throw new JwtRegistrationFailedException( String.format( "Application link '%s' has no '%s' property. It should have been set during add-on installation! Please reinstall the add-on.", applicationLink.getId(), ADD_ON_ID_PROPERTY_NAME)); } // pass shared secret to peer try { applicationLink .createAuthenticatedRequestFactory(Anonymous.class) .createRequest(Request.MethodType.POST, path) .addRequestParameters( "myId", hostApplication.getId().get(), "yourId", addOnKey.toString(), "secret", sharedSecret) .execute( new ResponseHandler<Response>() { @Override public void handle(Response response) throws ResponseException { if (!response.isSuccessful()) { throw new ResponseException( "Registration failed, received " + response.getStatusCode() + " " + response.getStatusText() + " from peer."); } } }); } catch (ResponseException e) { throw new JwtRegistrationFailedException(e); } catch (CredentialsRequiredException e) { // will not happen with an Anonymous authentication provider throw new IllegalStateException(e); } // store the shared secret on the application link applicationLink.putProperty(SHARED_SECRET_PROPERTY_NAME, sharedSecret); }
@SuppressWarnings("unused") public String getAppId() { if (appLink != null) { return appLink.getId().get(); } return ""; }
protected void doValidation() { // Validate comment and permissions super.doValidation(); // Make sure the URL belongs to an application link appLink = validatePageUrl(pageUrl); String pageId = null; if (!hasAnyErrors()) { pageId = getPageId(pageUrl, appLink); } if (!hasAnyErrors()) { if (pageId == null) { addErrorMessage(getText("addconfluencelink.error.pageid.notfound")); } } if (!hasAnyErrors()) { final String globalId = ConfluenceGlobalIdFactoryImpl.encode(appLink.getId(), pageId); final RemoteIssueLink remoteIssueLink = new RemoteIssueLinkBuilder() .issueId(getIssue().getLong("id")) .url(buildPageUrl(appLink, pageId)) .title(TITLE) .globalId(globalId) .relationship(RELATIONSHIP) .applicationType(RemoteIssueLink.APPLICATION_TYPE_CONFLUENCE) .applicationName(appLink.getName()) .build(); validationResult = remoteIssueLinkService.validateCreate(getLoggedInUser(), remoteIssueLink); if (!validationResult.isValid()) { mapErrors(validationResult.getErrorCollection()); addErrorCollection(validationResult.getErrorCollection()); } } }
@Override public void revokeSharedSecret(@Nonnull ApplicationLink applicationLink) { applicationLink.removeProperty(SHARED_SECRET_PROPERTY_NAME); }
private static String buildPageUrl(final ApplicationLink appLink, final String pageId) { return new UrlBuilder(appLink.getDisplayUrl().toASCIIString()) .addPathUnsafe("pages/viewpage.action") .addParameter("pageId", pageId) .asUrlString(); }