@Test public void testGetSearchClauseTwoProjects() throws Exception { final CustomFieldParamsImpl customFieldParams = new CustomFieldParamsImpl(); customFieldParams.addValue(Collections.singleton("123")); final Map<String, Object> map = MapBuilder.<String, Object>newBuilder() .add(urlParameterName, customFieldParams) .add( SystemSearchConstants.forProject().getUrlParameter(), CollectionBuilder.list("1", "2")) .toMap(); FieldValuesHolder values = new FieldValuesHolderImpl(map); final AtomicBoolean defaultCalled = new AtomicBoolean(false); final DefaultIndexedInputHelper helper = new DefaultIndexedInputHelper<Version>( indexInfoResolver, operandResolver, fieldFlagOperandRegistry, searchContextVisibilityChecker) { @Override public Clause getClauseForNavigatorValues(final String clauseName, final Set values) { return null; } }; transformer = new VersionCustomFieldSearchInputTransformer( urlParameterName, clauseNames, customField, indexInfoResolver, operandResolver, fieldFlagOperandRegistry, searchContextVisibilityChecker, versionResolver, customFieldInputHelper, versionManager) { @Override protected DefaultIndexedInputHelper getDefaultIndexedInputHelper() { defaultCalled.set(true); return helper; } @Override protected IndexedInputHelper getIndexedInputHelper() { throw new UnsupportedOperationException( "Should not have called through to the special indexed input helper"); } @Override protected String getClauseName(final User searcher, final ClauseNames clauseNames) { return primaryClauseName; } }; replay(); transformer.getSearchClause(theUser, values); assertTrue(defaultCalled.get()); }
public List<GenericValue> findByField( final String entityName, final String fieldName, final Object fieldValue, final String orderBy) { return findByAnd( entityName, new FieldMap(fieldName, fieldValue), CollectionBuilder.list(orderBy)); }
static { DOC_EXAMPLE = new ProjectRoleBean(); long id = 10360; DOC_EXAMPLE.self = Examples.restURI("project/MKY/role/" + id); DOC_EXAMPLE.id = id; DOC_EXAMPLE.name = "Developers"; DOC_EXAMPLE.description = "A project role that represents developers in a project"; DOC_EXAMPLE.actors = CollectionBuilder.list(RoleActorBean.DOC_EXAMPLE); }
/** * SQL Interceptor that detects changes to the database that aren't xsrf protected * * @since v4.1 */ public class XsrfVulnerabilityDetectionSQLInterceptor implements SQLConnectionInterceptor { private static final Logger log = Logger.getLogger(XsrfVulnerabilityDetectionSQLInterceptor.class); private static final String XSRF_VULNERABILITY_DETECTION_SQLINTERCEPTOR_DONE = "XsrfVulnerabilityDetectionSQLInterceptorDone"; @Override public void onConnectionTaken(Connection connection, ConnectionPoolState connectionPoolState) {} @Override public void onConnectionReplaced( Connection connection, ConnectionPoolState connectionPoolState) {} public void beforeExecution( final String sqlString, final List<String> parameterValues, final Statement statement) {} public void afterSuccessfulExecution( final String sqlString, final List<String> parameterValues, final Statement statement, final ResultSet resultSet, final int rowsUpdated) { afterExecutionImpl(sqlString); } public void onException( final String sqlString, final List<String> parameterValues, final Statement statement, final SQLException sqlException) { afterExecutionImpl(sqlString); } private boolean isMutatingSQL(String sql) { String sqlString = sql.toUpperCase(); return sqlString.startsWith("INSERT") || sqlString.startsWith("UPDATE") || sqlString.startsWith("DELETE"); } private void afterExecutionImpl(final String sqlString) { if (JiraSystemProperties.getInstance().isXsrfDiagnostics()) { final String requestURL = MDC.get("jira.request.url"); if (isMutatingSQL(sqlString)) { HttpServletRequest request = ActionContext.getRequest(); if (request != null && request.getAttribute(XSRF_VULNERABILITY_DETECTION_SQLINTERCEPTOR_DONE) == null) { // setting this into the request will make things a lot faster request.setAttribute(XSRF_VULNERABILITY_DETECTION_SQLINTERCEPTOR_DONE, "true"); CallStack callStack = new CallStack(); if (callStack.hasMethodsWeAreInterestedIn() && !callStack.isProtectedAction()) { log.error("XSRF VULNERABILITY DETECTED"); log.error("requestURL: " + requestURL); log.error("sql: " + sqlString); log.error("CallStack:", callStack); } } } } } static final List<String> methodsToIgnore = CollectionBuilder.list( "com.atlassian.sal.jira.lifecycle.JiraLifecycleManager.onJiraStart", "com.atlassian.jira.security.login.LoginStoreImpl.recordLoginAttempt", "com.atlassian.jira.user.DefaultUserHistoryManager.addItemToHistory"); static final List<String> actionWhiteList = new ArrayList<String>(); static { if (JiraSystemProperties.isXsrfDetectionCheckRequired()) { log.setLevel(Level.INFO); } LineIterator iterator = IOUtils.lineIterator( new InputStreamReader( XsrfVulnerabilityDetectionSQLInterceptor.class.getResourceAsStream( "/security/xsrf/xsrf-white-list.txt"))); for (; iterator.hasNext(); ) { String line = ((String) iterator.next()).trim(); if (line.length() > 0 && !line.startsWith("#")) { actionWhiteList.add(line); } } } private static class CallStack extends RuntimeException { public boolean hasMethodsWeAreInterestedIn() { for (StackTraceElement element : getStackTrace()) { String method = element.getClassName() + "." + element.getMethodName(); if (methodsToIgnore.contains(method)) { return false; } } return true; } public boolean isProtectedAction() { boolean isAnnotated = false; StackTraceElement elements[] = getStackTrace(); for (int i = 0; i < elements.length; i++) { StackTraceElement element = elements[i]; if (isActionSupport_execute(element)) { StackTraceElement action = findActionStackTraceElement(elements, i); // in OSGI land its possible that we cant see the method in play so // if we cant access it then we cant check it if (action != null) { final String className = action.getClassName(); try { final Class<?> aClass = Class.forName(action.getClassName()); final Method method = getMethod(aClass, action.getMethodName()); // in OGSI land its possible that we cant see the method in play so // if we cant access it then we cant check it if (method != null) { isAnnotated = method.isAnnotationPresent(RequiresXsrfCheck.class); final String actionMethodName = action.getMethodName(); final String actionName = className + "." + actionMethodName; log.info("ACTION: " + actionName + " PROTECTED: " + isAnnotated); final boolean isActionInWhiteList = isActionInWhiteList(aClass); if (!isAnnotated) { if (isActionInWhiteList) { // its mutated something and its in the white list of good actions. Something // is rotten in Denmark! throw new RuntimeException("XSRF white list failure"); } } else { if (!isActionInWhiteList) { // its a XSRF annotated method but its not in the white list. We have missed // putting it in the white list throw new RuntimeException( "ACTION: " + actionName + " has XSRF annotated but its not in the whitelist"); } } } } catch (ClassNotFoundException e) { // ignored } break; // out of the loop } } } return isAnnotated; } private StackTraceElement findActionStackTraceElement( final StackTraceElement[] elements, final int i) { StackTraceElement foundElement = null; // if the next method is ActionSupport.invokeCommand we need to search up the stack trace // until we find a doXXXX method StackTraceElement element = elements[i - 1]; if (isActionSupport_invokeCommand(element)) { for (int j = i; j >= 0; j--) { element = elements[j]; if (isActionDoMethod(element)) { foundElement = element; break; } } } return foundElement; } private boolean isActionSupport_invokeCommand(final StackTraceElement element) { return ActionSupport.class.getName().equals(element.getClassName()) && "invokeCommand".equals(element.getMethodName()); } private boolean isActionSupport_execute(final StackTraceElement element) { return ActionSupport.class.getName().equals(element.getClassName()) && "execute".equals(element.getMethodName()); } private boolean isActionDoMethod(final StackTraceElement element) { boolean isok = ActionSupport.class.isAssignableFrom(getClassOfElement(element)); isok = isok && element.getMethodName().startsWith("do"); return isok; } private Class getClassOfElement(final StackTraceElement element) { try { return Class.forName(element.getClassName()); } catch (ClassNotFoundException e) { return e.getClass(); } } private boolean isActionInWhiteList(final Class<?> aClass) { // complex name first boolean isActionInWhiteList = actionWhiteList.contains(aClass.getName()); if (!isActionInWhiteList) { // simple name last isActionInWhiteList = actionWhiteList.contains(aClass.getSimpleName()); } return isActionInWhiteList; } /** * Finds the declared method on the provided class. If the method is not declared on the class, * we search recursively up the inheritance hierarchy, stopping at {@link * com.atlassian.jira.web.action.JiraWebActionSupport} or {@link Object}. * * @param clazz the class * @param methodName the method name to find * @return the method on the class; null if it could not be found. */ private Method getMethod(final Class<?> clazz, final String methodName) { try { return clazz.getDeclaredMethod(methodName); } catch (NoSuchMethodException e) { if (clazz.equals(JiraWebActionSupport.class) || clazz.equals(Object.class)) { return null; } else { return getMethod(clazz.getSuperclass(), methodName); } } } } }
@Test public void testExecuteBuildNumberMissing() throws Exception { expect(mockBarrier.await(20, TimeUnit.SECONDS)).andReturn(true); expect(mockBeanFactory.getInstance(currentUser)).andReturn(new MockI18nHelper()).anyTimes(); // called during validation! expect(mockPermissionManager.hasPermission(Permissions.SYSTEM_ADMIN, currentUser)) .andReturn(true); // This is called during the first parse of the XML file. At this stage nothing should have // been created yet! final MockGenericValue mockGv = new MockGenericValue("someentity"); expect(mockOfBizDelegator.makeValue(EasyMock.<String>anyObject())).andReturn(mockGv).anyTimes(); expect(mockAttachmentPathManager.getDefaultAttachmentPath()) .andReturn(directories.get(0).getAbsolutePath()) .anyTimes(); expect(mockIndexPathManager.getDefaultIndexRootPath()) .andReturn(directories.get(1).getAbsolutePath()) .anyTimes(); expect( mockLicenseStringFactory.create( EasyMock.<String>anyObject(), EasyMock.<String>anyObject())) .andStubReturn(""); // after the first parse check the build number. expect(mockBuildUtilsInfo.getCurrentBuildNumber()).andStubReturn("1"); expect(mockBuildUtilsInfo.getMinimumUpgradableBuildNumber()).andStubReturn("0"); // after the first parse we also verify the license is good. expect( mockJiraLicenseService.validate( EasyMock.<I18nHelper>anyObject(), EasyMock.<String>anyObject())) .andStubReturn(mockValidationResult); expect(mockValidationResult.getLicenseVersion()).andStubReturn(2); expect(mockValidationResult.getErrorCollection()).andStubReturn(new SimpleErrorCollection()); // this gets called during shutdownAndFlushAsyncServices. After parse and before the import. // This shuts down // the scheduler expect(mockScheduler.isShutdown()).andReturn(false); mockScheduler.shutdown(); mockMailQueue.sendBuffer(); expect(mockTaskManager.shutdownAndWait(5)).andReturn(true); // Expect AO to be cleared. backup.clear(); // Once the import is running one of the first things to do is to clear out the old database // values. expect(mockOfBizDelegator.getModelReader()).andReturn(mockModelReader); expect(mockModelReader.getEntityNames()) .andReturn(CollectionBuilder.<String>list("Issue", "User")); expect(mockModelReader.getModelEntity("Issue")).andReturn(new ModelEntity()); expect(mockOfBizDelegator.removeByAnd("Issue", Collections.<String, Object>emptyMap())) .andReturn(10); expect(mockModelReader.getModelEntity("User")).andReturn(new ModelEntity()); expect(mockOfBizDelegator.removeByAnd("User", Collections.<String, Object>emptyMap())) .andReturn(5); // then we go through and create all our GVs (already mocked out during the first parse above) // once everything's been imported need to refresh the ofbiz sequencer and check for data // consistency. mockOfBizDelegator.refreshSequencer(); mockConsistencyChecker.checkDataConsistency(); // after the consistency check lets do the upgrade expect(mockUpgradeManager.doUpgradeIfNeededAndAllowed(null)) .andReturn(Collections.<String>emptyList()); // now do a reindex mockIndexManager.deactivate(); expect(mockIndexManager.size()).andReturn(5); expect(mockIndexManager.activate((Context) notNull())).andReturn(1L); // raise the JiraStartedEvent mockPluginEventManager.broadcast(EasyMock.<JiraStartedEvent>anyObject()); // finally we can restart the scheduler! expect( mockScheduler.scheduleJob( EasyMock.<JobDetail>anyObject(), EasyMock.<Trigger>anyObject())) .andReturn(new Date()) .anyTimes(); mockScheduler.start(); final String filePath = getDataFilePath("jira-export-test-no-build-number.xml"); final DataImportParams params = new DataImportParams.Builder(filePath).build(); // Finally everything's mocked out. Run the import! executeTest(params, true, DataImportService.ImportError.NONE); // create() should have been called on our GVs assertTrue(mockGv.isCreated()); // the world should have been rebuilt! assertTrue(((MockDataImportDependencies) mockDependencies).globalRefreshCalled); }
static { try { IssueBean issue = new IssueBean("EX-1", new URI("http://example.com:8080/jira/rest/api/2.0/issue/EX-1")); issue.fields = new HashMap<String, FieldBean>() { { put(UPDATED, FieldBean.create(UPDATED, JiraDataTypes.getType(UPDATED), new Date(1))); put( DESCRIPTION, FieldBean.create( DESCRIPTION, JiraDataTypes.getType(DESCRIPTION), "example bug report")); put( PROJECT, FieldBean.create( PROJECT, JiraDataTypes.getType(PROJECT), ProjectBean.SHORT_DOC_EXAMPLE_1)); put( TIMETRACKING, FieldBean.create( TIMETRACKING, JiraDataTypes.getType(TIMETRACKING), new TimeTrackingBean(600L, 200L, 400L))); } }; issue.addField( IssueFieldConstants.ATTACHMENT, FieldBean.create( IssueFieldConstants.ATTACHMENT, JiraDataTypes.getType(IssueFieldConstants.ATTACHMENT), CollectionBuilder.list(AttachmentBean.DOC_EXAMPLE))); issue.addField( IssueFieldConstants.COMMENT, FieldBean.create( IssueFieldConstants.COMMENT, JiraDataTypes.getType(IssueFieldConstants.COMMENT), CollectionBuilder.list(CommentBean.DOC_EXAMPLE))); issue.addField( IssueFieldConstants.WORKLOG, FieldBean.create( IssueFieldConstants.WORKLOG, JiraDataTypes.getType(IssueFieldConstants.WORKLOG), CollectionBuilder.list(WorklogBean.DOC_EXAMPLE))); issue.addField( "sub-tasks", FieldBean.create( "sub-tasks", JiraDataTypes.getType(IssueFieldConstants.ISSUE_LINKS), CollectionBuilder.list( new IssueLinkBean( "EX-2", new URI("http://example.com:8080/jira/rest/api/2.0/issue/EX-2"), LinkedIssueTypeBean.instance() .name("Sub-task") .direction(LinkedIssueTypeBean.Direction.OUTBOUND) .build())))); issue.addField( "links", FieldBean.create( "links", JiraDataTypes.getType(IssueFieldConstants.ISSUE_LINKS), CollectionBuilder.list( new IssueLinkBean( "PRJ-2", new URI("http://example.com:8080/jira/rest/api/2.0/issue/PRJ-2"), LinkedIssueTypeBean.instance() .name("Dependent") .description("depends on") .direction(LinkedIssueTypeBean.Direction.OUTBOUND) .build()), new IssueLinkBean( "PRJ-3", new URI("http://example.com:8080/jira/rest/api/2.0/issue/PRJ-3"), LinkedIssueTypeBean.instance() .name("Dependent") .description("is depended by") .direction(LinkedIssueTypeBean.Direction.INBOUND) .build())))); issue.addField( IssueFieldConstants.WATCHERS, FieldBean.create( IssueFieldConstants.WATCHERS, JiraDataTypes.getType(IssueFieldConstants.WATCHERS), WatchersBean.DOC_EXAMPLE)); // set this as the documentation example DOC_EXAMPLE = issue; } catch (URISyntaxException e) { throw new RuntimeException(e); // never happens } }