blob: 306eea65deb0bd367b5de45d3c0d385c8330215a [file] [log] [blame]
/*
* Copyright 2012 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.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.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.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
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;
import com.gitblit.utils.StringUtils;
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;
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() {
super();
throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
}
public UserPage(PageParameters params) {
super(params);
setup(params);
}
@Override
protected boolean reusePageParameters() {
return true;
}
private void setup(PageParameters params) {
setupPage("", "");
// check to see if we should display a login message
boolean authenticateView = app().settings().getBoolean(Keys.web.authenticateViewPages, true);
if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {
authenticationError("Please login");
return;
}
String userName = WicketUtils.getUsername(params);
if (StringUtils.isEmpty(userName)) {
throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
}
UserModel user = app().users().getUserModel(userName);
if (user == null) {
// construct a temporary user model
user = new UserModel(userName);
}
add(new UserTitlePanel("userTitlePanel", user, user.username));
UserModel sessionUser = GitBlitWebSession.get().getUser();
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 {
// 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) {
// reverse-chronological sort
return o2.lastChange.compareTo(o1.lastChange);
}
});
final ListDataProvider<RepositoryModel> dp = new ListDataProvider<RepositoryModel>(repositories);
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",
getLocalizer(), this, showAdmin, entry, getAccessRestrictions());
item.add(row);
}
};
add(dataView);
}
@Override
protected void addDropDownMenus(List<NavLink> navLinks) {
PageParameters params = getPageParameters();
DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
UserPage.class);
// preserve time filter option on repository choices
menu.menuItems.addAll(getRepositoryFilterItems(params));
// preserve repository filter option on time choices
menu.menuItems.addAll(getTimeFilterItems(params));
if (menu.menuItems.size() > 0) {
// Reset Filter
menu.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
}
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());
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().gitblit().isServingSSH()) {
availableTransports.add(Transport.SSH);
}
if (app().gitblit().isServingHTTP()) {
availableTransports.add(Transport.HTTPS);
availableTransports.add(Transport.HTTP);
}
if (app().gitblit().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 +")";
}
}
}