Skip to content

Commit 406a8df

Browse files
tulinkryVladimir Kotal
authored andcommitted
Authorization framework configuration in configuration.xml (#1465)
1 parent ac2f5c2 commit 406a8df

File tree

5 files changed

+88
-58
lines changed

5 files changed

+88
-58
lines changed

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

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
public final class AuthorizationFramework {
5454

5555
private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationFramework.class);
56-
private final File directory;
56+
private File pluginDirectory;
5757
private AuthorizationPluginClassLoader loader;
5858

5959
private volatile static AuthorizationFramework instance = new AuthorizationFramework();
@@ -70,6 +70,31 @@ public static AuthorizationFramework getInstance() {
7070
return instance;
7171
}
7272

73+
/**
74+
* Get the plugin directory.
75+
*/
76+
public synchronized File getPluginDirectory() {
77+
return pluginDirectory;
78+
}
79+
80+
/**
81+
* Set the plugin directory.
82+
*
83+
* @param pluginDirectory the directory
84+
*/
85+
public synchronized void setPluginDirectory(File pluginDirectory) {
86+
this.pluginDirectory = pluginDirectory;
87+
}
88+
89+
/**
90+
* Set the plugin directory.
91+
*
92+
* @param directory the directory path
93+
*/
94+
public void setPluginDirectory(String directory) {
95+
AuthorizationFramework.this.setPluginDirectory(directory != null ? new File(directory) : null);
96+
}
97+
7398
/**
7499
* Checks if the request should have an access to project.
75100
*
@@ -113,22 +138,19 @@ public boolean test(IAuthorizationPlugin plugin) {
113138
private AuthorizationFramework() {
114139
String path = RuntimeEnvironment.getInstance()
115140
.getPluginDirectory();
116-
File directory = path == null ? null : new File(path);
117-
if (path == null || directory == null || !directory.isDirectory() || !directory.canRead()) {
118-
LOGGER.log(Level.INFO, "plugin directory not found or not readable: {0}. "
119-
+ "The AuthorizationFramework will just pass requests through.", path);
120-
}
121141
plugins = new ArrayList<>();
122-
this.directory = directory;
142+
setPluginDirectory(path);
123143
reload();
124144
}
125145

126146
/**
127147
* Get available plugins.
128148
*
129149
* This and couple of following methods are declared as synchronized because
130-
* 1) plugins can be reloaded at anytime
131-
* 2) requests are pretty asynchronous
150+
* <ol>
151+
* <li>plugins can be reloaded at anytime</li>
152+
* <li>requests are pretty asynchronous</li>
153+
* </ol>
132154
*
133155
* So this tries to ensure that there will be no
134156
* ConcurrentModificationException or other similar exceptions.
@@ -179,7 +201,7 @@ private void removeAll() {
179201
* @return list of file with suffix
180202
*/
181203
private List<File> listFiles(String suffix) {
182-
File[] files = directory.listFiles(new FilenameFilter() {
204+
File[] files = pluginDirectory.listFiles(new FilenameFilter() {
183205
@Override
184206
public boolean accept(File dir, String name) {
185207
return name.endsWith(suffix);
@@ -196,7 +218,7 @@ public boolean accept(File dir, String name) {
196218
* @return recursively traversed list of files with given suffix
197219
*/
198220
private List<File> listFilesRec(String suffix) {
199-
return listFilesClassesRec(directory, suffix);
221+
return listFilesClassesRec(pluginDirectory, suffix);
200222
}
201223

202224
private List<File> listFilesClassesRec(File start, String suffix) {
@@ -236,7 +258,7 @@ private void loadClass(String classname) throws ClassNotFoundException,
236258
SecurityException,
237259
InstantiationException,
238260
IllegalAccessException {
239-
261+
240262
Class c = loader.loadClass(classname);
241263
// check for implemented interfaces
242264
Class[] intf = c.getInterfaces();
@@ -256,7 +278,7 @@ private void loadClass(String classname) throws ClassNotFoundException,
256278
}
257279

258280
private String getClassName(File f) {
259-
String classname = f.getAbsolutePath().substring(directory.getAbsolutePath().length() + 1, f.getAbsolutePath().length());
281+
String classname = f.getAbsolutePath().substring(pluginDirectory.getAbsolutePath().length() + 1, f.getAbsolutePath().length());
260282
classname = classname.replace(File.separatorChar, '.'); // convert to package name
261283
classname = classname.substring(0, classname.lastIndexOf('.')); // strip .class
262284
return classname;
@@ -275,24 +297,27 @@ private String getClassName(JarEntry f) {
275297
* Old instances of plugins are removed and new list of plugins is
276298
* constructed. Unload and load event is fired on each plugin.
277299
*
278-
* @see IAuthorizationPlugin#load()
279-
* @see IAuthorizationPlugin#unload()
300+
* @see IAuthorizationPlugin#load()
301+
* @see IAuthorizationPlugin#unload()
280302
*/
281303
@SuppressWarnings("unchecked")
282304
public synchronized void reload() {
283-
if (directory == null || !directory.isDirectory() || !directory.canRead()) {
305+
if (pluginDirectory == null || !pluginDirectory.isDirectory() || !pluginDirectory.canRead()) {
306+
LOGGER.log(Level.WARNING, "plugin directory not found or not readable: {0}. "
307+
+ "All requests allowed.", pluginDirectory);
284308
return;
285309
}
286-
LOGGER.log(Level.INFO, "Plugins are being reloaded from " + directory.getAbsolutePath());
310+
LOGGER.log(Level.INFO, "Plugins are being reloaded from {0}", pluginDirectory.getAbsolutePath());
287311
removeAll();
288312
// trashing out the old instance of the loaded enables us
289313
// to reaload the plugins at runtime
290314
loader = (AuthorizationPluginClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
315+
@Override
291316
public Object run() {
292-
return new AuthorizationPluginClassLoader(directory);
317+
return new AuthorizationPluginClassLoader(pluginDirectory);
293318
}
294319
});
295-
320+
296321
removeAll();
297322
plugins = new ArrayList<>();
298323

@@ -322,7 +347,7 @@ public Object run() {
322347
LOGGER.log(Level.INFO, "Could not manipulate with file because of: ", ex);
323348
}
324349
}
325-
350+
326351
for (IAuthorizationPlugin plugin : getPlugins()) {
327352
try {
328353
plugin.load();

src/org/opensolaris/opengrok/configuration/Configuration.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,17 @@ public final class Configuration {
7979
private int historyCacheTime;
8080

8181
private int messageLimit;
82+
/**
83+
* Directory with authorization plugins. Default value is
84+
* dataRoot/../plugins (can be /var/opengrok/plugins if dataRoot is
85+
* /var/opengrok/data).
86+
*/
8287
private String pluginDirectory;
88+
/**
89+
* Enable watching the plugin directory for changes in real time. Suitable
90+
* for development.
91+
*/
92+
private boolean authorizationWatchdogEnabled;
8393
private List<Project> projects;
8494
private Set<Group> groups;
8595
private String sourceRoot;
@@ -323,6 +333,7 @@ public Configuration() {
323333
setRevisionMessageCollapseThreshold(200);
324334
setGroupsCollapseThreshold(4);
325335
setPluginDirectory(null);
336+
setAuthorizationWatchdogEnabled(false);
326337
setMaxSearchThreadCount(2 * Runtime.getRuntime().availableProcessors());
327338
setIndexRefreshPeriod(3600);
328339
setMessageLimit(500);
@@ -374,6 +385,14 @@ public void setPluginDirectory(String pluginDirectory) {
374385
this.pluginDirectory = pluginDirectory;
375386
}
376387

388+
public boolean isAuthorizationWatchdogEnabled() {
389+
return authorizationWatchdogEnabled;
390+
}
391+
392+
public void setAuthorizationWatchdogEnabled(boolean authorizationWatchdogEnabled) {
393+
this.authorizationWatchdogEnabled = authorizationWatchdogEnabled;
394+
}
395+
377396
public void setCmds(Map<String, String> cmds) {
378397
this.cmds.clear();
379398
this.cmds.putAll(cmds);

src/org/opensolaris/opengrok/configuration/RuntimeEnvironment.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,14 @@ public String getPluginDirectory() {
730730
return threadConfig.get().getPluginDirectory();
731731
}
732732

733+
public boolean isAuthorizationWatchdog() {
734+
return threadConfig.get().isAuthorizationWatchdogEnabled();
735+
}
736+
737+
public void setAuthorizationWatchdog(boolean authorizationWatchdogEnabled) {
738+
threadConfig.get().setAuthorizationWatchdogEnabled(authorizationWatchdogEnabled);
739+
}
740+
733741
/**
734742
* Is the verbosity flag turned on?
735743
*
@@ -1576,6 +1584,8 @@ public void applyConfig(Configuration config, boolean reindex) {
15761584
// Force timestamp to update itself upon new config arrival.
15771585
config.refreshDateForLastIndexRun();
15781586
}
1587+
AuthorizationFramework.getInstance().setPluginDirectory(config.getPluginDirectory());
1588+
AuthorizationFramework.getInstance().reload();
15791589
}
15801590

15811591
/**
@@ -1691,10 +1701,11 @@ protected void handleMessage(Message m, final OutputStream output) throws IOExce
16911701

16921702
/**
16931703
* Starts a watch dog service for a directory. It automatically reloads the
1694-
* AuthorizationFramework if there was a change.
1704+
* AuthorizationFramework if there was a change in <b>real-time</b>.
1705+
* Suitable for plugin development.
16951706
*
1696-
* You can control start of this service by context-parameter in web.xml
1697-
* param-name: enableAuthorizationWatchDog
1707+
* You can control start of this service by a configuration parameter
1708+
* {@link Configuration#authorizationWatchdogEnabled}
16981709
*
16991710
* @param directory root directory for plugins
17001711
*/

src/org/opensolaris/opengrok/web/WebappListener.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
4242
import org.opensolaris.opengrok.logger.LoggerFactory;
4343

44-
import static org.opensolaris.opengrok.configuration.Configuration.PLUGIN_DIRECTORY_DEFAULT;
45-
4644
/**
4745
* Initialize webapp context
4846
*
@@ -98,22 +96,18 @@ public void contextInitialized(final ServletContextEvent servletContextEvent) {
9896
}
9997
}
10098

101-
String pluginDirectory = context.getInitParameter(AUTHORIZATION_PLUGIN_DIRECTORY);
102-
if (pluginDirectory != null) {
103-
env.getConfiguration().setPluginDirectory(pluginDirectory);
104-
AuthorizationFramework.getInstance(); // start + load
105-
} else {
106-
if (env.getDataRootPath() == null) {
107-
env.getConfiguration().setPluginDirectory(PLUGIN_DIRECTORY_DEFAULT);
108-
} else {
109-
env.getConfiguration().setPluginDirectory(env.getDataRootPath() + "/../" + PLUGIN_DIRECTORY_DEFAULT);
110-
}
111-
LOGGER.log(Level.INFO, AUTHORIZATION_PLUGIN_DIRECTORY + " is not set in web.xml. Default location will be used.");
99+
try {
100+
RuntimeEnvironment.getInstance().loadStatistics();
101+
} catch (IOException ex) {
102+
LOGGER.log(Level.INFO, "Could not load statistics from a file.", ex);
103+
} catch (ParseException ex) {
104+
LOGGER.log(Level.SEVERE, "Could not parse statistics from a file.", ex);
112105
}
113106

114-
String watchDog = context.getInitParameter(ENABLE_AUTHORIZATION_WATCH_DOG);
115-
if (pluginDirectory != null && watchDog != null && Boolean.parseBoolean(watchDog)) {
116-
RuntimeEnvironment.getInstance().startWatchDogService(new File(pluginDirectory));
107+
AuthorizationFramework.getInstance(); // start + load
108+
109+
if (env.getConfiguration().getPluginDirectory() != null && env.isAuthorizationWatchdog()) {
110+
RuntimeEnvironment.getInstance().startWatchDogService(new File(env.getConfiguration().getPluginDirectory()));
117111
}
118112

119113
RuntimeEnvironment.getInstance().startIndexReopenThread();

web/WEB-INF/web.xml

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,6 @@
1414
<param-value>localhost:2424</param-value>
1515
</context-param>
1616

17-
<context-param>
18-
<description>
19-
Directory with authorization plugins.
20-
Default value is dataRoot/../plugins
21-
(can be /var/opengrok/plugins if dataRoot is /var/opengrok/data).
22-
</description>
23-
<param-name>authorizationPluginDirectory</param-name>
24-
<param-value>/var/opengrok/plugins</param-value>
25-
</context-param>
26-
27-
<context-param>
28-
<description>
29-
Enable watching the plugin directory for changes in real time.
30-
Suitable for development.
31-
</description>
32-
<param-name>enableAuthorizationWatchDog</param-name>
33-
<param-value>false</param-value>
34-
</context-param>
35-
3617
<listener>
3718
<listener-class>org.opensolaris.opengrok.web.WebappListener</listener-class>
3819
</listener>

0 commit comments

Comments
 (0)