Skip to content

Commit 40f24db

Browse files
tulinkryVladimir Kotal
authored andcommitted
logging non-existent projects/groups in forProjects/forGroups (#1582)
fixes #1572
1 parent ca94d70 commit 40f24db

File tree

5 files changed

+267
-133
lines changed

5 files changed

+267
-133
lines changed

src/org/opensolaris/opengrok/authorization/AuthorizationEntity.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@
2828
import java.util.TreeMap;
2929
import java.util.TreeSet;
3030
import java.util.function.Predicate;
31+
import java.util.logging.Level;
32+
import java.util.logging.Logger;
3133
import java.util.stream.Collectors;
3234
import org.opensolaris.opengrok.configuration.Group;
3335
import org.opensolaris.opengrok.configuration.Nameable;
36+
import org.opensolaris.opengrok.configuration.Project;
37+
import org.opensolaris.opengrok.logger.LoggerFactory;
3438

3539
/**
3640
* This class covers authorization entities used in opengrok.
@@ -57,6 +61,8 @@
5761
*/
5862
public abstract class AuthorizationEntity implements Nameable, Serializable, Cloneable {
5963

64+
private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationEntity.class);
65+
6066
/**
6167
* Predicate specialized for the the plugin decisions. The caller should
6268
* implement the <code>decision</code> method. Returning true if the plugin
@@ -369,25 +375,49 @@ public void setForGroups(String[] groups) {
369375
* the group</li>
370376
* <li>add to the {@link #forProjects()} all projects and repositories which
371377
* are in the descendant groups or in the group itself</li>
378+
* <li>issue a warning for non-existent groups</li>
379+
* <li>issue a warning for non-existent projects</li>
372380
* </ul>
373381
*/
374-
protected void discoverGroups() {
382+
protected void processTargetGroupsAndProjects() {
375383
Set<String> groups = new TreeSet<>();
384+
376385
for (String x : forGroups()) {
377386
/**
378387
* Full group discovery takes place here. All projects/repositories
379388
* in the group are added into "forProjects" and all subgroups
380389
* (including projects/repositories) and parent groups (excluding
381390
* the projects/repositories) are added into "forGroups".
391+
*
392+
* If the group does not exist then a warning is issued.
382393
*/
383394
Group g;
384395
if ((g = Group.getByName(x)) != null) {
385396
forProjects().addAll(g.getAllProjects().stream().map((t) -> t.getName()).collect(Collectors.toSet()));
386397
groups.addAll(g.getRelatedGroups().stream().map((t) -> t.getName()).collect(Collectors.toSet()));
387398
groups.add(x);
399+
} else {
400+
LOGGER.log(Level.WARNING, "Configured group \"{0}\" in forGroups section"
401+
+ " for name \"{1}\" does not exist",
402+
new Object[]{x, getName()});
388403
}
389404
}
390405
setForGroups(groups);
406+
407+
forProjects().removeIf((t) -> {
408+
/**
409+
* Check the existence of the projects and issue a warning if there
410+
* is no such project.
411+
*/
412+
Project p;
413+
if ((p = Project.getByName(t)) == null) {
414+
LOGGER.log(Level.WARNING, "Configured project \"{0}\" in forProjects"
415+
+ " section for name \"{1}\" does not exist",
416+
new Object[]{t, getName()});
417+
return true;
418+
}
419+
return false;
420+
});
391421
}
392422

393423
/**

src/org/opensolaris/opengrok/authorization/AuthorizationPlugin.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ public AuthorizationPlugin(AuthControlFlag flag, String name, IAuthorizationPlug
9494
*/
9595
@Override
9696
public synchronized void load(Map<String, Object> parameters) {
97+
// fill properly the "forGroups" and "forProjects" fields
98+
processTargetGroupsAndProjects();
99+
97100
if (!hasPlugin()) {
98101
LOGGER.log(Level.SEVERE, "Configured plugin \"{0}\" has not been loaded into JVM (missing file?). "
99102
+ "This can cause the authorization to fail always.",
@@ -112,9 +115,6 @@ public synchronized void load(Map<String, Object> parameters) {
112115
s.putAll(parameters);
113116
s.putAll(getSetup());
114117

115-
// fill properly the "forGroups" and "forProjects" fields
116-
discoverGroups();
117-
118118
try {
119119
plugin.load(s);
120120
setWorking();

src/org/opensolaris/opengrok/authorization/AuthorizationStack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public void load(Map<String, Object> parameters) {
134134
getName()});
135135

136136
// fill properly the "forGroups" and "forProjects" fields
137-
discoverGroups();
137+
processTargetGroupsAndProjects();
138138

139139
setWorking();
140140

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* The contents of this file are subject to the terms of the
5+
* Common Development and Distribution License (the "License").
6+
* You may not use this file except in compliance with the License.
7+
*
8+
* See LICENSE.txt included in this distribution for the specific
9+
* language governing permissions and limitations under the License.
10+
*
11+
* When distributing Covered Code, include this CDDL HEADER in each
12+
* file and include the License file at LICENSE.txt.
13+
* If applicable, add the following below this CDDL HEADER, with the
14+
* fields enclosed by brackets "[]" replaced with your own identifying
15+
* information: Portions Copyright [yyyy] [name of copyright owner]
16+
*
17+
* CDDL HEADER END
18+
*/
19+
20+
/*
21+
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
22+
*/
23+
package org.opensolaris.opengrok.authorization;
24+
25+
import java.util.ArrayList;
26+
import java.util.Arrays;
27+
import java.util.Collection;
28+
import java.util.List;
29+
import java.util.Map;
30+
import java.util.Set;
31+
import java.util.TreeMap;
32+
import java.util.TreeSet;
33+
import java.util.function.Function;
34+
import org.junit.After;
35+
import org.junit.Before;
36+
import org.junit.Test;
37+
import org.junit.runner.RunWith;
38+
import org.junit.runners.Parameterized;
39+
import org.opensolaris.opengrok.configuration.Group;
40+
import org.opensolaris.opengrok.configuration.Project;
41+
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
42+
43+
import static org.junit.Assert.assertEquals;
44+
45+
/**
46+
*
47+
* @author Krystof Tulinger
48+
*/
49+
@RunWith(Parameterized.class)
50+
public class AuthorizationEntityTest {
51+
52+
private Set<Group> envGroups;
53+
private Map<String, Project> envProjects;
54+
55+
private final Function<Void, AuthorizationEntity> authEntityFactory;
56+
57+
private static final Function<Void, AuthorizationEntity> PLUGIN_FACTORY = new Function<Void, AuthorizationEntity>() {
58+
@Override
59+
public AuthorizationEntity apply(Void t) {
60+
return new AuthorizationPlugin(AuthControlFlag.REQUIRED, "");
61+
}
62+
};
63+
64+
private static final Function<Void, AuthorizationEntity> STACK_FACTORY = new Function<Void, AuthorizationEntity>() {
65+
@Override
66+
public AuthorizationEntity apply(Void t) {
67+
return new AuthorizationStack(AuthControlFlag.REQUIRED, "");
68+
}
69+
};
70+
71+
@Parameterized.Parameters
72+
public static Collection<Function<Void, AuthorizationEntity>> parameters() {
73+
List<Function<Void, AuthorizationEntity>> l = new ArrayList<>();
74+
l.add(PLUGIN_FACTORY);
75+
l.add(STACK_FACTORY);
76+
return l;
77+
}
78+
79+
public AuthorizationEntityTest(Function<Void, AuthorizationEntity> authEntityFactory) {
80+
this.authEntityFactory = authEntityFactory;
81+
}
82+
83+
@Before
84+
public void setUp() {
85+
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
86+
envGroups = env.getGroups();
87+
envProjects = env.getProjects();
88+
env.setGroups(new TreeSet<>());
89+
env.setProjects(new TreeMap<>());
90+
}
91+
92+
@After
93+
public void tearDown() {
94+
RuntimeEnvironment.getInstance().setGroups(envGroups);
95+
RuntimeEnvironment.getInstance().setProjects(envProjects);
96+
}
97+
98+
@Test
99+
public void testForGroupsAndForProjectsDiscovery() {
100+
Group g1, g2, g3;
101+
AuthorizationEntity authEntity;
102+
103+
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
104+
105+
env.getProjects().put("project 1", new Project("project 1"));
106+
env.getProjects().put("project 2", new Project("project 2"));
107+
env.getProjects().put("project 3", new Project("project 3"));
108+
env.getProjects().put("project 4", new Project("project 4"));
109+
env.getProjects().put("project 5", new Project("project 5"));
110+
env.getProjects().put("project 6", new Project("project 6"));
111+
env.getProjects().put("project 7", new Project("project 7"));
112+
env.getProjects().put("project 8", new Project("project 8"));
113+
env.getProjects().put("project 9", new Project("project 9"));
114+
115+
/**
116+
* Structure<br>
117+
* <pre>
118+
* G1 + P1
119+
* + P2
120+
* + P3
121+
* + G2
122+
* + P4
123+
* + P5
124+
* + P6
125+
* + P7
126+
* G3 + P8
127+
* + P9
128+
* </pre>
129+
*/
130+
g1 = new Group();
131+
g1.setName("group 1");
132+
g1.addProject(env.getProjects().get("project 1"));
133+
g1.addProject(env.getProjects().get("project 2"));
134+
g1.addProject(env.getProjects().get("project 3"));
135+
env.getGroups().add(g1);
136+
g2 = new Group();
137+
g2.setName("group 2");
138+
g2.addProject(env.getProjects().get("project 4"));
139+
g2.addProject(env.getProjects().get("project 5"));
140+
g2.addProject(env.getProjects().get("project 6"));
141+
g2.addProject(env.getProjects().get("project 7"));
142+
g1.addGroup(g2);
143+
env.getGroups().add(g2);
144+
g3 = new Group();
145+
g3.setName("group 3");
146+
g3.addProject(env.getProjects().get("project 8"));
147+
g3.addProject(env.getProjects().get("project 9"));
148+
env.getGroups().add(g3);
149+
150+
// add g1 and all descendants their projects
151+
authEntity = authEntityFactory.apply(null);
152+
authEntity.setForGroups(new TreeSet<>());
153+
authEntity.setForGroups("group 1");
154+
authEntity.load(new TreeMap<>());
155+
156+
assertEquals(new TreeSet<>(Arrays.asList(new String[]{"group 1", "group 2"})), authEntity.forGroups());
157+
assertEquals(new TreeSet<>(Arrays.asList(new String[]{"project 1", "project 2", "project 3",
158+
"project 4", "project 5", "project 6", "project 7"})), authEntity.forProjects());
159+
160+
// add group2, its parent g1 and g2 projects
161+
authEntity = authEntityFactory.apply(null);
162+
authEntity.setForGroups(new TreeSet<>());
163+
authEntity.setForGroups("group 2");
164+
authEntity.load(new TreeMap<>());
165+
166+
assertEquals(new TreeSet<>(Arrays.asList(new String[]{"group 1", "group 2"})), authEntity.forGroups());
167+
assertEquals(new TreeSet<>(Arrays.asList(new String[]{"project 4", "project 5", "project 6", "project 7"})), authEntity.forProjects());
168+
169+
// add only g3 and its projects
170+
authEntity = authEntityFactory.apply(null);
171+
authEntity.setForGroups(new TreeSet<>());
172+
authEntity.setForGroups("group 3");
173+
authEntity.load(new TreeMap<>());
174+
175+
assertEquals(new TreeSet<>(Arrays.asList(new String[]{"group 3"})), authEntity.forGroups());
176+
assertEquals(new TreeSet<>(Arrays.asList(new String[]{"project 8", "project 9"})), authEntity.forProjects());
177+
}
178+
179+
/**
180+
* Listed projects don't exist.
181+
*/
182+
@Test
183+
public void testForGroupsAndForProjectsDiscoveryInvalidProject() {
184+
AuthorizationEntity authEntity = authEntityFactory.apply(null);
185+
186+
authEntity.setForProjects(new TreeSet<>(Arrays.asList(new String[]{"project 1", "project 2", "project 3",
187+
"project 4", "project 5", "project 6", "project 7"})));
188+
189+
authEntity.load(new TreeMap<>());
190+
191+
assertEquals(new TreeSet<>(), authEntity.forGroups());
192+
assertEquals(new TreeSet<>(), authEntity.forProjects());
193+
}
194+
195+
/**
196+
* Listed groups don't exist.
197+
*/
198+
@Test
199+
public void testForGroupsAndForProjectsDiscoveryInvalidGroup() {
200+
AuthorizationEntity authEntity = authEntityFactory.apply(null);
201+
202+
authEntity.setForGroups(new TreeSet<>(Arrays.asList(new String[]{"group 1", "group 2"})));
203+
204+
authEntity.load(new TreeMap<>());
205+
206+
assertEquals(new TreeSet<>(), authEntity.forGroups());
207+
assertEquals(new TreeSet<>(), authEntity.forProjects());
208+
}
209+
210+
/**
211+
* Listed projects in the group don't exist.
212+
*/
213+
@Test
214+
public void testForGroupsAndForProjectsDiscoveryInvalidProjectInGroup() {
215+
AuthorizationEntity authEntity = authEntityFactory.apply(null);
216+
217+
authEntity.setForGroups(new TreeSet<>(Arrays.asList(new String[]{"group 1", "group 2"})));
218+
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
219+
220+
Group g1 = new Group();
221+
g1.setName("group 1");
222+
g1.addProject(new Project("project 1"));
223+
g1.addProject(new Project("project 2"));
224+
g1.addProject(new Project("project 3"));
225+
env.getGroups().add(g1);
226+
227+
authEntity.load(new TreeMap<>());
228+
229+
assertEquals(new TreeSet<>(Arrays.asList(new String[]{"group 1"})), authEntity.forGroups());
230+
assertEquals(new TreeSet<>(), authEntity.forProjects());
231+
}
232+
}

0 commit comments

Comments
 (0)