From c9921bd3b0b7bf90b6e5e2a52141c3fdf0f31f89 Mon Sep 17 00:00:00 2001 From: James Moger Date: Wed, 4 Jun 2014 17:04:17 -0400 Subject: Revise the user profile page and add a preferences form --- .../com/gitblit/wicket/GitBlitWebApp.properties | 9 +- .../java/com/gitblit/wicket/pages/UserPage.html | 51 ++++--- .../java/com/gitblit/wicket/pages/UserPage.java | 153 +++++++++++++++++++-- .../gitblit/wicket/panels/AccessPolicyPanel.html | 2 +- .../gitblit/wicket/panels/BooleanChoiceOption.html | 2 +- .../com/gitblit/wicket/panels/BooleanOption.html | 2 +- .../com/gitblit/wicket/panels/ChoiceOption.html | 2 +- .../java/com/gitblit/wicket/panels/TextOption.html | 2 +- 8 files changed, 185 insertions(+), 38 deletions(-) (limited to 'src/main/java/com') diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties index d6fd57e9..81171799 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties @@ -722,4 +722,11 @@ gb.originDescription = The url from which this repository was cloned. gb.gc = GC gb.garbageCollection = Garbage Collection gb.garbageCollectionDescription = The garbage collector will pack loose objects pushed from clients and will remove unreferenced objects from the repository. -gb.commitMessageRendererDescription = Commit messages can be displayed as plaintext or as rendered markup. \ No newline at end of file +gb.commitMessageRendererDescription = Commit messages can be displayed as plaintext or as rendered markup. +gb.preferences = preferences +gb.accountPreferences = Account Preferences +gb.accountPreferencesDescription = Specify your account preferences +gb.languagePreference = Language Preference +gb.languagePreferenceDescription = Select your preferred translation for the Gitblit UI +gb.displayNameDescription = The preferred name for display +gb.emailAddressDescription = The primary email address for receiving notifications \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.html b/src/main/java/com/gitblit/wicket/pages/UserPage.html index 7aaded7a..09267873 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.html +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.html @@ -7,27 +7,19 @@
-
-
-
-
-

