Skip to content

Commit

Permalink
upstream: b=main,r=314d894c671a662a70e9c0f93c105a2b90765ca0,t=2022-09…
Browse files Browse the repository at this point in the history
…-30-1242-43906
  • Loading branch information
sonatype-zion committed Sep 30, 2022
1 parent 13df2af commit baac7d7
Show file tree
Hide file tree
Showing 75 changed files with 1,887 additions and 251 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public CleanupPolicyResource(
this.cleanupPolicyStorage = checkNotNull(cleanupPolicyStorage);
this.formats = checkNotNull(formats);
this.formatNames = formats.stream().map(Format::getValue).collect(Collectors.toList());
this.formatNames.add("*");
this.formatNames.add(ALL_FORMATS);
this.cleanupFormatConfigurationMap = checkNotNull(cleanupFormatConfigurationMap);
this.defaultCleanupFormatConfiguration = checkNotNull(cleanupFormatConfigurationMap.get("default"));
this.cleanupPreviewHelper = checkNotNull(cleanupPreviewHelper);
Expand Down Expand Up @@ -175,12 +175,18 @@ public CleanupPolicyXO edit(
throw new ValidationErrorsException("format", "specified format " + cleanupPolicyXO.getFormat() + " is not valid.");
}

int inUseCount = (int) repositoryManager.browseForCleanupPolicy(name).count();
if (!cleanupPolicyXO.getFormat().equals(ALL_FORMATS) &&
!cleanupPolicy.getFormat().equals(cleanupPolicyXO.getFormat()) &&
inUseCount > 0) {
throw new ValidationErrorsException("format", "You cannot change the format of a policy that is in use.");
}

cleanupPolicy.setNotes(cleanupPolicyXO.getNotes());
cleanupPolicy.setFormat(cleanupPolicyXO.getFormat());
cleanupPolicy.setCriteria(toCriteriaMap(cleanupPolicyXO));

return CleanupPolicyXO.fromCleanupPolicy(cleanupPolicyStorage.update(cleanupPolicy),
(int) repositoryManager.browseForCleanupPolicy(name).count());
return CleanupPolicyXO.fromCleanupPolicy(cleanupPolicyStorage.update(cleanupPolicy), inUseCount);
}

