James Moger
2015-11-22 ed552ba47c02779c270ffd62841d6d1048dade70
commit | author | age
1e1b85 1 /*
JM 2  * Copyright 2012 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.wicket.pages;
17
c9921b 18 import java.io.Serializable;
1e1b85 19 import java.util.ArrayList;
c9921b 20 import java.util.Arrays;
1e1b85 21 import java.util.Collections;
JM 22 import java.util.Comparator;
23 import java.util.List;
c9921b 24 import java.util.Locale;
1e1b85 25
JM 26 import org.apache.wicket.PageParameters;
c9921b 27 import org.apache.wicket.ajax.AjaxRequestTarget;
JM 28 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
1e1b85 29 import org.apache.wicket.markup.html.basic.Label;
c9921b 30 import org.apache.wicket.markup.html.form.Form;
JM 31 import org.apache.wicket.markup.html.panel.Fragment;
1e1b85 32 import org.apache.wicket.markup.repeater.Item;
JM 33 import org.apache.wicket.markup.repeater.data.DataView;
34 import org.apache.wicket.markup.repeater.data.ListDataProvider;
c9921b 35 import org.apache.wicket.model.IModel;
JM 36 import org.apache.wicket.model.Model;
1e1b85 37
1b04d7 38 import com.gitblit.Constants.Transport;
c9921b 39 import com.gitblit.GitBlitException;
1e1b85 40 import com.gitblit.Keys;
856f3f 41 import com.gitblit.models.Menu.ParameterMenuItem;
7a401a 42 import com.gitblit.models.NavLink;
0047fb 43 import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
1e1b85 44 import com.gitblit.models.ProjectModel;
JM 45 import com.gitblit.models.RepositoryModel;
46 import com.gitblit.models.UserModel;
47 import com.gitblit.utils.StringUtils;
48 import com.gitblit.wicket.GitBlitWebApp;
49 import com.gitblit.wicket.GitBlitWebSession;
9bdf88 50 import com.gitblit.wicket.GitblitRedirectException;
1e1b85 51 import com.gitblit.wicket.WicketUtils;
afbaeb 52 import com.gitblit.wicket.panels.BooleanOption;
c9921b 53 import com.gitblit.wicket.panels.ChoiceOption;
1e1b85 54 import com.gitblit.wicket.panels.ProjectRepositoryPanel;
05f229 55 import com.gitblit.wicket.panels.SshKeysPanel;
c9921b 56 import com.gitblit.wicket.panels.TextOption;
JM 57 import com.gitblit.wicket.panels.UserTitlePanel;
1e1b85 58
JM 59 public class UserPage extends RootPage {
699e71 60
1e1b85 61     List<ProjectModel> projectModels = new ArrayList<ProjectModel>();
JM 62
63     public UserPage() {
64         super();
9bdf88 65         throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
1e1b85 66     }
JM 67
68     public UserPage(PageParameters params) {
69         super(params);
70         setup(params);
71     }
72
73     @Override
74     protected boolean reusePageParameters() {
75         return true;
76     }
77
78     private void setup(PageParameters params) {
79         setupPage("", "");
80         // check to see if we should display a login message
99d0d4 81         boolean authenticateView = app().settings().getBoolean(Keys.web.authenticateViewPages, true);
1e1b85 82         if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {
JM 83             authenticationError("Please login");
84             return;
85         }
86
87         String userName = WicketUtils.getUsername(params);
88         if (StringUtils.isEmpty(userName)) {
9bdf88 89             throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
1e1b85 90         }
JM 91
99d0d4 92         UserModel user = app().users().getUserModel(userName);
1e1b85 93         if (user == null) {
JM 94             // construct a temporary user model
95             user = new UserModel(userName);
96         }
699e71 97
JM 98
c9921b 99         add(new UserTitlePanel("userTitlePanel", user, user.username));
699e71 100
6662e3 101         UserModel sessionUser = GitBlitWebSession.get().getUser();
c9921b 102         boolean isMyProfile = sessionUser != null && sessionUser.equals(user);
JM 103
104         if (isMyProfile) {
105             addPreferences(user);
05f229 106
7d3a31 107             if (app().services().isServingSSH()) {
05f229 108                 // show the SSH key management tab
JM 109                 addSshKeys(user);
110             } else {
111                 // SSH daemon is disabled, hide keys tab
112                 add(new Label("sshKeysLink").setVisible(false));
113                 add(new Label("sshKeysTab").setVisible(false));
114             }
6662e3 115         } else {
c9921b 116             // visiting user
JM 117             add(new Label("preferencesLink").setVisible(false));
118             add(new Label("preferencesTab").setVisible(false));
05f229 119
JM 120             add(new Label("sshKeysLink").setVisible(false));
121             add(new Label("sshKeysTab").setVisible(false));
6662e3 122         }
699e71 123
1e1b85 124         List<RepositoryModel> repositories = getRepositories(params);
699e71 125
1e1b85 126         Collections.sort(repositories, new Comparator<RepositoryModel>() {
JM 127             @Override
128             public int compare(RepositoryModel o1, RepositoryModel o2) {
129                 // reverse-chronological sort
130                 return o2.lastChange.compareTo(o1.lastChange);
131             }
132         });
133
134         final ListDataProvider<RepositoryModel> dp = new ListDataProvider<RepositoryModel>(repositories);
135         DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("repositoryList", dp) {
136             private static final long serialVersionUID = 1L;
137
699e71 138             @Override
1e1b85 139             public void populateItem(final Item<RepositoryModel> item) {
JM 140                 final RepositoryModel entry = item.getModelObject();
699e71 141
JM 142                 ProjectRepositoryPanel row = new ProjectRepositoryPanel("repository",
1e1b85 143                         getLocalizer(), this, showAdmin, entry, getAccessRestrictions());
JM 144                 item.add(row);
145             }
146         };
147         add(dataView);
148     }
149
150     @Override
7a401a 151     protected void addDropDownMenus(List<NavLink> navLinks) {
1e1b85 152         PageParameters params = getPageParameters();
JM 153
7a401a 154         DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
1e1b85 155                 UserPage.class);
JM 156         // preserve time filter option on repository choices
157         menu.menuItems.addAll(getRepositoryFilterItems(params));
158
159         // preserve repository filter option on time choices
160         menu.menuItems.addAll(getTimeFilterItems(params));
161
162         if (menu.menuItems.size() > 0) {
163             // Reset Filter
856f3f 164             menu.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
1e1b85 165         }
JM 166
7a401a 167         navLinks.add(menu);
1e1b85 168     }
c9921b 169
JM 170     private void addPreferences(UserModel user) {
171         // add preferences
172         Form<Void> prefs = new Form<Void>("prefsForm");
173
174         List<Language> languages = Arrays.asList(
13dd75 175                 new Language("Deutsch","de"),
c9921b 176                 new Language("English","en"),
JM 177                 new Language("Español", "es"),
178                 new Language("Français", "fr"),
5881c4 179                 new Language("Italiano", "it"),
c9921b 180                 new Language("日本語", "ja"),
JM 181                 new Language("한국말", "ko"),
182                 new Language("Nederlands", "nl"),
183                 new Language("Norsk", "no"),
184                 new Language("Język Polski", "pl"),
185                 new Language("Português", "pt_BR"),
25e1a6 186                 new Language("簡體中文", "zh_CN"),
JM 187                 new Language("正體中文", "zh_TW"));
c9921b 188
6537de 189         Locale locale = user.getPreferences().getLocale();
JM 190         if (locale == null) {
c9921b 191             // user has not specified language preference
JM 192             // try server default preference
6537de 193             String lc = app().settings().getString(Keys.web.forceDefaultLocale, null);
c9921b 194             if (StringUtils.isEmpty(lc)) {
JM 195                 // server default language is not configured
196                 // try browser preference
197                 Locale sessionLocale = GitBlitWebSession.get().getLocale();
198                 if (sessionLocale != null) {
6537de 199                     locale = sessionLocale;
c9921b 200                 }
6537de 201             } else {
JM 202
c9921b 203             }
JM 204         }
6537de 205
c9921b 206         Language preferredLanguage = null;
6537de 207         if (locale != null) {
JM 208             String localeCode = locale.getLanguage();
209             if (!StringUtils.isEmpty(locale.getCountry())) {
210                 localeCode += "_" + locale.getCountry();
211             }
212
c9921b 213             for (Language language : languages) {
6537de 214                 if (language.code.equals(localeCode)) {
c9921b 215                     // language_COUNTRY match
JM 216                     preferredLanguage = language;
6537de 217                 } else if (preferredLanguage != null && language.code.startsWith(locale.getLanguage())) {
JM 218                     // language match
c9921b 219                     preferredLanguage = language;
JM 220                 }
221             }
222         }
223
224         final IModel<String> displayName = Model.of(user.getDisplayName());
225         final IModel<String> emailAddress = Model.of(user.emailAddress == null ? "" : user.emailAddress);
226         final IModel<Language> language = Model.of(preferredLanguage);
afbaeb 227         final IModel<Boolean> emailMeOnMyTicketChanges = Model.of(user.getPreferences().isEmailMeOnMyTicketChanges());
1b04d7 228         final IModel<Transport> transport = Model.of(user.getPreferences().getTransport());
c9921b 229
JM 230         prefs.add(new TextOption("displayName",
231                 getString("gb.displayName"),
232                 getString("gb.displayNameDescription"),
233                 displayName).setVisible(app().authentication().supportsDisplayNameChanges(user)));
234
235         prefs.add(new TextOption("emailAddress",
236                 getString("gb.emailAddress"),
237                 getString("gb.emailAddressDescription"),
238                 emailAddress).setVisible(app().authentication().supportsEmailAddressChanges(user)));
239
240         prefs.add(new ChoiceOption<Language>("language",
241                 getString("gb.languagePreference"),
242                 getString("gb.languagePreferenceDescription"),
243                 language,
244                 languages));
245
afbaeb 246         prefs.add(new BooleanOption("emailMeOnMyTicketChanges",
JM 247                 getString("gb.emailMeOnMyTicketChanges"),
248                 getString("gb.emailMeOnMyTicketChangesDescription"),
249                 emailMeOnMyTicketChanges).setVisible(app().notifier().isSendingMail()));
250
1b04d7 251         List<Transport> availableTransports = new ArrayList<>();
7d3a31 252         if (app().services().isServingSSH()) {
1b04d7 253             availableTransports.add(Transport.SSH);
JM 254         }
7d3a31 255         if (app().services().isServingHTTP()) {
1b04d7 256             availableTransports.add(Transport.HTTP);
JM 257         }
67ba8f 258         if (app().services().isServingHTTPS()) {
JM 259             availableTransports.add(Transport.HTTPS);
260         }
7d3a31 261         if (app().services().isServingGIT()) {
1b04d7 262             availableTransports.add(Transport.GIT);
JM 263         }
264
265         prefs.add(new ChoiceOption<Transport>("transport",
266                 getString("gb.transportPreference"),
267                 getString("gb.transportPreferenceDescription"),
268                 transport,
269                 availableTransports));
270
c9921b 271         prefs.add(new AjaxButton("save") {
JM 272
273             private static final long serialVersionUID = 1L;
274
275             @Override
276             protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
277
278                 UserModel user = GitBlitWebSession.get().getUser();
279
280                 user.displayName = displayName.getObject();
281                 user.emailAddress = emailAddress.getObject();
282
283                 Language lang = language.getObject();
284                 if (lang != null) {
6537de 285                     user.getPreferences().setLocale(lang.code);
c9921b 286                 }
JM 287
afbaeb 288                 user.getPreferences().setEmailMeOnMyTicketChanges(emailMeOnMyTicketChanges.getObject());
1b04d7 289                 user.getPreferences().setTransport(transport.getObject());
afbaeb 290
c9921b 291                 try {
JM 292                     app().gitblit().reviseUser(user.username, user);
293
294                     setRedirect(true);
295                     setResponsePage(UserPage.class, WicketUtils.newUsernameParameter(user.username));
296                 } catch (GitBlitException e) {
297                     // logger.error("Failed to update user " + user.username, e);
298                     // error(getString("gb.failedToUpdateUser"), false);
299                 }
300             }
301         });
302
303         // add the preferences tab
304         add(new Fragment("preferencesLink", "preferencesLinkFragment", this).setRenderBodyOnly(true));
305         Fragment fragment = new Fragment("preferencesTab", "preferencesTabFragment", this);
306         fragment.add(prefs);
307         add(fragment.setRenderBodyOnly(true));
308     }
309
05f229 310     private void addSshKeys(final UserModel user) {
JM 311         Fragment keysTab = new Fragment("sshKeysTab", "sshKeysTabFragment", this);
b0658e 312         keysTab.add(new SshKeysPanel("sshKeysPanel", user));
05f229 313
JM 314         // add the SSH keys tab
315         add(new Fragment("sshKeysLink", "sshKeysLinkFragment", this).setRenderBodyOnly(true));
316         add(keysTab.setRenderBodyOnly(true));
317     }
318
c9921b 319     private class Language implements Serializable {
JM 320
321         private static final long serialVersionUID = 1L;
322
323         final String name;
324         final String code;
325
326         public Language(String name, String code) {
327             this.name = name;
328             this.code = code;
329         }
330
331         @Override
332         public String toString() {
333             return name + " (" + code +")";
334         }
335     }
1e1b85 336 }