Add support for user-specific URL aliases
User-specific URL aliases overwrite global URL aliases. Plugins may use user-specific URL aliases to replace certain screens for certain users. The cookbook plugin was adapted to demonstrate this. Change-Id: I9b4d89e9b0fcedbeceb7298b91506167d464a070 Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
parent
107b0ad53f
commit
b1e6a3a69c
@ -1792,6 +1792,11 @@ By defining an link:config-gerrit.html#urlAlias[urlAlias] Gerrit
|
||||
administrators can map plugin screens into the Gerrit URL namespace or
|
||||
even replace Gerrit screens by plugin screens.
|
||||
|
||||
Plugins may also programatically add URL aliases in the preferences of
|
||||
of a user. This way certain screens can be replaced for certain users.
|
||||
E.g. the plugin may offer a user preferences setting for choosing a
|
||||
screen that then sets/unsets a URL alias for the user.
|
||||
|
||||
[[settings-screen]]
|
||||
== Plugin Settings Screen
|
||||
|
||||
|
@ -1638,6 +1638,9 @@ Allowed values are `SIDE_BY_SIDE`, `UNIFIED_DIFF`.
|
||||
|`my` ||
|
||||
The menu items of the `MY` top menu as a list of
|
||||
link:rest-api-config.html#top-menu-item-info[TopMenuItemInfo] entities.
|
||||
|`url_aliases` |optional|
|
||||
A map of URL path pairs, where the first URL path is an alias for the
|
||||
second URL path.
|
||||
|============================================
|
||||
|
||||
[[preferences-input]]
|
||||
@ -1684,6 +1687,9 @@ Allowed values are `SIDE_BY_SIDE`, `UNIFIED_DIFF`.
|
||||
|`my` |optional|
|
||||
The menu items of the `MY` top menu as a list of
|
||||
link:rest-api-config.html#top-menu-item-info[TopMenuItemInfo] entities.
|
||||
|`url_aliases` |optional|
|
||||
A map of URL path pairs, where the first URL path is an alias for the
|
||||
second URL path.
|
||||
|============================================
|
||||
|
||||
[[query-limit-info]]
|
||||
|
@ -14,6 +14,9 @@
|
||||
|
||||
package com.google.gerrit.client.info;
|
||||
|
||||
import com.google.gerrit.client.rpc.NativeMap;
|
||||
import com.google.gerrit.client.rpc.NativeString;
|
||||
import com.google.gerrit.client.rpc.Natives;
|
||||
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
|
||||
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DateFormat;
|
||||
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DiffView;
|
||||
@ -24,7 +27,9 @@ import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.TimeFormat;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.core.client.JsArray;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AccountPreferencesInfo extends JavaScriptObject {
|
||||
public static AccountPreferencesInfo create() {
|
||||
@ -197,6 +202,26 @@ public class AccountPreferencesInfo extends JavaScriptObject {
|
||||
final native void initMy() /*-{ this.my = []; }-*/;
|
||||
final native void addMy(TopMenuItem m) /*-{ this.my.push(m); }-*/;
|
||||
|
||||
public final Map<String, String> urlAliases() {
|
||||
Map<String, String> urlAliases = new HashMap<>();
|
||||
for (String k : Natives.keys(_urlAliases())) {
|
||||
urlAliases.put(k, urlAliasToken(k));
|
||||
}
|
||||
return urlAliases;
|
||||
}
|
||||
|
||||
private final native String urlAliasToken(String m) /*-{ return this.url_aliases[m]; }-*/;
|
||||
private final native NativeMap<NativeString> _urlAliases() /*-{ return this.url_aliases; }-*/;
|
||||
|
||||
public final void setUrlAliases(Map<String, String> urlAliases) {
|
||||
initUrlAliases();
|
||||
for (Map.Entry<String, String> e : urlAliases.entrySet()) {
|
||||
putUrlAlias(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
private final native void putUrlAlias(String m, String t) /*-{ this.url_aliases[m] = t; }-*/;
|
||||
private final native void initUrlAliases() /*-{ this.url_aliases = {}; }-*/;
|
||||
|
||||
protected AccountPreferencesInfo() {
|
||||
}
|
||||
}
|
||||
|
@ -391,6 +391,7 @@ public class Gerrit implements EntryPoint {
|
||||
myAccount = AccountInfo.create(0, null, null, null);
|
||||
myAccountDiffPref = null;
|
||||
myPrefs = AccountPreferencesInfo.createDefault();
|
||||
urlAliasMatcher.clearUserAliases();
|
||||
xGerritAuth = null;
|
||||
refreshMenuBar();
|
||||
|
||||
@ -880,6 +881,7 @@ public class Gerrit implements EntryPoint {
|
||||
siteFooter.setVisible(myPrefs.showSiteHeader());
|
||||
}
|
||||
FormatUtil.setPreferences(myPrefs);
|
||||
urlAliasMatcher.updateUserAliases(myPrefs.urlAliases());
|
||||
}
|
||||
|
||||
private static void getDocIndex(final AsyncCallback<DocInfo> cb) {
|
||||
|
@ -20,18 +20,41 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class UrlAliasMatcher {
|
||||
private final Map<RegExp, String> userUrlAliases;
|
||||
private final Map<RegExp, String> globalUrlAliases;
|
||||
|
||||
UrlAliasMatcher(Map<String, String> globalUrlAliases) {
|
||||
this.globalUrlAliases = new HashMap<>();
|
||||
if (globalUrlAliases != null) {
|
||||
for (Map.Entry<String, String> e : globalUrlAliases.entrySet()) {
|
||||
this.globalUrlAliases.put(RegExp.compile(e.getKey()), e.getValue());
|
||||
this.globalUrlAliases = compile(globalUrlAliases);
|
||||
this.userUrlAliases = new HashMap<>();
|
||||
}
|
||||
|
||||
private static Map<RegExp, String> compile(Map<String, String> urlAliases) {
|
||||
Map<RegExp, String> compiledUrlAliases = new HashMap<>();
|
||||
if (urlAliases != null) {
|
||||
for (Map.Entry<String, String> e : urlAliases.entrySet()) {
|
||||
compiledUrlAliases.put(RegExp.compile(e.getKey()), e.getValue());
|
||||
}
|
||||
}
|
||||
return compiledUrlAliases;
|
||||
}
|
||||
|
||||
void clearUserAliases() {
|
||||
this.userUrlAliases.clear();
|
||||
}
|
||||
|
||||
void updateUserAliases(Map<String, String> userUrlAliases) {
|
||||
clearUserAliases();
|
||||
this.userUrlAliases.putAll(compile(userUrlAliases));
|
||||
}
|
||||
|
||||
public String replace(String token) {
|
||||
for (Map.Entry<RegExp, String> e : userUrlAliases.entrySet()) {
|
||||
RegExp pat = e.getKey();
|
||||
if (pat.exec(token) != null) {
|
||||
return pat.replace(token, e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<RegExp, String> e : globalUrlAliases.entrySet()) {
|
||||
RegExp pat = e.getKey();
|
||||
if (pat.exec(token) != null) {
|
||||
|
@ -44,7 +44,9 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Singleton
|
||||
public class GetPreferences implements RestReadView<AccountResource> {
|
||||
@ -54,6 +56,9 @@ public class GetPreferences implements RestReadView<AccountResource> {
|
||||
public static final String KEY_URL = "url";
|
||||
public static final String KEY_TARGET = "target";
|
||||
public static final String KEY_ID = "id";
|
||||
public static final String URL_ALIAS = "urlAlias";
|
||||
public static final String KEY_MATCH = "match";
|
||||
public static final String KEY_TOKEN = "token";
|
||||
|
||||
private final Provider<CurrentUser> self;
|
||||
private final Provider<ReviewDb> db;
|
||||
@ -110,6 +115,7 @@ public class GetPreferences implements RestReadView<AccountResource> {
|
||||
ReviewCategoryStrategy reviewCategoryStrategy;
|
||||
DiffView diffView;
|
||||
List<TopMenu.MenuItem> my;
|
||||
Map<String, String> urlAliases;
|
||||
|
||||
public PreferenceInfo(AccountGeneralPreferences p,
|
||||
VersionedAccountPreferences v, Repository allUsers) {
|
||||
@ -129,12 +135,12 @@ public class GetPreferences implements RestReadView<AccountResource> {
|
||||
reviewCategoryStrategy = p.getReviewCategoryStrategy();
|
||||
diffView = p.getDiffView();
|
||||
}
|
||||
my = my(v, allUsers);
|
||||
loadFromAllUsers(v, allUsers);
|
||||
}
|
||||
|
||||
private List<TopMenu.MenuItem> my(VersionedAccountPreferences v,
|
||||
private void loadFromAllUsers(VersionedAccountPreferences v,
|
||||
Repository allUsers) {
|
||||
List<TopMenu.MenuItem> my = my(v);
|
||||
my = my(v);
|
||||
if (my.isEmpty() && !v.isDefaults()) {
|
||||
try {
|
||||
VersionedAccountPreferences d = VersionedAccountPreferences.forDefault();
|
||||
@ -153,7 +159,8 @@ public class GetPreferences implements RestReadView<AccountResource> {
|
||||
my.add(new TopMenu.MenuItem("Starred Changes", "#/q/is:starred", null));
|
||||
my.add(new TopMenu.MenuItem("Groups", "#/groups/self", null));
|
||||
}
|
||||
return my;
|
||||
|
||||
urlAliases = urlAliases(v);
|
||||
}
|
||||
|
||||
private List<TopMenu.MenuItem> my(VersionedAccountPreferences v) {
|
||||
@ -175,5 +182,15 @@ public class GetPreferences implements RestReadView<AccountResource> {
|
||||
String val = cfg.getString(MY, subsection, key);
|
||||
return !Strings.isNullOrEmpty(val) ? val : defaultValue;
|
||||
}
|
||||
|
||||
private static Map<String, String> urlAliases(VersionedAccountPreferences v) {
|
||||
HashMap<String, String> urlAliases = new HashMap<>();
|
||||
Config cfg = v.getConfig();
|
||||
for (String subsection : cfg.getSubsections(URL_ALIAS)) {
|
||||
urlAliases.put(cfg.getString(URL_ALIAS, subsection, KEY_MATCH),
|
||||
cfg.getString(URL_ALIAS, subsection, KEY_TOKEN));
|
||||
}
|
||||
return !urlAliases.isEmpty() ? urlAliases : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,12 @@
|
||||
package com.google.gerrit.server.account;
|
||||
|
||||
import static com.google.gerrit.server.account.GetPreferences.KEY_ID;
|
||||
import static com.google.gerrit.server.account.GetPreferences.KEY_MATCH;
|
||||
import static com.google.gerrit.server.account.GetPreferences.KEY_TARGET;
|
||||
import static com.google.gerrit.server.account.GetPreferences.KEY_TOKEN;
|
||||
import static com.google.gerrit.server.account.GetPreferences.KEY_URL;
|
||||
import static com.google.gerrit.server.account.GetPreferences.MY;
|
||||
import static com.google.gerrit.server.account.GetPreferences.URL_ALIAS;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
@ -48,6 +51,8 @@ import org.eclipse.jgit.lib.Config;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@Singleton
|
||||
public class SetPreferences implements RestModifyView<AccountResource, Input> {
|
||||
@ -67,6 +72,7 @@ public class SetPreferences implements RestModifyView<AccountResource, Input> {
|
||||
public ReviewCategoryStrategy reviewCategoryStrategy;
|
||||
public DiffView diffView;
|
||||
public List<TopMenu.MenuItem> my;
|
||||
public Map<String, String> urlAliases;
|
||||
}
|
||||
|
||||
private final Provider<CurrentUser> self;
|
||||
@ -164,11 +170,11 @@ public class SetPreferences implements RestModifyView<AccountResource, Input> {
|
||||
db.get().accounts().update(Collections.singleton(a));
|
||||
db.get().commit();
|
||||
storeMyMenus(versionedPrefs, i.my);
|
||||
storeUrlAliases(versionedPrefs, i.urlAliases);
|
||||
versionedPrefs.commit(md);
|
||||
cache.evict(accountId);
|
||||
return new GetPreferences.PreferenceInfo(
|
||||
p, versionedPrefs,
|
||||
md.getRepository());
|
||||
p, versionedPrefs, md.getRepository());
|
||||
} finally {
|
||||
md.close();
|
||||
db.get().rollback();
|
||||
@ -202,4 +208,21 @@ public class SetPreferences implements RestModifyView<AccountResource, Input> {
|
||||
cfg.unsetSection(section, subsection);
|
||||
}
|
||||
}
|
||||
|
||||
public static void storeUrlAliases(VersionedAccountPreferences prefs,
|
||||
Map<String, String> urlAliases) {
|
||||
if (urlAliases != null) {
|
||||
Config cfg = prefs.getConfig();
|
||||
for (String subsection : cfg.getSubsections(URL_ALIAS)) {
|
||||
cfg.unsetSection(URL_ALIAS, subsection);
|
||||
}
|
||||
|
||||
int i = 1;
|
||||
for (Entry<String, String> e : urlAliases.entrySet()) {
|
||||
cfg.setString(URL_ALIAS, URL_ALIAS + i, KEY_MATCH, e.getKey());
|
||||
cfg.setString(URL_ALIAS, URL_ALIAS + i, KEY_TOKEN, e.getValue());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e49010bbbed9d941c35a9f1eed1178cd909c7e34
|
||||
Subproject commit d2f6bc3511185729d3ecc3b3df25b1e9cebe2b2d
|
Loading…
Reference in New Issue
Block a user