I've implemented a Credential type that stores the OAuth details and uses a
form on a new window to present the OAuth flow and then populate back the
token, e.g.
in the credentials.jelly:
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler"
xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson"
xmlns:f="/lib/form">
<j:set var="needAuth" value="${instance==null ||
instance.userId==null || instance.userId.length() == 0}"/>
<j:if test="${!needAuth}">
<f:entry title="${%Account}" >
<div style="display:none">
<f:password field="oAuth2RefreshToken"/>
</div>
<f:textbox field="userId" disabled="true"/>
</f:entry>
</j:if>
<j:if test="${needAuth}">
<j:set var="authId" value="${descriptor.newAuthId}"/>
<f:entry title="${%Account}">
<div id="${authId}">
<input type="button" value="${%Authenticate}..."
onclick="window.open('${rootUrl}/descriptor/com.cloudbees.jenkins.plugins.gaecredentials.GoogleAppEngineCredentialsImpl/authenticate?authId=${authId}',
'auth').opener=window; return false;" class="submit-button" />
</div>
</f:entry>
</j:if>
</j:jelly>
Then in the callback's index.jelly
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form"
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" >
<l:layout>
<l:main-panel>
<j:set var="instance" value="${it}"/>
<div style="display:none">
<div id="content">
<div style="display:none">
<f:password field="oAuth2RefreshToken"/>
</div>
<f:textbox field="userId" disabled="true"/>
</div>
</div>
<script>
try {
var id="${it.authId}";
var newDiv = document.getElementById('content');
var oldDiv = window.opener.document.getElementById(id);
oldDiv.innerHTML = newDiv.innerHTML;
} catch (e) {
// ignore
}
window.close();
</script>
</l:main-panel>
</l:layout>
</j:jelly>
And the callback class looks something like:
public static class Callback {
private final Secret oAuth2RefreshToken;
private final String userId;
private final String authId;
public Callback(GoogleCredential accessTokenResponse, Userinfo
userinfo, String authId) {
this.userId = userinfo.getEmail();
this.oAuth2RefreshToken =
Secret.fromString(accessTokenResponse.getRefreshToken());
this.authId = authId;
}
public Secret getOAuth2RefreshToken() {
return oAuth2RefreshToken;
}
public String getUserId() {
return userId;
}
public String getAuthId() {
return authId;
}
}
Which gets instantiated using this method (which is bound to the callback
endpoint)
public void doIndex(StaplerRequest request, StaplerResponse
response, @QueryParameter String state,
@QueryParameter String code) throws
IOException, ServletException {
// parse the code
NetHttpTransport transport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
TokenResponse tokenResponse = null;
try {
tokenResponse =
new GoogleAuthorizationCodeTokenRequest(
transport, jsonFactory, CLIENT_ID,
CLIENT_SECRET, code,
getCallbackUrl()
).execute();
} catch (HttpResponseException e) {
}
// look up the email address
GoogleCredential credential =
new GoogleCredential.Builder()
.setTransport(transport)
.setJsonFactory(jsonFactory)
.setClientSecrets(CLIENT_ID, CLIENT_SECRET)
.build()
.setFromTokenResponse(tokenResponse);
Oauth2 oauth2 = new Oauth2.Builder(credential.getTransport(),
credential.getJsonFactory(), null)
.setHttpRequestInitializer(credential)
.setJsonHttpRequestInitializer(new
JsonHttpRequestInitializer() {
public void initialize(JsonHttpRequest request)
throws IOException {
if (request instanceof Oauth2Request) {
Oauth2Request oauth2Request =
(Oauth2Request) request;
oauth2Request.setPrettyPrint(true);
oauth2Request.setKey(CLIENT_ID);
}
}
})
.build();
Userinfo userinfo = oauth2.userinfo().get().execute();
// now sort out passing back the details
response.forward(new Callback(credential, userinfo,
request.getParameter("state")), "index", request);
}
So what happens is that if the credential has just been created there is an
Authenticate button... clicking the button will open a new window (tab) for
a page from the local domain (so that we can interact via scripts). That
URL does an immediate redirect to the OAuth end-point passing back the
callback URL. Once OAuth completes it comes back to the callback, which
captures the authorization and renders a page that uses javascript to close
itself after injecting back the reference into the page that opened the tab
in the first place.
There may be other ways, but that was the easiest to keep working
On 23 December 2015 at 09:56, Thomas Einwaller <[email protected]>
wrote:
> I am working on a Jenkins plugin that uses the new Bitbucket Build Status
> API. The best way to access the API is using oauth.
>
> What is the best way of building oauth into my Jenkins plugin? Should I
> use a oauth Java library or is there another Jenkins plugin I can depend my
> plugin on?
>
> How would the process of "connecting" Jenkins and my plugin to the
> Bitbucket account (granting access and storing the tokens)?
>
> --
> You received this message because you are subscribed to the Google Groups
> "Jenkins Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jenkinsci-users/d63d3781-48ae-4704-8365-6258d44592a0%40googlegroups.com
> <https://groups.google.com/d/msgid/jenkinsci-users/d63d3781-48ae-4704-8365-6258d44592a0%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/jenkinsci-users/CA%2BnPnMz8Sky9b0nC3t9QS2Gy_YfLy%2B7x6pjYD3_oh%2B5QHuUw%3Dw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.