src/main/java/com/gitblit/GitBlit.java
@@ -117,6 +117,21 @@ 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()}; } src/main/java/com/gitblit/manager/GitblitManager.java
@@ -602,6 +602,21 @@ } @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(); } src/main/java/com/gitblit/manager/IRuntimeManager.java
@@ -57,6 +57,33 @@ 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 src/main/java/com/gitblit/manager/RuntimeManager.java
@@ -119,9 +119,42 @@ */ @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; } /** src/main/java/com/gitblit/manager/ServicesManager.java
@@ -112,9 +112,21 @@ } 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() { src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
@@ -730,3 +730,11 @@ 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 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 src/main/java/com/gitblit/wicket/pages/UserPage.html
@@ -20,6 +20,7 @@ <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 --> @@ -37,6 +38,9 @@ <!-- preferences tab --> <div wicket:id="preferencesTab"></div> <!-- ssh keys tab --> <div wicket:id="sshKeysTab"></div> </div> </div> </div> @@ -45,6 +49,10 @@ <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"> @@ -63,6 +71,12 @@ </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> src/main/java/com/gitblit/wicket/pages/UserPage.java
@@ -50,6 +50,7 @@ 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 @@ 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); @@ -251,6 +264,15 @@ 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; src/main/java/com/gitblit/wicket/panels/SshKeysPanel.html
New file @@ -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> src/main/java/com/gitblit/wicket/panels/SshKeysPanel.java
New file @@ -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<? extends WebPage> pageClass; private final PageParameters params; public SshKeysPanel(String wicketId, UserModel user, Class<? extends WebPage> pageClass, PageParameters params) { super(wicketId); this.user = user; this.pageClass = pageClass; this.params = params; } @Override protected void onInitialize() { super.onInitialize(); List<SshKey> keys = app().keys().getKeys(user.username); final ListDataProvider<SshKey> dp = new ListDataProvider<SshKey>(keys); 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())); Link<Void> delete = new Link<Void>("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<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)) { setRedirect(true); setResponsePage(pageClass, params); } } }); add(addKeyForm); } } src/main/java/com/gitblit/wicket/panels/TextAreaOption.html
New file @@ -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> src/main/java/com/gitblit/wicket/panels/TextAreaOption.java
New file @@ -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); } } src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java
@@ -82,6 +82,21 @@ } @Override public boolean isServingHTTP() { return true; } @Override public boolean isServingGIT() { return true; } @Override public boolean isServingSSH() { return true; } @Override public boolean isDebugMode() { return true; }