Skip to content

Commit

Permalink
[JENKINS-30574] Make GlobalQueueItemAuthenticator work with SpecificU…
Browse files Browse the repository at this point in the history
…sersAuthorizationStrategy
  • Loading branch information
ikedam committed Mar 6, 2016
1 parent 6137153 commit 932d35f
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 50 deletions.
Expand Up @@ -30,7 +30,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import jenkins.model.Jenkins;
import jenkins.security.QueueItemAuthenticatorConfiguration;

import net.sf.json.JSONObject;
Expand All @@ -41,14 +40,12 @@

import hudson.DescriptorExtensionList;
import hudson.Extension;
import hudson.model.Describable;
import hudson.model.DescriptorVisibilityFilter;
import hudson.model.Job;
import hudson.model.JobProperty;
import hudson.model.JobPropertyDescriptor;
import hudson.model.Queue;
import hudson.model.Descriptor;
import hudson.security.AuthorizationStrategy;

/**
* Specifies how to authorize its builds.
Expand Down Expand Up @@ -197,55 +194,9 @@ public AuthorizeProjectProperty newInstance(StaplerRequest req, JSONObject formD
return null;
}

AuthorizeProjectStrategy strategy = bindJSONWithDescriptor(req, form, "strategy", AuthorizeProjectStrategy.class);
AuthorizeProjectStrategy strategy = AuthorizeProjectUtil.bindJSONWithDescriptor(req, form, "strategy", AuthorizeProjectStrategy.class);

return new AuthorizeProjectProperty(strategy);
}

/**
* Create a new {@link Describable} object from user inputs.
*
* @param req
* @param formData
* @param fieldName
* @param clazz
* @return
* @throws hudson.model.Descriptor.FormException
*/
private <T extends Describable<?>> T bindJSONWithDescriptor(
StaplerRequest req,
JSONObject formData,
String fieldName,
Class<T> clazz
) throws hudson.model.Descriptor.FormException {
formData = formData.getJSONObject(fieldName);
if (formData == null || formData.isNullObject()) {
return null;
}
String staplerClazzName = formData.optString("$class", null);
if (staplerClazzName == null) {
// Fall back on the legacy stapler-class attribute.
staplerClazzName = formData.optString("stapler-class", null);
}
if (staplerClazzName == null) {
throw new FormException("No $class is specified", fieldName);
}
try {
@SuppressWarnings("unchecked")
Class<? extends T> staplerClass = (Class<? extends T>)Jenkins.getInstance().getPluginManager().uberClassLoader.loadClass(staplerClazzName);
Descriptor<?> d = Jenkins.getInstance().getDescriptorOrDie(staplerClass);

@SuppressWarnings("unchecked")
T instance = (T)d.newInstance(req, formData);

return instance;
} catch(ClassNotFoundException e) {
throw new FormException(
String.format("Failed to instantiate %s", staplerClazzName),
e,
fieldName
);
}
}
}
}
@@ -0,0 +1,84 @@
/*
* The MIT License
*
* Copyright (c) 2016 IKEDA Yasuyuki
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package org.jenkinsci.plugins.authorizeproject;

import jenkins.model.Jenkins;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.model.Descriptor.FormException;
import net.sf.json.JSONObject;

import org.kohsuke.stapler.StaplerRequest;

/**
*
*/
/*package*/ class AuthorizeProjectUtil {
/**
* Create a new {@link Describable} object from user inputs.
*
* @param req
* @param formData
* @param fieldName
* @param clazz
* @return
* @throws FormException
*/
public static <T extends Describable<?>> T bindJSONWithDescriptor(
StaplerRequest req,
JSONObject formData,
String fieldName,
Class<T> clazz
) throws FormException {
formData = formData.getJSONObject(fieldName);
if (formData == null || formData.isNullObject()) {
return null;
}
String staplerClazzName = formData.optString("$class", null);
if (staplerClazzName == null) {
// Fall back on the legacy stapler-class attribute.
staplerClazzName = formData.optString("stapler-class", null);
}
if (staplerClazzName == null) {
throw new FormException("No $class is specified", fieldName);
}
try {
@SuppressWarnings("unchecked")
Class<? extends T> staplerClass = (Class<? extends T>)Jenkins.getInstance().getPluginManager().uberClassLoader.loadClass(staplerClazzName);
Descriptor<?> d = Jenkins.getInstance().getDescriptorOrDie(staplerClass);

@SuppressWarnings("unchecked")
T instance = (T)d.newInstance(req, formData);

return instance;
} catch(ClassNotFoundException e) {
throw new FormException(
String.format("Failed to instantiate %s", staplerClazzName),
e,
fieldName
);
}
}
}
Expand Up @@ -5,9 +5,12 @@
import hudson.model.Queue;
import jenkins.security.QueueItemAuthenticator;
import jenkins.security.QueueItemAuthenticatorDescriptor;
import net.sf.json.JSONObject;

import org.acegisecurity.Authentication;
import org.jenkinsci.plugins.authorizeproject.strategy.AnonymousAuthorizationStrategy;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

/**
* A global default authenticator to allow changing the default for all projects.
Expand Down Expand Up @@ -44,5 +47,28 @@ public String getDisplayName() {
public AuthorizeProjectStrategy getDefaultStrategy() {
return new AnonymousAuthorizationStrategy();
}

/**
* Creates new {@link GlobalQueueItemAuthenticator} from inputs.
* This is required to call {@link hudson.model.Descriptor#newInstance(StaplerRequest, JSONObject)}
* of {@link AuthorizeProjectProperty}.
*
* @param req
* @param formData
* @return
* @throws hudson.model.Descriptor.FormException
* @see hudson.model.Descriptor#newInstance(org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject)
*/
@Override
public GlobalQueueItemAuthenticator newInstance(StaplerRequest req, JSONObject formData)
throws FormException
{
if(formData == null || formData.isNullObject()) {
return null;
}
AuthorizeProjectStrategy strategy = AuthorizeProjectUtil.bindJSONWithDescriptor(req, formData, "strategy", AuthorizeProjectStrategy.class);

return new GlobalQueueItemAuthenticator(strategy);
}
}
}
Expand Up @@ -111,9 +111,21 @@ public void testConfigurationWithDescriptorNewInstance() throws Exception {
WebClient wc = j.createWebClient();
j.submit(wc.goTo("configureSecurity").getFormByName("config"));

/*
// as SpecificUsersAuthorizationStrategy is not annotated with @DataBoundConstoctor,
// assertEqualDataBoundBeans is not applicable.
j.assertEqualDataBoundBeans(
auth,
QueueItemAuthenticatorConfiguration.get().getAuthenticators().get(GlobalQueueItemAuthenticator.class)
);
*/
AuthorizeProjectStrategy strategy = QueueItemAuthenticatorConfiguration.get().getAuthenticators().get(GlobalQueueItemAuthenticator.class).getStrategy();
assertEquals(SpecificUsersAuthorizationStrategy.class, strategy.getClass());
assertEquals(
"admin",
((SpecificUsersAuthorizationStrategy)strategy).getUserid()
);
// Don't care about noNeedReauthentication
// (It might be removed for GlobalQueueItemAuthenticator in future)
}
}

0 comments on commit 932d35f

Please sign in to comment.