com.marvelution.jenkins.plugins.jira.oauth.action.AccessTokenOAuthAction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jenkins-jira-plugin Show documentation
Show all versions of jenkins-jira-plugin Show documentation
Jenkins plugin for integrating with JIRA
/*
* JIRA Plugin for Jenkins
* Copyright (C) 2012 Marvelution
* [email protected]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.marvelution.jenkins.plugins.jira.oauth.action;
import com.atlassian.oauth.Request;
import com.atlassian.oauth.serviceprovider.Clock;
import com.atlassian.oauth.serviceprovider.ServiceProviderToken;
import com.atlassian.oauth.serviceprovider.SystemClock;
import com.marvelution.jenkins.plugins.jira.JIRAPlugin;
import com.marvelution.jenkins.plugins.jira.oauth.utils.ConsumerUtils;
import com.marvelution.jenkins.plugins.jira.store.ApplicationLinkStore;
import com.marvelution.jenkins.plugins.jira.store.ServiceProviderTokenStore;
import com.marvelution.jenkins.plugins.jira.utils.UriUtils;
import hudson.Extension;
import net.oauth.OAuth;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthMessage;
import net.oauth.OAuthProblemException;
import net.oauth.server.OAuthServlet;
import org.apache.commons.lang.RandomStringUtils;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import static net.oauth.server.OAuthServlet.handleException;
/**
* {@link OAuthAction} implemented to allow for getting access tokens
*
* @author Mark Rekveld
* @since 1.0.0
*/
@Extension
public class AccessTokenOAuthAction extends OAuthAction {
public static final String URL_NAME = "access-token";
private final Clock clock = new SystemClock();
@Override
public String getUrlName() {
return URL_NAME;
}
/**
* Handler for the access-token request
*
* @param request the {@link org.kohsuke.stapler.StaplerRequest}
* @param response the {@link org.kohsuke.stapler.StaplerResponse}
* @throws Exception
*/
public void doIndex(StaplerRequest request, StaplerResponse response) throws Exception {
ServiceProviderToken accessToken;
ServiceProviderTokenStore tokenStore = ServiceProviderTokenStore.getStore();
try {
OAuthMessage requestMessage = OAuthServlet.getMessage(request, UriUtils.getLogicalUri(request));
requestMessage.requireParameters(OAuth.OAUTH_TOKEN);
ServiceProviderToken token = tokenStore.getToken(requestMessage.getToken());
if (token == null) {
throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
}
if (token.isRequestToken()) {
checkRequestToken(requestMessage, token);
} else {
checkAccessToken(requestMessage, token);
}
JIRAPlugin.getOAuthValidator().validateMessage(requestMessage, getOAuthAccessor(token));
accessToken = tokenStore.addToken(ServiceProviderToken.newAccessToken(RandomStringUtils.randomAlphanumeric(32))
.tokenSecret(token.getTokenSecret())
.consumer(token.getConsumer())
.authorizedBy(token.getUser())
.session(newSession(token))
.build());
tokenStore.removeToken(token.getToken());
} catch (Exception e) {
handleException(response, e, ApplicationLinkStore.getStore().getApplicationUrl(), true);
return;
}
response.setContentType("text/plain");
OAuth.formEncode(OAuth.newList(
OAuth.OAUTH_TOKEN, accessToken.getToken(),
OAuth.OAUTH_TOKEN_SECRET, accessToken.getTokenSecret(),
Request.OAUTH_EXPIRES_IN, Long.toString(accessToken.getTimeToLive() / 1000),
Request.OAUTH_SESSION_HANDLE, accessToken.getSession().getHandle(),
Request.OAUTH_AUTHORIZATION_EXPIRES_IN, Long.toString(accessToken.getSession().getTimeToLive() / 1000)
), response.getOutputStream());
}
/**
* Check the given {code token} to see if its a valid request token
*
* @param requestMessage the {@link net.oauth.OAuthMessage}
* @param token the {@link com.atlassian.oauth.serviceprovider.ServiceProviderToken request token}
* @throws OAuthProblemException
* @throws IOException
*/
private void checkRequestToken(OAuthMessage requestMessage, ServiceProviderToken token) throws OAuthProblemException, IOException {
if (token.hasExpired(clock)) {
throw new OAuthProblemException(OAuth.Problems.TOKEN_EXPIRED);
}
if (token.getAuthorization() == ServiceProviderToken.Authorization.NONE) {
throw new OAuthProblemException(OAuth.Problems.PERMISSION_UNKNOWN);
}
if (token.getAuthorization() == ServiceProviderToken.Authorization.DENIED) {
throw new OAuthProblemException(OAuth.Problems.PERMISSION_DENIED);
}
if (!token.getConsumer().getKey().equals(requestMessage.getConsumerKey())) {
throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
}
if (ServiceProviderToken.Version.V_1_0_A.equals(token.getVersion())) {
requestMessage.requireParameters(OAuth.OAUTH_VERIFIER);
if (token.getVerifier() != null && !token.getVerifier().equals(requestMessage.getParameter(OAuth.OAUTH_VERIFIER))) {
throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
}
}
}
/**
* Check the given {code token} to see if its a valid access token
*
* @param requestMessage the {@link net.oauth.OAuthMessage}
* @param token the {@link com.atlassian.oauth.serviceprovider.ServiceProviderToken access token}
* @throws OAuthProblemException
* @throws IOException
*/
private void checkAccessToken(OAuthMessage requestMessage, ServiceProviderToken token) throws OAuthProblemException, IOException {
if (token.getSession() == null) {
throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
}
requestMessage.requireParameters(Request.OAUTH_SESSION_HANDLE);
if (!token.getSession().getHandle().equals(requestMessage.getParameter(Request.OAUTH_SESSION_HANDLE))) {
throw new OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
}
if (token.getSession().hasExpired(clock)) {
throw new OAuthProblemException(OAuth.Problems.PERMISSION_DENIED);
}
}
/**
* Get the {@link net.oauth.OAuthAccessor} for the given {@code token}
*
* @param token the {@link com.atlassian.oauth.serviceprovider.ServiceProviderToken}
* @return the {@link net.oauth.OAuthAccessor}
* @throws IOException
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
*/
private OAuthAccessor getOAuthAccessor(ServiceProviderToken token) throws IOException, InvalidKeySpecException,
NoSuchAlgorithmException {
return new OAuthAccessor(ConsumerUtils.toOAuthConsumer(token));
}
/**
* Create a new {@link com.atlassian.oauth.serviceprovider.ServiceProviderToken.Session} for the given {@code token}
*
* @param token the {@link com.atlassian.oauth.serviceprovider.ServiceProviderToken} to create the session for
* @return the new {@link com.atlassian.oauth.serviceprovider.ServiceProviderToken.Session}
*/
private ServiceProviderToken.Session newSession(ServiceProviderToken token) {
ServiceProviderToken.Session.Builder builder = ServiceProviderToken.Session.newSession(RandomStringUtils.randomAlphanumeric(32));
if (token.getSession() != null) {
builder.creationTime(token.getSession().getCreationTime());
}
return builder.build();
}
}