@DELETE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.sonatype.goodies.common.ComponentSupport;
import org.sonatype.nexus.selector.CselSelector;
import org.sonatype.nexus.selector.JexlSelector;
import org.sonatype.nexus.selector.SelectorConfiguration;
import org.sonatype.nexus.selector.SelectorEvaluationException;
import org.sonatype.nexus.selector.SelectorFilterBuilder;
Expand Down Expand Up @@ -52,13 +53,16 @@ public String buildFilter(
final List<SelectorConfiguration> selectors,
final Map<String, Object> filterParameters)
{
if (selectors.isEmpty()) {
List<SelectorConfiguration> activeSelectors =
selectors.stream().filter(s -> !JexlSelector.TYPE.equals(s.getType())).collect(Collectors.toList());

if (activeSelectors.isEmpty()) {
return null;
}

StringBuilder filterBuilder = new StringBuilder();

if (selectors.size() > 1) {
if (activeSelectors.size() > 1) {
filterBuilder.append('(');
}

Expand All @@ -68,9 +72,9 @@ public String buildFilter(
.parameterPrefix("#{" + FILTER_PARAMS + ".")
.parameterSuffix("}");

appendSelectors(filterBuilder, sqlBuilder, selectors, filterParameters);
appendSelectors(filterBuilder, sqlBuilder, activeSelectors, filterParameters);

if (selectors.size() > 1) {
if (activeSelectors.size() > 1) {
filterBuilder.append(')');
}

Expand All @@ -86,27 +90,25 @@ public void appendSelectors(
int selectorCount = 0;

for (SelectorConfiguration selector : selectors) {
if (CselSelector.TYPE.equals(selector.getType())) {
try {
sqlBuilder.parameterNamePrefix("s" + selectorCount + "p");
try {
sqlBuilder.parameterNamePrefix("s" + selectorCount + "p");

selectorManager.toSql(selector, sqlBuilder);
selectorManager.toSql(selector, sqlBuilder);

if (selectorCount > 0) {
filterBuilder.append(" or ");
}
if (selectorCount > 0) {
filterBuilder.append(" or ");
}

filterBuilder.append('(').append(sqlBuilder.getQueryString()).append(')');
filterParameters.putAll(sqlBuilder.getQueryParameters());
filterBuilder.append('(').append(sqlBuilder.getQueryString()).append(')');
filterParameters.putAll(sqlBuilder.getQueryParameters());

selectorCount++;
}
catch (SelectorEvaluationException e) {
log.warn("Problem evaluating selector {} as SQL", selector.getName(), e);
}
finally {
sqlBuilder.clearQueryString();
}
selectorCount++;
}
catch (SelectorEvaluationException e) {
log.warn("Problem evaluating selector {} as SQL", selector.getName(), log.isDebugEnabled() ? e : null);
}
finally {
sqlBuilder.clearQueryString();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,21 @@ public void testJexl() {
Map<String, Object> filterParameters = new HashMap<>();
String filter = underTest.buildFilter("raw", "request_path", ImmutableList.of(selector), filterParameters);

assertThat(filter, is(""));
assertThat(filter, nullValue());
assertThat(filterParameters.size(), is(0));
}

// Jexl expressions are not put into the filter, they need to be checked in code
@Test
public void testMultipleJexl() {
SelectorConfiguration selector1 = createSelectorConfiguration(JexlSelector.TYPE, "selector1", "path.size() > 5");
SelectorConfiguration selector2 = createSelectorConfiguration(JexlSelector.TYPE, "selector2", "format == 'raw'");

Map<String, Object> filterParameters = new HashMap<>();
String filter =
underTest.buildFilter("raw", "request_path", ImmutableList.of(selector1, selector2), filterParameters);

assertThat(filter, nullValue());
assertThat(filterParameters.size(), is(0));
}

Expand All @@ -156,8 +170,7 @@ public void testMixedTypes() {
String filter =
underTest.buildFilter("raw", "request_path", ImmutableList.of(selector1, selector2), filterParameters);

// appends extra parenthesis because it expected more than one expression
assertThat(filter, is("((request_path = #{filterParams.s0p0}))"));
assertThat(filter, is("(request_path = #{filterParams.s0p0})"));
assertThat(filterParameters.size(), is(1));
assertThat(filterParameters.get("s0p0"), is("/baz/"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Ext.define('NX.controller.Features', {
path = clonedFeature.mode + '/' + path;
clonedFeature.path = '/' + path;

model = me.getStore('Feature').getById(clonedFeature.path);
model = me.getStore('Feature').getById(clonedFeature.id);
if (model) {
me.getStore('Feature').remove(model);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ Ext.define('NX.controller.Menu', {
if (me.bookmarkingEnabled) {
me.bookmark(featureMenuModel);
}
me.selectFeature(me.getStore('Feature').getById(featureMenuModel.get('path')));
me.selectFeature(me.getStore('Feature').getById(featureMenuModel.get('id')));
me.populateFeatureGroupStore(featureMenuModel);
}
},
Expand Down Expand Up @@ -287,7 +287,7 @@ Ext.define('NX.controller.Menu', {
// add all children of the record to the group store, but do not include the node for the current record
record.eachChild(function (node) {
node.cascadeBy(function (child) {
features.push(featureStore.getById(child.get('path')));
features.push(featureStore.getById(child.get('id')));
});
});

Expand Down Expand Up @@ -571,6 +571,7 @@ Ext.define('NX.controller.Menu', {
expanded: nodeExpandMap[feature.path] === undefined ? feature.expanded : nodeExpandMap[feature.path],
helpKeyword: feature.helpKeyword,
iconName: feature.iconName,
id: feature.id,
mode: feature.mode,
path: feature.path,
text: feature.text,
Expand Down Expand Up @@ -629,6 +630,7 @@ Ext.define('NX.controller.Menu', {
*/
createNotAvailableFeature: function (feature) {
return this.getFeatureModel().create({
id: feature.get('id'),
text: feature.get('text'),
path: feature.get('path'),
description: feature.get('description'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
Ext.define('NX.model.Feature', {
extend: 'Ext.data.Model',

idProperty: 'path',
idProperty: 'id',

// FIXME: define types so its clear what this data is! Also consider comments for further clarity.

fields: [
{ name: 'id' },
{ name: 'path' },
{ name: 'text' },
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ Ext.define('NX.model.FeatureMenu', {

// FIXME: define types so its clear what this data is! Also consider comments for further clarity.

// FIXME: Set ID for module... unsure what this should be in a tree though

fields: [
{ name: 'id' },
{ name: 'path' },
{
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,12 @@ public interface RoutingRuleHelper
* Ensures that the user has the necessary permissions to Read routing rules
*/
void ensureUserHasPermissionToRead();

/**
* Determine if the repository has a routing rule configured.
*
* @param repository the repository for the context of this request
* @return true if the repository has a routing rule configured
*/
boolean hasRoutingRule(final Repository repository);
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,14 @@ private void track(final Repository repository) {
// configure security
securityContributor.add(repository);

log.debug("Tracking: {}", repository);
repositories.put(repository.getName().toLowerCase(), repository);
Repository value = repositories.putIfAbsent(repository.getName().toLowerCase(), repository);

if (value == null) {
log.debug("Tracking: {}", repository);
}
else {
log.debug("An existing repository with the same name is already tracked {}", value);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ public Map<EntityId, List<Repository>> calculateAssignedRepositories() {
.collect(groupingBy(routingRuleCache::getRoutingRuleId, toList()));
}

@Override
public boolean hasRoutingRule(final Repository repository) {
RoutingRule routingRule = routingRuleCache.getRoutingRule(repository);

return routingRule != null;
}

@Override
public void ensureUserHasPermissionToRead() {
List<Permission> permissions = getRepositoryAddPermissions();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2008-present Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
import React from 'react';
import {NxReadOnly} from '@sonatype/react-shared-components';
import {isNil, isEmpty} from 'ramda';

/**
* @param {string} label
* @param value [required]
* @return {ReactNode}
*/
export default function ReadOnlyField({label, value}) {
const valid = !isNil(value) && !isEmpty(value);

return (
valid && (
<>
<NxReadOnly.Label>{label}</NxReadOnly.Label>
<NxReadOnly.Data>{value}</NxReadOnly.Data>
</>
)
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2008-present Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
import React from 'react';
import {render, screen} from '@testing-library/react';
import ReadOnlyField from './ReadOnlyField';

describe('readOnlyRenderField', () => {
const label = 'Best Label';
const data = '[email protected]';

const selectors = {
label: () => screen.getByText(label),
data: () => screen.getByText(data),
queryLabel: () => screen.queryByText(label),
queryData: () => screen.queryByText(data),
};

const renderComponent = () =>
render(<ReadOnlyField label={label} value={data} />);

it('returns an element', () => {
renderComponent();

expect(selectors.label()).toBeInTheDocument();
expect(selectors.data()).toBeInTheDocument();
});

it('does not return an element if the data is empty, null or undefined', async () => {
const {rerender} = renderComponent();

rerender(<ReadOnlyField label={label} />);

expect(selectors.queryLabel()).not.toBeInTheDocument();
expect(selectors.queryData()).not.toBeInTheDocument();

rerender(<ReadOnlyField label={label} value="" />);

expect(selectors.queryLabel()).not.toBeInTheDocument();
expect(selectors.queryData()).not.toBeInTheDocument();

rerender(<ReadOnlyField label={label} value={null} />);

expect(selectors.queryLabel()).not.toBeInTheDocument();
expect(selectors.queryData()).not.toBeInTheDocument();

rerender(<ReadOnlyField label={label} value={undefined} />);

expect(selectors.queryLabel()).not.toBeInTheDocument();
expect(selectors.queryData()).not.toBeInTheDocument();
});
});
1 change: 1 addition & 0 deletions components/nexus-ui-plugin/src/frontend/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export { default as FieldWrapper } from './components/widgets/FieldWrapper/Field
export { default as HelpTile } from './components/widgets/HelpTile/HelpTile';
export { default as Information } from './components/widgets/Information/Information';
export { default as Select } from './components/widgets/Select/Select';
export { default as ReadOnlyField } from './components/widgets/ReadOnlyField/ReadOnlyField';
export {
default as SslCertificateDetailsModal
} from './components/widgets/SslCertificateDetailsModal/SslCertificateDetailsModal';
Expand Down
Loading

0 comments on commit baac7d7

Please sign in to comment.