-
-
-
+
+
+
- -
- -
+
+ +
+
+
@@ -41,11 +33,36 @@
+ + +
+
+ + +
  • +
    + + +
    +

    +

    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.java b/src/main/java/com/gitblit/wicket/pages/UserPage.java index 29b49b33..baad4a06 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.java +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.java @@ -15,19 +15,27 @@ */ package com.gitblit.wicket.pages; +import java.io.Serializable; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Locale; import org.apache.wicket.PageParameters; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; -import org.eclipse.jgit.lib.PersonIdent; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import com.gitblit.GitBlitException; import com.gitblit.Keys; import com.gitblit.models.Menu.ParameterMenuItem; import com.gitblit.models.NavLink; @@ -40,9 +48,10 @@ import com.gitblit.wicket.GitBlitWebApp; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.GitblitRedirectException; import com.gitblit.wicket.WicketUtils; -import com.gitblit.wicket.panels.GravatarImage; -import com.gitblit.wicket.panels.LinkPanel; +import com.gitblit.wicket.panels.ChoiceOption; import com.gitblit.wicket.panels.ProjectRepositoryPanel; +import com.gitblit.wicket.panels.TextOption; +import com.gitblit.wicket.panels.UserTitlePanel; public class UserPage extends RootPage { @@ -83,21 +92,18 @@ public class UserPage extends RootPage { user = new UserModel(userName); } - add(new Label("userDisplayName", user.getDisplayName())); - add(new Label("userUsername", user.username)); - LinkPanel email = new LinkPanel("userEmail", null, user.emailAddress, "mailto:#"); - email.setRenderBodyOnly(true); - add(email.setVisible(app().settings().getBoolean(Keys.web.showEmailAddresses, true) && !StringUtils.isEmpty(user.emailAddress))); - PersonIdent person = new PersonIdent(user.getDisplayName(), user.emailAddress == null ? user.getDisplayName() : user.emailAddress); - add(new GravatarImage("gravatar", person, 210)); + add(new UserTitlePanel("userTitlePanel", user, user.username)); UserModel sessionUser = GitBlitWebSession.get().getUser(); - if (sessionUser != null && user.canCreate() && sessionUser.equals(user)) { - // user can create personal repositories - add(new BookmarkablePageLink("newRepository", app().getNewRepositoryPage())); + boolean isMyProfile = sessionUser != null && sessionUser.equals(user); + + if (isMyProfile) { + addPreferences(user); } else { - add(new Label("newRepository").setVisible(false)); + // visiting user + add(new Label("preferencesLink").setVisible(false)); + add(new Label("preferencesTab").setVisible(false)); } List repositories = getRepositories(params); @@ -145,4 +151,121 @@ public class UserPage extends RootPage { navLinks.add(menu); } + + private void addPreferences(UserModel user) { + // add preferences + Form prefs = new Form("prefsForm"); + + List languages = Arrays.asList( + new Language("English","en"), + new Language("Español", "es"), + new Language("Français", "fr"), + new Language("日本語", "ja"), + new Language("한국말", "ko"), + new Language("Nederlands", "nl"), + new Language("Norsk", "no"), + new Language("Język Polski", "pl"), + new Language("Português", "pt_BR"), + new Language("中文", "zh_CN")); + + String lc = user.getPreferences().locale; + if (StringUtils.isEmpty(lc)) { + // user has not specified language preference + // try server default preference + lc = app().settings().getString(Keys.web.forceDefaultLocale, null); + if (StringUtils.isEmpty(lc)) { + // server default language is not configured + // try browser preference + Locale sessionLocale = GitBlitWebSession.get().getLocale(); + if (sessionLocale != null) { + lc = sessionLocale.getLanguage() + "_" + sessionLocale.getCountry(); + } + } + } + Language preferredLanguage = null; + if (!StringUtils.isEmpty(lc)) { + for (Language language : languages) { + if (language.code.equals(lc)) { + // language_COUNTRY match + preferredLanguage = language; + } else if (preferredLanguage != null && lc.startsWith(language.code)) { + // language match, but not COUNTRY match + preferredLanguage = language; + } + } + } + + final IModel displayName = Model.of(user.getDisplayName()); + final IModel emailAddress = Model.of(user.emailAddress == null ? "" : user.emailAddress); + final IModel language = Model.of(preferredLanguage); + + prefs.add(new TextOption("displayName", + getString("gb.displayName"), + getString("gb.displayNameDescription"), + displayName).setVisible(app().authentication().supportsDisplayNameChanges(user))); + + prefs.add(new TextOption("emailAddress", + getString("gb.emailAddress"), + getString("gb.emailAddressDescription"), + emailAddress).setVisible(app().authentication().supportsEmailAddressChanges(user))); + + prefs.add(new ChoiceOption("language", + getString("gb.languagePreference"), + getString("gb.languagePreferenceDescription"), + language, + languages)); + + prefs.add(new AjaxButton("save") { + + private static final long serialVersionUID = 1L; + + @Override + protected void onSubmit(AjaxRequestTarget target, Form form) { + + UserModel user = GitBlitWebSession.get().getUser(); + + user.displayName = displayName.getObject(); + user.emailAddress = emailAddress.getObject(); + + Language lang = language.getObject(); + if (lang != null) { + user.getPreferences().locale = lang.code; + } + + try { + app().gitblit().reviseUser(user.username, user); + + setRedirect(true); + setResponsePage(UserPage.class, WicketUtils.newUsernameParameter(user.username)); + } catch (GitBlitException e) { + // logger.error("Failed to update user " + user.username, e); + // error(getString("gb.failedToUpdateUser"), false); + } + } + }); + + // add the preferences tab + add(new Fragment("preferencesLink", "preferencesLinkFragment", this).setRenderBodyOnly(true)); + Fragment fragment = new Fragment("preferencesTab", "preferencesTabFragment", this); + fragment.add(prefs); + add(fragment.setRenderBodyOnly(true)); + } + + private class Language implements Serializable { + + private static final long serialVersionUID = 1L; + + final String name; + final String code; + + public Language(String name, String code) { + this.name = name; + this.code = code; + } + + @Override + public String toString() { + return name + " (" + code +")"; + } + } } diff --git a/src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.html b/src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.html index 87a02068..07050192 100644 --- a/src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.html +++ b/src/main/java/com/gitblit/wicket/panels/AccessPolicyPanel.html @@ -13,7 +13,7 @@
    - +
    diff --git a/src/main/java/com/gitblit/wicket/panels/BooleanChoiceOption.html b/src/main/java/com/gitblit/wicket/panels/BooleanChoiceOption.html index fb360d12..b1ced8da 100644 --- a/src/main/java/com/gitblit/wicket/panels/BooleanChoiceOption.html +++ b/src/main/java/com/gitblit/wicket/panels/BooleanChoiceOption.html @@ -8,7 +8,7 @@
    - +
    diff --git a/src/main/java/com/gitblit/wicket/panels/ChoiceOption.html b/src/main/java/com/gitblit/wicket/panels/ChoiceOption.html index 8c34c819..e9e48874 100644 --- a/src/main/java/com/gitblit/wicket/panels/ChoiceOption.html +++ b/src/main/java/com/gitblit/wicket/panels/ChoiceOption.html @@ -7,7 +7,7 @@
    -
    +
    @@ -47,6 +51,10 @@
  • + +
  • +
    +

    @@ -63,6 +71,12 @@
    + +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.java b/src/main/java/com/gitblit/wicket/pages/UserPage.java index baad4a06..4a955c7c 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.java +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.java @@ -50,6 +50,7 @@ import com.gitblit.wicket.GitblitRedirectException; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.ChoiceOption; import com.gitblit.wicket.panels.ProjectRepositoryPanel; +import com.gitblit.wicket.panels.SshKeysPanel; import com.gitblit.wicket.panels.TextOption; import com.gitblit.wicket.panels.UserTitlePanel; @@ -100,10 +101,22 @@ public class UserPage extends RootPage { if (isMyProfile) { addPreferences(user); + + if (app().gitblit().isServingSSH()) { + // show the SSH key management tab + addSshKeys(user); + } else { + // SSH daemon is disabled, hide keys tab + add(new Label("sshKeysLink").setVisible(false)); + add(new Label("sshKeysTab").setVisible(false)); + } } else { // visiting user add(new Label("preferencesLink").setVisible(false)); add(new Label("preferencesTab").setVisible(false)); + + add(new Label("sshKeysLink").setVisible(false)); + add(new Label("sshKeysTab").setVisible(false)); } List repositories = getRepositories(params); @@ -251,6 +264,15 @@ public class UserPage extends RootPage { add(fragment.setRenderBodyOnly(true)); } + private void addSshKeys(final UserModel user) { + Fragment keysTab = new Fragment("sshKeysTab", "sshKeysTabFragment", this); + keysTab.add(new SshKeysPanel("sshKeysPanel", user, getClass(), getPageParameters())); + + // add the SSH keys tab + add(new Fragment("sshKeysLink", "sshKeysLinkFragment", this).setRenderBodyOnly(true)); + add(keysTab.setRenderBodyOnly(true)); + } + private class Language implements Serializable { private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.html b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.html new file mode 100644 index 00000000..d67b704a --- /dev/null +++ b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.html @@ -0,0 +1,46 @@ + + + + + +

    +

    +
    + +
    +
    + +
    +
    +
    +
    
    +		
    + +
    +
    +
    +
    + +
    + +
    + +
    +
    + +
    +
    +

    +
    +
    +
    + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java new file mode 100644 index 00000000..03cb93ca --- /dev/null +++ b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java @@ -0,0 +1,161 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.wicket.panels; + +import java.util.Arrays; +import java.util.List; + +import org.apache.wicket.PageParameters; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.link.Link; +import org.apache.wicket.markup.repeater.Item; +import org.apache.wicket.markup.repeater.data.DataView; +import org.apache.wicket.markup.repeater.data.ListDataProvider; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; + +import com.gitblit.Constants.AccessPermission; +import com.gitblit.models.UserModel; +import com.gitblit.transport.ssh.SshKey; +import com.gitblit.utils.StringUtils; +import com.gitblit.wicket.GitBlitWebSession; + + +/** + * A panel that enumerates and manages SSH public keys. + * + * @author James Moger + * + */ +public class SshKeysPanel extends BasePanel { + + private static final long serialVersionUID = 1L; + + private final UserModel user; + + private final Class pageClass; + + private final PageParameters params; + + public SshKeysPanel(String wicketId, UserModel user, Class pageClass, PageParameters params) { + super(wicketId); + + this.user = user; + this.pageClass = pageClass; + this.params = params; + } + + @Override + protected void onInitialize() { + super.onInitialize(); + List keys = app().keys().getKeys(user.username); + + final ListDataProvider dp = new ListDataProvider(keys); + DataView keysView = new DataView("keys", dp) { + private static final long serialVersionUID = 1L; + + @Override + public void populateItem(final Item item) { + final SshKey key = item.getModelObject(); + item.add(new Label("comment", key.getComment())); + item.add(new Label("fingerprint", key.getFingerprint())); + item.add(new Label("permission", key.getPermission().toString())); + item.add(new Label("algorithm", key.getAlgorithm())); + + Link delete = new Link("delete") { + + private static final long serialVersionUID = 1L; + + @Override + public void onClick() { + if (app().keys().removeKey(user.username, key)) { + setRedirect(true); + setResponsePage(pageClass, params); + } + } + }; + item.add(delete); + } + }; + add(keysView); + + Form addKeyForm = new Form("addKeyForm"); + + final IModel keyData = Model.of(""); + addKeyForm.add(new TextAreaOption("addKeyData", + getString("gb.key"), + null, + "span5", + keyData)); + + final IModel keyPermission = Model.of(AccessPermission.PUSH); + addKeyForm.add(new ChoiceOption("addKeyPermission", + getString("gb.permission"), + getString("gb.sshKeyPermissionDescription"), + keyPermission, + Arrays.asList(AccessPermission.SSHPERMISSIONS))); + + final IModel keyComment = Model.of(""); + addKeyForm.add(new TextOption("addKeyComment", + getString("gb.comment"), + getString("gb.sshKeyCommentDescription"), + "span5", + keyComment)); + + addKeyForm.add(new AjaxButton("addKeyButton") { + + private static final long serialVersionUID = 1L; + + @Override + protected void onSubmit(AjaxRequestTarget target, Form form) { + + UserModel user = GitBlitWebSession.get().getUser(); + String data = keyData.getObject(); + if (StringUtils.isEmpty(data)) { + // do not submit empty key + return; + } + + SshKey key = new SshKey(data); + try { + key.getPublicKey(); + } catch (Exception e) { + // failed to parse the key + return; + } + + AccessPermission permission = keyPermission.getObject(); + key.setPermission(permission); + + String comment = keyComment.getObject(); + if (!StringUtils.isEmpty(comment)) { + key.setComment(comment); + } + + if (app().keys().addKey(user.username, key)) { + setRedirect(true); + setResponsePage(pageClass, params); + } + } + }); + + add(addKeyForm); + } +} diff --git a/src/main/java/com/gitblit/wicket/panels/TextAreaOption.html b/src/main/java/com/gitblit/wicket/panels/TextAreaOption.html new file mode 100644 index 00000000..bb7dc7c6 --- /dev/null +++ b/src/main/java/com/gitblit/wicket/panels/TextAreaOption.html @@ -0,0 +1,20 @@ + + + + + +
    +
    + +
    + + +
    +
    + + \ No newline at end of file diff --git a/src/main/java/com/gitblit/wicket/panels/TextAreaOption.java b/src/main/java/com/gitblit/wicket/panels/TextAreaOption.java new file mode 100644 index 00000000..d2c74a06 --- /dev/null +++ b/src/main/java/com/gitblit/wicket/panels/TextAreaOption.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.wicket.panels; + +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.TextArea; +import org.apache.wicket.model.IModel; + +import com.gitblit.utils.StringUtils; +import com.gitblit.wicket.WicketUtils; + +/** + * A re-usable textarea option panel. + * + * title + * description + * [text + * area] + * + * @author James Moger + * + */ +public class TextAreaOption extends BasePanel { + + private static final long serialVersionUID = 1L; + + public TextAreaOption(String wicketId, String title, String description, IModel model) { + this(wicketId, title, description, null, model); + } + + public TextAreaOption(String wicketId, String title, String description, String css, IModel model) { + super(wicketId); + add(new Label("name", title)); + add(new Label("description", description).setVisible(!StringUtils.isEmpty(description))); + TextArea tf = new TextArea("text", model); + if (!StringUtils.isEmpty(css)) { + WicketUtils.setCssClass(tf, css); + } + add(tf); + } +} diff --git a/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java b/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java index 6e56a873..54be539f 100644 --- a/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java +++ b/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java @@ -81,6 +81,21 @@ public class MockRuntimeManager implements IRuntimeManager { return true; } + @Override + public boolean isServingHTTP() { + return true; + } + + @Override + public boolean isServingGIT() { + return true; + } + + @Override + public boolean isServingSSH() { + return true; + } + @Override public boolean isDebugMode() { return true; -- cgit v1.2.3 From 6537deb8b76b7a4725c40a174a7c440385f88e51 Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 5 Jun 2014 10:20:59 -0400 Subject: Revise language/locale preference handling --- src/main/java/com/gitblit/ConfigUserService.java | 9 +++++--- .../java/com/gitblit/models/UserPreferences.java | 6 ++++- .../com/gitblit/wicket/GitBlitWebApp.properties | 2 +- .../java/com/gitblit/wicket/pages/UserPage.java | 26 ++++++++++++++-------- 4 files changed, 29 insertions(+), 14 deletions(-) (limited to 'src/main/java/com') diff --git a/src/main/java/com/gitblit/ConfigUserService.java b/src/main/java/com/gitblit/ConfigUserService.java index 9b4dd7f1..b5dfde3b 100644 --- a/src/main/java/com/gitblit/ConfigUserService.java +++ b/src/main/java/com/gitblit/ConfigUserService.java @@ -707,8 +707,9 @@ public class ConfigUserService implements IUserService { config.setBoolean(USER, model.username, DISABLED, true); } if (model.getPreferences() != null) { - if (!StringUtils.isEmpty(model.getPreferences().locale)) { - config.setString(USER, model.username, LOCALE, model.getPreferences().locale); + if (model.getPreferences().getLocale() != null) { + String val = model.getPreferences().getLocale().getLanguage() + "_" + model.getPreferences().getLocale().getCountry(); + config.setString(USER, model.username, LOCALE, val); } } @@ -880,11 +881,13 @@ public class ConfigUserService implements IUserService { user.stateProvince = config.getString(USER, username, STATEPROVINCE); user.countryCode = config.getString(USER, username, COUNTRYCODE); user.cookie = config.getString(USER, username, COOKIE); - user.getPreferences().locale = config.getString(USER, username, LOCALE); if (StringUtils.isEmpty(user.cookie) && !StringUtils.isEmpty(user.password)) { user.cookie = StringUtils.getSHA1(user.username + user.password); } + // preferences + user.getPreferences().setLocale(config.getString(USER, username, LOCALE)); + // user roles Set roles = new HashSet(Arrays.asList(config.getStringList( USER, username, ROLE))); diff --git a/src/main/java/com/gitblit/models/UserPreferences.java b/src/main/java/com/gitblit/models/UserPreferences.java index 44e44933..61db353c 100644 --- a/src/main/java/com/gitblit/models/UserPreferences.java +++ b/src/main/java/com/gitblit/models/UserPreferences.java @@ -37,7 +37,7 @@ public class UserPreferences implements Serializable { public final String username; - public String locale; + private String locale; private final Map repositoryPreferences = new TreeMap(); @@ -58,6 +58,10 @@ public class UserPreferences implements Serializable { return new Locale(locale); } + public void setLocale(String locale) { + this.locale = locale; + } + public UserRepositoryPreferences getRepositoryPreferences(String repositoryName) { String key = repositoryName.toLowerCase(); if (!repositoryPreferences.containsKey(key)) { diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties index 7dc0f9b6..90d30f29 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties @@ -727,7 +727,7 @@ gb.preferences = preferences gb.accountPreferences = Account Preferences gb.accountPreferencesDescription = Specify your account preferences gb.languagePreference = Language Preference -gb.languagePreferenceDescription = Select your preferred translation for the Gitblit UI +gb.languagePreferenceDescription = Select your preferred translation for Gitblit gb.displayNameDescription = The preferred name for display gb.emailAddressDescription = The primary email address for receiving notifications gb.sshKeys = SSH Keys diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.java b/src/main/java/com/gitblit/wicket/pages/UserPage.java index 4a955c7c..94048963 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.java +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.java @@ -181,28 +181,36 @@ public class UserPage extends RootPage { new Language("Português", "pt_BR"), new Language("中文", "zh_CN")); - String lc = user.getPreferences().locale; - if (StringUtils.isEmpty(lc)) { + Locale locale = user.getPreferences().getLocale(); + if (locale == null) { // user has not specified language preference // try server default preference - lc = app().settings().getString(Keys.web.forceDefaultLocale, null); + String lc = app().settings().getString(Keys.web.forceDefaultLocale, null); if (StringUtils.isEmpty(lc)) { // server default language is not configured // try browser preference Locale sessionLocale = GitBlitWebSession.get().getLocale(); if (sessionLocale != null) { - lc = sessionLocale.getLanguage() + "_" + sessionLocale.getCountry(); + locale = sessionLocale; } + } else { + } } + Language preferredLanguage = null; - if (!StringUtils.isEmpty(lc)) { + if (locale != null) { + String localeCode = locale.getLanguage(); + if (!StringUtils.isEmpty(locale.getCountry())) { + localeCode += "_" + locale.getCountry(); + } + for (Language language : languages) { - if (language.code.equals(lc)) { + if (language.code.equals(localeCode)) { // language_COUNTRY match preferredLanguage = language; - } else if (preferredLanguage != null && lc.startsWith(language.code)) { - // language match, but not COUNTRY match + } else if (preferredLanguage != null && language.code.startsWith(locale.getLanguage())) { + // language match preferredLanguage = language; } } @@ -242,7 +250,7 @@ public class UserPage extends RootPage { Language lang = language.getObject(); if (lang != null) { - user.getPreferences().locale = lang.code; + user.getPreferences().setLocale(lang.code); } try { -- cgit v1.2.3 From 74221eb302e782ef23777d5c3f0a649ceb321c1e Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 5 Jun 2014 10:23:58 -0400 Subject: Add method to INotificationManager to return email service status --- src/main/java/com/gitblit/FederationClient.java | 5 +++++ src/main/java/com/gitblit/manager/GitblitManager.java | 5 +++++ src/main/java/com/gitblit/manager/INotificationManager.java | 8 ++++++++ src/main/java/com/gitblit/manager/NotificationManager.java | 5 +++++ 4 files changed, 23 insertions(+) (limited to 'src/main/java/com') diff --git a/src/main/java/com/gitblit/FederationClient.java b/src/main/java/com/gitblit/FederationClient.java index c3dcd9da..cd06c3cb 100644 --- a/src/main/java/com/gitblit/FederationClient.java +++ b/src/main/java/com/gitblit/FederationClient.java @@ -165,6 +165,11 @@ public class FederationClient { return this; } + @Override + public boolean isSendingMail() { + return false; + } + @Override public void sendMailToAdministrators(String subject, String message) { } diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index ef2433dd..98ad33e7 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -660,6 +660,11 @@ public class GitblitManager implements IGitblit { * NOTIFICATION MANAGER */ + @Override + public boolean isSendingMail() { + return notificationManager.isSendingMail(); + } + @Override public void sendMailToAdministrators(String subject, String message) { notificationManager.sendMailToAdministrators(subject, message); diff --git a/src/main/java/com/gitblit/manager/INotificationManager.java b/src/main/java/com/gitblit/manager/INotificationManager.java index 231cf43a..64fc01e8 100644 --- a/src/main/java/com/gitblit/manager/INotificationManager.java +++ b/src/main/java/com/gitblit/manager/INotificationManager.java @@ -21,6 +21,14 @@ import com.gitblit.models.Mailing; public interface INotificationManager extends IManager { + /** + * Returns true if the email service is configured and ready to send notifications. + * + * @return true if the email service is operational + * @since 1.6.0 + */ + boolean isSendingMail(); + /** * Notify the administrators by email. * diff --git a/src/main/java/com/gitblit/manager/NotificationManager.java b/src/main/java/com/gitblit/manager/NotificationManager.java index ba63cfc1..69a611bb 100644 --- a/src/main/java/com/gitblit/manager/NotificationManager.java +++ b/src/main/java/com/gitblit/manager/NotificationManager.java @@ -71,6 +71,11 @@ public class NotificationManager implements INotificationManager { return this; } + @Override + public boolean isSendingMail() { + return mailService.isReady(); + } + /** * Notify the administrators by email. * -- cgit v1.2.3 From afbaebde11093fae8b420aaaf71dcd56d8c0f9fd Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 5 Jun 2014 10:24:39 -0400 Subject: Add "email me on my ticket changes" preference --- src/main/java/com/gitblit/ConfigUserService.java | 4 ++++ src/main/java/com/gitblit/models/UserPreferences.java | 13 +++++++++++++ src/main/java/com/gitblit/tickets/TicketNotifier.java | 11 +++++++++-- src/main/java/com/gitblit/wicket/GitBlitWebApp.properties | 2 ++ src/main/java/com/gitblit/wicket/pages/UserPage.html | 3 ++- src/main/java/com/gitblit/wicket/pages/UserPage.java | 9 +++++++++ 6 files changed, 39 insertions(+), 3 deletions(-) (limited to 'src/main/java/com') diff --git a/src/main/java/com/gitblit/ConfigUserService.java b/src/main/java/com/gitblit/ConfigUserService.java index b5dfde3b..9759eff7 100644 --- a/src/main/java/com/gitblit/ConfigUserService.java +++ b/src/main/java/com/gitblit/ConfigUserService.java @@ -96,6 +96,8 @@ public class ConfigUserService implements IUserService { private static final String LOCALE = "locale"; + private static final String EMAILONMYTICKETCHANGES = "emailMeOnMyTicketChanges"; + private static final String ACCOUNTTYPE = "accountType"; private static final String DISABLED = "disabled"; @@ -711,6 +713,7 @@ public class ConfigUserService implements IUserService { String val = model.getPreferences().getLocale().getLanguage() + "_" + model.getPreferences().getLocale().getCountry(); config.setString(USER, model.username, LOCALE, val); } + config.setBoolean(USER, model.username, EMAILONMYTICKETCHANGES, model.getPreferences().isEmailMeOnMyTicketChanges()); } // user roles @@ -887,6 +890,7 @@ public class ConfigUserService implements IUserService { // preferences user.getPreferences().setLocale(config.getString(USER, username, LOCALE)); + user.getPreferences().setEmailMeOnMyTicketChanges(config.getBoolean(USER, username, EMAILONMYTICKETCHANGES, true)); // user roles Set roles = new HashSet(Arrays.asList(config.getStringList( diff --git a/src/main/java/com/gitblit/models/UserPreferences.java b/src/main/java/com/gitblit/models/UserPreferences.java index 61db353c..c95b0da5 100644 --- a/src/main/java/com/gitblit/models/UserPreferences.java +++ b/src/main/java/com/gitblit/models/UserPreferences.java @@ -39,6 +39,8 @@ public class UserPreferences implements Serializable { private String locale; + private Boolean emailMeOnMyTicketChanges; + private final Map repositoryPreferences = new TreeMap(); public UserPreferences(String username) { @@ -100,4 +102,15 @@ public class UserPreferences implements Serializable { Collections.sort(list); return list; } + + public boolean isEmailMeOnMyTicketChanges() { + if (emailMeOnMyTicketChanges == null) { + return true; + } + return emailMeOnMyTicketChanges; + } + + public void setEmailMeOnMyTicketChanges(boolean value) { + this.emailMeOnMyTicketChanges = value; + } } diff --git a/src/main/java/com/gitblit/tickets/TicketNotifier.java b/src/main/java/com/gitblit/tickets/TicketNotifier.java index 9a5e4e1d..07371b1b 100644 --- a/src/main/java/com/gitblit/tickets/TicketNotifier.java +++ b/src/main/java/com/gitblit/tickets/TicketNotifier.java @@ -545,7 +545,6 @@ public class TicketNotifier { } } } - mailing.setRecipients(toAddresses); // // CC recipients @@ -554,7 +553,7 @@ public class TicketNotifier { // repository owners if (!ArrayUtils.isEmpty(repository.owners)) { - tos.addAll(repository.owners); + ccs.addAll(repository.owners); } // cc users mentioned in last comment @@ -595,6 +594,14 @@ public class TicketNotifier { } ccAddresses.addAll(settings.getStrings(Keys.mail.mailingLists)); + // respect the author's email preference + UserModel lastAuthor = userManager.getUserModel(lastChange.author); + if (!lastAuthor.getPreferences().isEmailMeOnMyTicketChanges()) { + toAddresses.remove(lastAuthor.emailAddress); + ccAddresses.remove(lastAuthor.emailAddress); + } + + mailing.setRecipients(toAddresses); mailing.setCCs(ccAddresses); } diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties index 90d30f29..c80d45ce 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties @@ -728,6 +728,8 @@ gb.accountPreferences = Account Preferences gb.accountPreferencesDescription = Specify your account preferences gb.languagePreference = Language Preference gb.languagePreferenceDescription = Select your preferred translation for Gitblit +gb.emailMeOnMyTicketChanges = Email me on my ticket changes +gb.emailMeOnMyTicketChangesDescription = Send me an email notification for changes that I make to a ticket gb.displayNameDescription = The preferred name for display gb.emailAddressDescription = The primary email address for receiving notifications gb.sshKeys = SSH Keys diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.html b/src/main/java/com/gitblit/wicket/pages/UserPage.html index d71cb2b5..017fcb1f 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.html +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.html @@ -64,7 +64,8 @@
    -
    +
    +
    diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.java b/src/main/java/com/gitblit/wicket/pages/UserPage.java index 94048963..505f55d9 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.java +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.java @@ -48,6 +48,7 @@ import com.gitblit.wicket.GitBlitWebApp; import com.gitblit.wicket.GitBlitWebSession; import com.gitblit.wicket.GitblitRedirectException; import com.gitblit.wicket.WicketUtils; +import com.gitblit.wicket.panels.BooleanOption; import com.gitblit.wicket.panels.ChoiceOption; import com.gitblit.wicket.panels.ProjectRepositoryPanel; import com.gitblit.wicket.panels.SshKeysPanel; @@ -219,6 +220,7 @@ public class UserPage extends RootPage { final IModel displayName = Model.of(user.getDisplayName()); final IModel emailAddress = Model.of(user.emailAddress == null ? "" : user.emailAddress); final IModel language = Model.of(preferredLanguage); + final IModel emailMeOnMyTicketChanges = Model.of(user.getPreferences().isEmailMeOnMyTicketChanges()); prefs.add(new TextOption("displayName", getString("gb.displayName"), @@ -236,6 +238,11 @@ public class UserPage extends RootPage { language, languages)); + prefs.add(new BooleanOption("emailMeOnMyTicketChanges", + getString("gb.emailMeOnMyTicketChanges"), + getString("gb.emailMeOnMyTicketChangesDescription"), + emailMeOnMyTicketChanges).setVisible(app().notifier().isSendingMail())); + prefs.add(new AjaxButton("save") { private static final long serialVersionUID = 1L; @@ -253,6 +260,8 @@ public class UserPage extends RootPage { user.getPreferences().setLocale(lang.code); } + user.getPreferences().setEmailMeOnMyTicketChanges(emailMeOnMyTicketChanges.getObject()); + try { app().gitblit().reviseUser(user.username, user); -- cgit v1.2.3 From b0658eedf4bc1590cd5003d17d9c71dd47b3c70c Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 5 Jun 2014 11:22:44 -0400 Subject: Use AJAX to manage the SSH keys panel --- .../java/com/gitblit/wicket/pages/UserPage.java | 2 +- .../com/gitblit/wicket/panels/SshKeysPanel.java | 46 +++++++++++++--------- 2 files changed, 28 insertions(+), 20 deletions(-) (limited to 'src/main/java/com') diff --git a/src/main/java/com/gitblit/wicket/pages/UserPage.java b/src/main/java/com/gitblit/wicket/pages/UserPage.java index 505f55d9..00a36272 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.java +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.java @@ -283,7 +283,7 @@ public class UserPage extends RootPage { private void addSshKeys(final UserModel user) { Fragment keysTab = new Fragment("sshKeysTab", "sshKeysTabFragment", this); - keysTab.add(new SshKeysPanel("sshKeysPanel", user, getClass(), getPageParameters())); + keysTab.add(new SshKeysPanel("sshKeysPanel", user)); // add the SSH keys tab add(new Fragment("sshKeysLink", "sshKeysLinkFragment", this).setRenderBodyOnly(true)); diff --git a/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java index 03cb93ca..15ebd67b 100644 --- a/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java +++ b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java @@ -15,16 +15,15 @@ */ package com.gitblit.wicket.panels; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.apache.wicket.PageParameters; import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.ajax.markup.html.form.AjaxButton; -import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; @@ -39,7 +38,7 @@ import com.gitblit.wicket.GitBlitWebSession; /** - * A panel that enumerates and manages SSH public keys. + * A panel that enumerates and manages SSH public keys using AJAX. * * @author James Moger * @@ -50,25 +49,21 @@ public class SshKeysPanel extends BasePanel { private final UserModel user; - private final Class pageClass; - - private final PageParameters params; - - public SshKeysPanel(String wicketId, UserModel user, Class pageClass, PageParameters params) { + public SshKeysPanel(String wicketId, UserModel user) { super(wicketId); this.user = user; - this.pageClass = pageClass; - this.params = params; } @Override protected void onInitialize() { super.onInitialize(); - List keys = app().keys().getKeys(user.username); + setOutputMarkupId(true); + + final List keys = new ArrayList(app().keys().getKeys(user.username)); final ListDataProvider dp = new ListDataProvider(keys); - DataView keysView = new DataView("keys", dp) { + final DataView keysView = new DataView("keys", dp) { private static final long serialVersionUID = 1L; @Override @@ -79,15 +74,19 @@ public class SshKeysPanel extends BasePanel { item.add(new Label("permission", key.getPermission().toString())); item.add(new Label("algorithm", key.getAlgorithm())); - Link delete = new Link("delete") { + AjaxLink delete = new AjaxLink("delete") { private static final long serialVersionUID = 1L; @Override - public void onClick() { + public void onClick(AjaxRequestTarget target) { if (app().keys().removeKey(user.username, key)) { - setRedirect(true); - setResponsePage(pageClass, params); + // reset the keys list + keys.clear(); + keys.addAll(app().keys().getKeys(user.username)); + + // update the panel + target.addComponent(SshKeysPanel.this); } } }; @@ -150,8 +149,17 @@ public class SshKeysPanel extends BasePanel { } if (app().keys().addKey(user.username, key)) { - setRedirect(true); - setResponsePage(pageClass, params); + // reset add key fields + keyData.setObject(""); + keyPermission.setObject(AccessPermission.PUSH); + keyComment.setObject(""); + + // reset the keys list + keys.clear(); + keys.addAll(app().keys().getKeys(user.username)); + + // update the panel + target.addComponent(SshKeysPanel.this); } } }); -- cgit v1.2.3