Paul Martin
2016-04-30 a502d96a860456ec5e8c96761db70f7cabb74751
src/main/java/com/gitblit/wicket/pages/UserPage.java
@@ -15,21 +15,32 @@
 */
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.GitBlit;
import com.gitblit.Constants.Transport;
import com.gitblit.GitBlitException;
import com.gitblit.Keys;
import com.gitblit.models.Menu.ParameterMenuItem;
import com.gitblit.models.NavLink;
import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
@@ -37,16 +48,16 @@
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException;
import com.gitblit.wicket.PageRegistration;
import com.gitblit.wicket.PageRegistration.DropDownMenuItem;
import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
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 {
   List<ProjectModel> projectModels = new ArrayList<ProjectModel>();
   public UserPage() {
@@ -67,7 +78,7 @@
   private void setup(PageParameters params) {
      setupPage("", "");
      // check to see if we should display a login message
      boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true);
      boolean authenticateView = app().settings().getBoolean(Keys.web.authenticateViewPages, true);
      if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {
         authenticationError("Please login");
         return;
@@ -78,38 +89,40 @@
         throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
      }
      UserModel user = GitBlit.self().getUserModel(userName);
      UserModel user = app().users().getUserModel(userName);
      if (user == null) {
         // construct a temporary user model
         user = new UserModel(userName);
      }
      String projectName = user.getPersonalPath();
      ProjectModel project = GitBlit.self().getProjectModel(projectName);
      if (project == null) {
         project = new ProjectModel(projectName);
      }
      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(GitBlit.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", EditRepositoryPage.class));
      boolean isMyProfile = sessionUser != null && sessionUser.equals(user);
      if (isMyProfile) {
         addPreferences(user);
         if (app().services().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);
      Collections.sort(repositories, new Comparator<RepositoryModel>() {
         @Override
         public int compare(RepositoryModel o1, RepositoryModel o2) {
@@ -122,10 +135,11 @@
      DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("repositoryList", dp) {
         private static final long serialVersionUID = 1L;
         @Override
         public void populateItem(final Item<RepositoryModel> item) {
            final RepositoryModel entry = item.getModelObject();
            ProjectRepositoryPanel row = new ProjectRepositoryPanel("repository",
            ProjectRepositoryPanel row = new ProjectRepositoryPanel("repository",
                  getLocalizer(), this, showAdmin, entry, getAccessRestrictions());
            item.add(row);
         }
@@ -134,10 +148,10 @@
   }
   @Override
   protected void addDropDownMenus(List<PageRegistration> pages) {
   protected void addDropDownMenus(List<NavLink> navLinks) {
      PageParameters params = getPageParameters();
      DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",
      DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
            UserPage.class);
      // preserve time filter option on repository choices
      menu.menuItems.addAll(getRepositoryFilterItems(params));
@@ -147,9 +161,176 @@
      if (menu.menuItems.size() > 0) {
         // Reset Filter
         menu.menuItems.add(new DropDownMenuItem(getString("gb.reset"), null, null));
         menu.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
      }
      pages.add(menu);
      navLinks.add(menu);
   }
   private void addPreferences(UserModel user) {
      // add preferences
      Form<Void> prefs = new Form<Void>("prefsForm");
      List<Language> languages = Arrays.asList(
            new Language("Deutsch","de"),
            new Language("English","en"),
            new Language("Español", "es"),
            new Language("Français", "fr"),
            new Language("Italiano", "it"),
            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"),
            new Language("正體中文", "zh_TW"));
      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());
      final IModel<Transport> transport = Model.of(user.getPreferences().getTransport());
      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()));
      List<Transport> availableTransports = new ArrayList<>();
      if (app().services().isServingSSH()) {
         availableTransports.add(Transport.SSH);
      }
      if (app().services().isServingHTTP()) {
         availableTransports.add(Transport.HTTP);
      }
      if (app().services().isServingHTTPS()) {
         availableTransports.add(Transport.HTTPS);
      }
      if (app().services().isServingGIT()) {
         availableTransports.add(Transport.GIT);
      }
      prefs.add(new ChoiceOption<Transport>("transport",
            getString("gb.transportPreference"),
            getString("gb.transportPreferenceDescription"),
            transport,
            availableTransports));
      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());
            user.getPreferences().setTransport(transport.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 +")";
      }
   }
}