diff options
author | James Moger <james.moger@gitblit.com> | 2014-06-05 09:29:22 -0600 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2014-06-05 09:29:22 -0600 |
commit | 1984375641fe0880f64e378e8116ca433b28dac2 (patch) | |
tree | cb28d4acf61c2d75f591603b25c7299dd6b4da22 /src/main/java | |
parent | 004bc1af52013eeaa9d9a02eac3381daf05bef89 (diff) | |
parent | c7796ebac77a30c91e61ca474f63e8f181f6e1be (diff) | |
download | gitblit-1984375641fe0880f64e378e8116ca433b28dac2.tar.gz gitblit-1984375641fe0880f64e378e8116ca433b28dac2.zip |
Merged #64 "Editable user profile page"
Diffstat (limited to 'src/main/java')
23 files changed, 706 insertions, 50 deletions
diff --git a/src/main/java/com/gitblit/ConfigUserService.java b/src/main/java/com/gitblit/ConfigUserService.java index 9b4dd7f1..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";
@@ -707,9 +709,11 @@ 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);
}
+ config.setBoolean(USER, model.username, EMAILONMYTICKETCHANGES, model.getPreferences().isEmailMeOnMyTicketChanges());
}
// user roles
@@ -880,11 +884,14 @@ 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.getPreferences().setEmailMeOnMyTicketChanges(config.getBoolean(USER, username, EMAILONMYTICKETCHANGES, true));
+
// user roles
Set<String> roles = new HashSet<String>(Arrays.asList(config.getStringList(
USER, username, ROLE)));
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 @@ -166,6 +166,11 @@ public class FederationClient { }
@Override
+ public boolean isSendingMail() {
+ return false;
+ }
+
+ @Override
public void sendMailToAdministrators(String subject, String message) {
}
diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java index 3db5f087..81793850 100644 --- a/src/main/java/com/gitblit/GitBlit.java +++ b/src/main/java/com/gitblit/GitBlit.java @@ -117,6 +117,21 @@ public class GitBlit extends GitblitManager { return servicesManager.isServingRepositories(); } + @Override + public boolean isServingHTTP() { + return servicesManager.isServingHTTP(); + } + + @Override + public boolean isServingGIT() { + return servicesManager.isServingGIT(); + } + + @Override + public boolean isServingSSH() { + return servicesManager.isServingSSH(); + } + protected Object [] getModules() { return new Object [] { new GitBlitModule()}; } diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index 16c71ba6..98ad33e7 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -602,6 +602,21 @@ public class GitblitManager implements IGitblit { } @Override + public boolean isServingHTTP() { + return runtimeManager.isServingHTTP(); + } + + @Override + public boolean isServingGIT() { + return runtimeManager.isServingGIT(); + } + + @Override + public boolean isServingSSH() { + return runtimeManager.isServingSSH(); + } + + @Override public TimeZone getTimezone() { return runtimeManager.getTimezone(); } @@ -646,6 +661,11 @@ public class GitblitManager implements IGitblit { */ @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 @@ -22,6 +22,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. * * @param subject diff --git a/src/main/java/com/gitblit/manager/IRuntimeManager.java b/src/main/java/com/gitblit/manager/IRuntimeManager.java index 29e7368f..b2d7a2b3 100644 --- a/src/main/java/com/gitblit/manager/IRuntimeManager.java +++ b/src/main/java/com/gitblit/manager/IRuntimeManager.java @@ -57,6 +57,33 @@ public interface IRuntimeManager extends IManager { boolean isServingRepositories(); /** + * Determine if this Gitblit instance is actively serving git repositories + * over HTTP. + * + * @return true if Gitblit is serving repositories over HTTP + * @since 1.6.0 + */ + boolean isServingHTTP(); + + /** + * Determine if this Gitblit instance is actively serving git repositories + * over the GIT Daemon protocol. + * + * @return true if Gitblit is serving repositories over the GIT Daemon protocol + * @since 1.6.0 + */ + boolean isServingGIT(); + + /** + * Determine if this Gitblit instance is actively serving git repositories + * over the SSH protocol. + * + * @return true if Gitblit is serving repositories over the SSH protocol + * @since 1.6.0 + */ + boolean isServingSSH(); + + /** * Determine if this Gitblit instance is running in debug mode * * @return true if Gitblit is running in debug mode 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. * diff --git a/src/main/java/com/gitblit/manager/RuntimeManager.java b/src/main/java/com/gitblit/manager/RuntimeManager.java index 52f4d67b..9cdc64eb 100644 --- a/src/main/java/com/gitblit/manager/RuntimeManager.java +++ b/src/main/java/com/gitblit/manager/RuntimeManager.java @@ -119,9 +119,42 @@ public class RuntimeManager implements IRuntimeManager { */ @Override public boolean isServingRepositories() { - return settings.getBoolean(Keys.git.enableGitServlet, true) - || (settings.getInteger(Keys.git.daemonPort, 0) > 0) - || (settings.getInteger(Keys.git.sshPort, 0) > 0); + return isServingHTTP() + || isServingGIT() + || isServingSSH(); + } + + /** + * Determine if this Gitblit instance is actively serving git repositories + * over the HTTP protocol. + * + * @return true if Gitblit is serving repositories over the HTTP protocol + */ + @Override + public boolean isServingHTTP() { + return settings.getBoolean(Keys.git.enableGitServlet, true); + } + + /** + * Determine if this Gitblit instance is actively serving git repositories + * over the Git Daemon protocol. + * + * @return true if Gitblit is serving repositories over the Git Daemon protocol + */ + @Override + public boolean isServingGIT() { + return settings.getInteger(Keys.git.daemonPort, 0) > 0; + } + + /** + * Determine if this Gitblit instance is actively serving git repositories + * over the SSH protocol. + * + * @return true if Gitblit is serving repositories over the SSH protocol + */ + @Override + public boolean isServingSSH() { + return settings.getInteger(Keys.git.sshPort, 0) > 0; } /** diff --git a/src/main/java/com/gitblit/manager/ServicesManager.java b/src/main/java/com/gitblit/manager/ServicesManager.java index 755d8bac..37215786 100644 --- a/src/main/java/com/gitblit/manager/ServicesManager.java +++ b/src/main/java/com/gitblit/manager/ServicesManager.java @@ -112,9 +112,21 @@ public class ServicesManager implements IManager { } public boolean isServingRepositories() { - return settings.getBoolean(Keys.git.enableGitServlet, true) - || (gitDaemon != null && gitDaemon.isRunning()) - || (sshDaemon != null && sshDaemon.isRunning()); + return isServingHTTP() + || isServingGIT() + || isServingSSH(); + } + + public boolean isServingHTTP() { + return settings.getBoolean(Keys.git.enableGitServlet, true); + } + + public boolean isServingGIT() { + return gitDaemon != null && gitDaemon.isRunning(); + } + + public boolean isServingSSH() { + return sshDaemon != null && sshDaemon.isRunning(); } protected void configureFederation() { diff --git a/src/main/java/com/gitblit/models/UserPreferences.java b/src/main/java/com/gitblit/models/UserPreferences.java index 44e44933..c95b0da5 100644 --- a/src/main/java/com/gitblit/models/UserPreferences.java +++ b/src/main/java/com/gitblit/models/UserPreferences.java @@ -37,7 +37,9 @@ public class UserPreferences implements Serializable { public final String username; - public String locale; + private String locale; + + private Boolean emailMeOnMyTicketChanges; private final Map<String, UserRepositoryPreferences> repositoryPreferences = new TreeMap<String, UserRepositoryPreferences>(); @@ -58,6 +60,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)) { @@ -96,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 d6fd57e9..c80d45ce 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties @@ -722,4 +722,21 @@ 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 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 +gb.sshKeysDescription = SSH public key authentication is a secure alternative to password authentication +gb.addSshKey = Add SSH Key +gb.key = Key +gb.comment = Comment +gb.sshKeyCommentDescription = Enter an optional comment. If blank, the comment will be extracted from the key data. +gb.permission = Permission +gb.sshKeyPermissionDescription = Specify the access permission for the SSH key
\ 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..017fcb1f 100644 --- a/src/main/java/com/gitblit/wicket/pages/UserPage.html +++ b/src/main/java/com/gitblit/wicket/pages/UserPage.html @@ -7,27 +7,20 @@ <body>
<wicket:extend>
<div class="container">
- <div class="row" style="padding-top:10px;">
- <div class="span4">
- <div wicket:id="gravatar"></div>
- <div style="text-align: left;">
- <h2><span wicket:id="userDisplayName"></span></h2>
- <div><i class="icon-user"></i> <span wicket:id="userUsername"></span></div>
- <div><i class="icon-envelope"></i><span wicket:id="userEmail"></span></div>
- </div>
+ <div class="row" style="padding-top:15px;">
+ <div class="span3">
+ <div wicket:id="userTitlePanel"></div>
</div>
-
- <div class="span8">
- <div class="pull-right">
- <a class="btn-small" wicket:id="newRepository" style="padding-right:0px;">
- <i class="icon icon-plus-sign"></i>
- <wicket:message key="gb.newRepository"></wicket:message>
- </a>
- </div>
- <div class="tabbable">
+ </div>
+
+ <div class="row" style="padding-top:10px;">
+ <div class="span12">
+ <div class="tabbable tabs-left">
<!-- tab titles -->
<ul class="nav nav-tabs">
<li class="active"><a href="#repositories" data-toggle="tab"><wicket:message key="gb.repositories"></wicket:message></a></li>
+ <div wicket:id="preferencesLink"></div>
+ <div wicket:id="sshKeysLink"></div>
</ul>
<!-- tab content -->
@@ -41,11 +34,50 @@ </tbody>
</table>
</div>
+
+ <!-- preferences tab -->
+ <div wicket:id="preferencesTab"></div>
+
+ <!-- ssh keys tab -->
+ <div wicket:id="sshKeysTab"></div>
+
</div>
</div>
</div>
</div>
</div>
+
+<wicket:fragment wicket:id="preferencesLinkFragment">
+ <li><a href="#preferences" data-toggle="tab"><wicket:message key="gb.preferences"></wicket:message></a></li>
+</wicket:fragment>
+
+<wicket:fragment wicket:id="sshKeysLinkFragment">
+ <li><a href="#ssh" data-toggle="tab"><wicket:message key="gb.sshKeys"></wicket:message></a></li>
+</wicket:fragment>
+
+<wicket:fragment wicket:id="preferencesTabFragment">
+ <div class="tab-pane" id="preferences">
+ <h4><wicket:message key="gb.accountPreferences"></wicket:message></h4>
+ <p><wicket:message key="gb.accountPreferencesDescription"></wicket:message></p>
+ <hr />
+
+ <form wicket:id="prefsForm">
+ <div wicket:id="displayName"></div>
+ <div wicket:id="emailAddress"></div>
+ <div wicket:id="language"></div>
+ <div wicket:id="emailMeOnMyTicketChanges"></div>
+
+ <div class="form-actions"><input class="btn btn-appmenu" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" /></div>
+ </form>
+ </div>
+</wicket:fragment>
+
+<wicket:fragment wicket:id="sshKeysTabFragment">
+ <div class="tab-pane" id="ssh">
+ <div wicket:id="sshKeysPanel"></div>
+ </div>
+</wicket:fragment>
+
</wicket:extend>
</body>
</html>
\ 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..00a36272 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,12 @@ 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.BooleanOption;
+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;
public class UserPage extends RootPage {
@@ -83,21 +94,30 @@ 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<Void>("newRepository", app().getNewRepositoryPage()));
+ boolean isMyProfile = sessionUser != null && sessionUser.equals(user);
+
+ 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 {
- add(new Label("newRepository").setVisible(false));
+ // 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<RepositoryModel> repositories = getRepositories(params);
@@ -145,4 +165,146 @@ public class UserPage extends RootPage { navLinks.add(menu);
}
+
+ private void addPreferences(UserModel user) {
+ // add preferences
+ Form<Void> prefs = new Form<Void>("prefsForm");
+
+ List<Language> 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"));
+
+ Locale locale = user.getPreferences().getLocale();
+ if (locale == null) {
+ // user has not specified language preference
+ // try server default preference
+ 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) {
+ locale = sessionLocale;
+ }
+ } else {
+
+ }
+ }
+
+ Language preferredLanguage = null;
+ if (locale != null) {
+ String localeCode = locale.getLanguage();
+ if (!StringUtils.isEmpty(locale.getCountry())) {
+ localeCode += "_" + locale.getCountry();
+ }
+
+ for (Language language : languages) {
+ if (language.code.equals(localeCode)) {
+ // language_COUNTRY match
+ preferredLanguage = language;
+ } else if (preferredLanguage != null && language.code.startsWith(locale.getLanguage())) {
+ // language match
+ preferredLanguage = language;
+ }
+ }
+ }
+
+ final IModel<String> displayName = Model.of(user.getDisplayName());
+ final IModel<String> emailAddress = Model.of(user.emailAddress == null ? "" : user.emailAddress);
+ final IModel<Language> language = Model.of(preferredLanguage);
+ final IModel<Boolean> emailMeOnMyTicketChanges = Model.of(user.getPreferences().isEmailMeOnMyTicketChanges());
+
+ 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>("language",
+ getString("gb.languagePreference"),
+ getString("gb.languagePreferenceDescription"),
+ 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;
+
+ @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().setLocale(lang.code);
+ }
+
+ user.getPreferences().setEmailMeOnMyTicketChanges(emailMeOnMyTicketChanges.getObject());
+
+ 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 void addSshKeys(final UserModel user) {
+ Fragment keysTab = new Fragment("sshKeysTab", "sshKeysTabFragment", this);
+ keysTab.add(new SshKeysPanel("sshKeysPanel", user));
+
+ // 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;
+
+ 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 @@ <div wicket:id="policiesGroup">
<div wicket:id="policies" style="padding-top:4px;">
<div>
- <label style="font-weight:bold;"><input type="radio" wicket:id="radio" /> <img wicket:id="image"></img> <span wicket:id="name"></span></label>
+ <label style="font-weight:bold;margin-bottom:1px;"><input type="radio" wicket:id="radio" /> <img wicket:id="image"></img> <span wicket:id="name"></span></label>
</div>
<label class="checkbox" style="color:#777;" wicket:id="description"></label>
</div>
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 @@ <wicket:panel>
<div style="padding-top:4px;">
<div>
- <label style="font-weight:bold;" class="checkbox"><input type="checkbox" wicket:id="checkbox" /> <span wicket:id="name"></span></label>
+ <label style="font-weight:bold;margin-bottom:1px;" class="checkbox"><input type="checkbox" wicket:id="checkbox" /> <span wicket:id="name"></span></label>
</div>
<label class="checkbox" style="color:#777;"> <span wicket:id="description"></span>
<p style="padding-top:5px;"><select class="span3" wicket:id="choice" /></p>
diff --git a/src/main/java/com/gitblit/wicket/panels/BooleanOption.html b/src/main/java/com/gitblit/wicket/panels/BooleanOption.html index 6684fe92..297cbd3b 100644 --- a/src/main/java/com/gitblit/wicket/panels/BooleanOption.html +++ b/src/main/java/com/gitblit/wicket/panels/BooleanOption.html @@ -8,7 +8,7 @@ <wicket:panel>
<div style="padding-top:4px;">
<div>
- <label style="font-weight:bold;" class="checkbox"><input type="checkbox" wicket:id="checkbox" /> <span wicket:id="name"></span></label>
+ <label style="font-weight:bold;margin-bottom:1px;" class="checkbox"><input type="checkbox" wicket:id="checkbox" /> <span wicket:id="name"></span></label>
</div>
<label class="checkbox" style="color:#777;" wicket:id="description"></label>
</div>
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 @@ <body>
<wicket:panel>
<div style="padding-top:4px;">
- <div>
+ <div style="margin-bottom:1px;">
<b><span wicket:id="name"></span></b>
</div>
<label class="checkbox" style="color:#777;"> <span wicket:id="description"></span>
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 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"
+ xml:lang="en"
+ lang="en">
+
+<body>
+<wicket:panel>
+ <h4><wicket:message key="gb.sshKeys"></wicket:message></h4>
+ <p><wicket:message key="gb.sshKeysDescription"></wicket:message></p>
+ <hr />
+
+ <div wicket:id="keys">
+ <div style="display:inline-block;font-size:2em;padding:10px;">
+ <i class="fa fa-key"></i>
+ </div>
+ <div style="display:inline-block;">
+ <div wicket:id="comment" style="font-weight:bold;"></div>
+ <pre wicket:id="fingerprint"></pre>
+ </div>
+
+ <div style="display:inline-block;padding: 0px 20px">
+ <div wicket:id="permission" style="font-weight:bold;"></div>
+ <div wicket:id="algorithm"></div>
+ </div>
+
+ <div style="display:inline-block;vertical-align:text-bottom;">
+ <button class="btn btn-danger" wicket:id="delete"><wicket:message key="gb.delete"></wicket:message></button>
+ </div>
+
+ <hr />
+ </div>
+
+ <div class="well">
+ <form wicket:id="addKeyForm">
+ <h4><wicket:message key="gb.addSshKey"></wicket:message></h4>
+ <div wicket:id="addKeyData"></div>
+ <div wicket:id="addKeyPermission"></div>
+ <div wicket:id="addKeyComment"></div>
+
+ <div class="form-actions"><input class="btn btn-appmenu" type="submit" value="Add" wicket:message="value:gb.add" wicket:id="addKeyButton" /></div>
+ </form>
+ </div>
+</wicket:panel>
+</body>
+</html>
\ 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..15ebd67b --- /dev/null +++ b/src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java @@ -0,0 +1,169 @@ +/*
+ * 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.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+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.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+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 using AJAX.
+ *
+ * @author James Moger
+ *
+ */
+public class SshKeysPanel extends BasePanel {
+
+ private static final long serialVersionUID = 1L;
+
+ private final UserModel user;
+
+ public SshKeysPanel(String wicketId, UserModel user) {
+ super(wicketId);
+
+ this.user = user;
+ }
+
+ @Override
+ protected void onInitialize() {
+ super.onInitialize();
+
+ setOutputMarkupId(true);
+
+ final List<SshKey> keys = new ArrayList<SshKey>(app().keys().getKeys(user.username));
+ final ListDataProvider<SshKey> dp = new ListDataProvider<SshKey>(keys);
+ final DataView<SshKey> keysView = new DataView<SshKey>("keys", dp) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void populateItem(final Item<SshKey> 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()));
+
+ AjaxLink<Void> delete = new AjaxLink<Void>("delete") {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onClick(AjaxRequestTarget target) {
+ if (app().keys().removeKey(user.username, key)) {
+ // reset the keys list
+ keys.clear();
+ keys.addAll(app().keys().getKeys(user.username));
+
+ // update the panel
+ target.addComponent(SshKeysPanel.this);
+ }
+ }
+ };
+ item.add(delete);
+ }
+ };
+ add(keysView);
+
+ Form<Void> addKeyForm = new Form<Void>("addKeyForm");
+
+ final IModel<String> keyData = Model.of("");
+ addKeyForm.add(new TextAreaOption("addKeyData",
+ getString("gb.key"),
+ null,
+ "span5",
+ keyData));
+
+ final IModel<AccessPermission> keyPermission = Model.of(AccessPermission.PUSH);
+ addKeyForm.add(new ChoiceOption<AccessPermission>("addKeyPermission",
+ getString("gb.permission"),
+ getString("gb.sshKeyPermissionDescription"),
+ keyPermission,
+ Arrays.asList(AccessPermission.SSHPERMISSIONS)));
+
+ final IModel<String> 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)) {
+ // 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);
+ }
+ }
+ });
+
+ 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 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"
+ xml:lang="en"
+ lang="en">
+
+<body>
+<wicket:panel>
+ <div style="padding-top:4px;">
+ <div style="margin-bottom:1px;">
+ <b><span wicket:id="name"></span></b>
+ </div>
+ <label class="checkbox" style="color:#777;"> <span wicket:id="description"></span>
+ <p style="padding-top:5px;"><textarea rows="12" class="span5" wicket:id="text"></textarea></p>
+ </label>
+
+ </div>
+</wicket:panel>
+</body>
+</html>
\ 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<String> model) {
+ this(wicketId, title, description, null, model);
+ }
+
+ public TextAreaOption(String wicketId, String title, String description, String css, IModel<String> model) {
+ super(wicketId);
+ add(new Label("name", title));
+ add(new Label("description", description).setVisible(!StringUtils.isEmpty(description)));
+ TextArea<String> tf = new TextArea<String>("text", model);
+ if (!StringUtils.isEmpty(css)) {
+ WicketUtils.setCssClass(tf, css);
+ }
+ add(tf);
+ }
+}
diff --git a/src/main/java/com/gitblit/wicket/panels/TextOption.html b/src/main/java/com/gitblit/wicket/panels/TextOption.html index 9fa0c700..d14da2b1 100644 --- a/src/main/java/com/gitblit/wicket/panels/TextOption.html +++ b/src/main/java/com/gitblit/wicket/panels/TextOption.html @@ -7,7 +7,7 @@ <body>
<wicket:panel>
<div style="padding-top:4px;">
- <div>
+ <div style="margin-bottom:1px;">
<b><span wicket:id="name"></span></b>
</div>
<label class="checkbox" style="color:#777;"> <span wicket:id="description"></span>
|