Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

www.github.com/gitblit/gitblit.git

Package Overview
Dependencies
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

www.github.com/gitblit/gitblit.git - npm Package Compare versions

Comparing version
v1.9.3-0.20221205170652-71697e5fc0f5
to
v1.9.3
src/main/resources/clippy.swf

Sorry, the diff of this file is not supported yet

+25
-34

@@ -1,2 +0,2 @@

name: Continous integration
name: Continous build - build and test on every push

@@ -8,13 +8,10 @@ on:

- gh-pages
pull_request:
branches-ignore:
- 'release*'
- gh-pages
jobs:
build_linux:
name: Linux build and test
runs-on: ubuntu-latest
build:
name: Build and test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
java-version: [8, 11]

@@ -24,3 +21,3 @@

- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v1
with:

@@ -30,13 +27,6 @@ submodules: true

- name: Setup Java ${{ matrix.java-version }}
uses: actions/setup-java@v3
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.java-version }}
distribution: 'temurin'
- name: Setup Moxie
run: |
wget http://gitblit.github.io/moxie/maven/com/gitblit/moxie/moxie+ant/0.9.4/moxie+ant-0.9.4.tar.gz
tar -xzf moxie+ant-0.9.4.tar.gz
moxie-0.9.4/bin/moxie -version
- name: Report Java version

@@ -47,24 +37,19 @@ run: |

- name: Build with Moxie
run: moxie-0.9.4/bin/moxie test
- name: Build with Ant
run: ant test
build_windows:
name: Windows build and test
runs-on: windows-latest
strategy:
matrix:
java-version: [8, 11]
build_j7:
name: Build and test on Java 7
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v1
with:
submodules: true
- name: Setup Java ${{ matrix.java-version }}
uses: actions/setup-java@v3
- name: Setup Java 7
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.java-version }}
distribution: 'temurin'
java-version: 7

@@ -76,3 +61,9 @@ - name: Report Java version

- name: Build with Ant
run: ant test
- name: Setup Moxie
run: |
wget http://gitblit.github.io/moxie/maven/com/gitblit/moxie/moxie+ant/0.9.4/moxie+ant-0.9.4.tar.gz
tar -xzf moxie+ant-0.9.4.tar.gz
moxie-0.9.4/bin/moxie -version
- name: Build with Moxie
run: moxie-0.9.4/bin/moxie test

@@ -6,3 +6,4 @@ dist: trusty

jdk:
- openjdk7
- openjdk8
- oraclejdk11

@@ -34,5 +34,2 @@ /*

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;

@@ -43,3 +40,2 @@ import java.util.Collections;

import java.util.Set;
import java.util.StringTokenizer;

@@ -63,4 +59,2 @@ import org.eclipse.jgit.errors.ConfigInvalidException;

import static java.nio.charset.StandardCharsets.UTF_8;
public final class BugtraqConfig {

@@ -81,3 +75,2 @@

private static final String LOG_LINKTEXT = "loglinktext";
private static final String PROJECTS = "projects";

@@ -105,3 +98,2 @@ // Static =================================================================

}
if (getString(null, URL, config, baseConfig) != null) {

@@ -117,3 +109,3 @@ allNames.add(null);

final List<BugtraqConfigEntry> entries = new ArrayList<>();
final List<BugtraqEntry> entries = new ArrayList<BugtraqEntry>();
for (String name : allNames) {

@@ -166,22 +158,4 @@ final String url = getString(name, URL, config, baseConfig);

final String projectsList = getString(name, PROJECTS, config, baseConfig);
final List<String> projects;
if (projectsList != null) {
projects = new ArrayList<>();
final StringTokenizer tokenizer = new StringTokenizer(projectsList, ",", false);
while (tokenizer.hasMoreTokens()) {
projects.add(tokenizer.nextToken().trim());
}
if (projects.isEmpty()) {
throw new ConfigInvalidException("'" + name + ".projects' must specify at least one project or be not present at all.");
}
}
else {
projects = null;
}
final String linkText = getString(name, LOG_LINKTEXT, config, baseConfig);
entries.add(new BugtraqConfigEntry(url, idRegex, linkRegex, filterRegex, linkText, projects));
entries.add(new BugtraqEntry(url, idRegex, linkRegex, filterRegex, linkText));
}

@@ -199,7 +173,7 @@

@NotNull
private final List<BugtraqConfigEntry> entries;
private final List<BugtraqEntry> entries;
// Setup ==================================================================
BugtraqConfig(@NotNull List<BugtraqConfigEntry> entries) {
BugtraqConfig(@NotNull List<BugtraqEntry> entries) {
this.entries = entries;

@@ -211,3 +185,3 @@ }

@NotNull
public List<BugtraqConfigEntry> getEntries() {
public List<BugtraqEntry> getEntries() {
return Collections.unmodifiableList(entries);

@@ -237,3 +211,2 @@ }

}
RevCommit commit = rw.parseCommit(headId);

@@ -247,3 +220,3 @@ RevTree tree = commit.getTree();

ObjectLoader ldr = repository.open(entid, Constants.OBJ_BLOB);
content = new String(ldr.getCachedBytes(), guessEncoding(commit));
content = new String(ldr.getCachedBytes(), commit.getEncoding());
break;

@@ -284,11 +257,2 @@ }

@NotNull
private static Charset guessEncoding(RevCommit commit) {
try {
return commit.getEncoding();
} catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
return UTF_8;
}
}
@Nullable

@@ -305,4 +269,4 @@ private static String getString(@Nullable String subsection, @NotNull String key, @NotNull Config config, @Nullable Config baseConfig) {

return value;
}
return value;
}

@@ -309,0 +273,0 @@ @Nullable

@@ -34,3 +34,3 @@ /*

public final class BugtraqEntry {
final class BugtraqEntry {

@@ -37,0 +37,0 @@ // Fields =================================================================

@@ -60,8 +60,6 @@ /*

for (BugtraqConfigEntry configEntry : config.getEntries()) {
for (BugtraqEntry entry : configEntry.getEntries()) {
final List<BugtraqParserIssueId> ids = entry.getParser().parse(message);
for (BugtraqParserIssueId id : ids) {
allIds.add(new IssueId(entry, id));
}
for (BugtraqEntry entry : config.getEntries()) {
final List<BugtraqParserIssueId> ids = entry.getParser().parse(message);
for (BugtraqParserIssueId id : ids) {
allIds.add(new IssueId(entry, id));
}

@@ -68,0 +66,0 @@ }

@@ -302,7 +302,3 @@ /*

ucm.user = userService.getUserModel(ucm.user.username);
// Users may have been deleted, but are still present in authority.conf.
// TODO: Currently this only keeps the app from crashing. It should provide means to show obsolete user entries and delete them.
if (ucm.user != null) {
map.put(ucm.user.username, ucm);
}
map.put(ucm.user.username, ucm);
}

@@ -309,0 +305,0 @@ } catch (IOException e) {

@@ -648,24 +648,2 @@ /*

public enum TlsClientCertPolicy {
REQUIRED, TRUE, OPTIONAL, FALSE, DISABLED, NONE;
public static TlsClientCertPolicy fromString(String value) {
for (TlsClientCertPolicy t : values()) {
if (t.name().equalsIgnoreCase(value)) {
switch(t) {
case TRUE:
return REQUIRED;
case FALSE:
return OPTIONAL;
case NONE:
return DISABLED;
default:
return t;
}
}
}
return TlsClientCertPolicy.OPTIONAL;
}
}
/**

@@ -672,0 +650,0 @@ * The type of merge Gitblit will use when merging a ticket to the integration branch.

@@ -230,7 +230,4 @@ /*

public String toString() {
if (propertiesFile == null) {
return "[empty]";
}
return propertiesFile.getAbsolutePath();
}
}

@@ -47,4 +47,3 @@ /*

import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.ListenerHolder;
import org.eclipse.jetty.server.session.HashSessionManager;
import org.eclipse.jetty.util.security.Constraint;

@@ -62,3 +61,2 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;

import com.gitblit.Constants.TlsClientCertPolicy;
import com.gitblit.authority.GitblitAuthority;

@@ -296,14 +294,10 @@ import com.gitblit.authority.NewCertificateConfig;

serverKeyStore, serverTrustStore, params.storePassword, caRevocationList);
TlsClientCertPolicy clientCertPolicy = TlsClientCertPolicy.fromString(params.requireClientCertificates);
if (clientCertPolicy == TlsClientCertPolicy.REQUIRED) {
if (params.requireClientCertificates) {
factory.setNeedClientAuth(true);
} else if (clientCertPolicy == TlsClientCertPolicy.OPTIONAL) {
factory.setNeedClientAuth(false);
} else {
factory.setWantClientAuth(true);
} else {
factory.setNeedClientAuth(false);
factory.setWantClientAuth(false);
}
ServerConnector connector = new ServerConnector(server, factory);
connector.setSoLingerTime(-1);
connector.setIdleTimeout(settings.getLong(Keys.server.httpIdleTimeout, 30000L));

@@ -345,2 +339,3 @@ connector.setPort(params.securePort);

ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
connector.setSoLingerTime(-1);
connector.setIdleTimeout(settings.getLong(Keys.server.httpIdleTimeout, 30000L));

@@ -387,9 +382,9 @@ connector.setPort(params.port);

// Set cookies HttpOnly so they are not accessible to JavaScript engines
SessionHandler sessionHandler = rootContext.getSessionHandler();
sessionHandler.setHttpOnly(true);
HashSessionManager sessionManager = new HashSessionManager();
sessionManager.setHttpOnly(true);
// Use secure cookies if only serving https
sessionHandler.setSecureRequestOnly( (params.port <= 0 && params.securePort > 0) ||
(params.port > 0 && params.securePort > 0 && settings.getBoolean(Keys.server.redirectToHttpsPort, true)) );
sessionManager.setSecureRequestOnly( (params.port <= 0 && params.securePort > 0) ||
(params.port > 0 && params.securePort > 0 && settings.getBoolean(Keys.server.redirectToHttpsPort, true)) );
rootContext.getSessionHandler().setSessionManager(sessionManager);

@@ -460,9 +455,8 @@ // Ensure there is a defined User Service

// Configure this context to use the Security Handler defined before
rootContext.setSecurityHandler(sh);
rootContext.setHandler(sh);
}
// Setup the Gitblit context
ListenerHolder gitblitHolder = new ListenerHolder(GitblitContext.class);
gitblitHolder.setListener(newGitblit(settings, baseFolder));
rootContext.getServletHandler().addListener(gitblitHolder);
GitblitContext gitblit = newGitblit(settings, baseFolder);
rootContext.addEventListener(gitblit);

@@ -615,3 +609,3 @@ try {

@Option(name = "--requireClientCertificates", usage = "Require client X509 certificates for https connections.")
public String requireClientCertificates = FILESETTINGS.getString(Keys.server.requireClientCertificates, "optional");
public Boolean requireClientCertificates = FILESETTINGS.getBoolean(Keys.server.requireClientCertificates, false);

@@ -618,0 +612,0 @@ /*

@@ -113,3 +113,3 @@ /*

public List<RegistrantAccessPermission> getRepositoryPermissions() {
List<RegistrantAccessPermission> list = new ArrayList<>();
List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
if (canAdmin()) {

@@ -139,2 +139,3 @@ // user has REWIND access to all repositories

// include immutable team permissions, being careful to preserve order
Set<RegistrantAccessPermission> set = new LinkedHashSet<RegistrantAccessPermission>(list);
for (TeamModel team : teams) {

@@ -147,13 +148,6 @@ for (RegistrantAccessPermission teamPermission : team.getRepositoryPermissions()) {

teamPermission.mutable = false;
int i = list.indexOf(teamPermission);
if (i < 0) list.add(teamPermission);
else {
RegistrantAccessPermission lp = list.get(i);
if (teamPermission.permission.exceeds(lp.permission)) {
list.set(i, teamPermission);
}
}
set.add(teamPermission);
}
}
return list;
return new ArrayList<RegistrantAccessPermission>(set);
}

@@ -160,0 +154,0 @@

@@ -21,9 +21,5 @@ /*

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Arrays;

@@ -33,21 +29,15 @@ import java.util.Iterator;

import org.apache.sshd.common.config.keys.PrivateKeyEntryDecoder;
import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.PasswordFinder;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.util.OpenSSHPrivateKeyUtil;
import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil;
import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec;
import org.bouncycastle.jcajce.spec.OpenSSHPublicKeySpec;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
/**
* This host key provider loads private keys from the specified files.
* <p>
*
* Note that this class has a direct dependency on BouncyCastle and won't work

@@ -58,53 +48,52 @@ * unless it has been correctly registered as a security provider.

*/
public class FileKeyPairProvider extends AbstractKeyPairProvider
{
public class FileKeyPairProvider extends AbstractKeyPairProvider {
private String[] files;
private PasswordFinder passwordFinder;
public FileKeyPairProvider()
{
public FileKeyPairProvider() {
}
public FileKeyPairProvider(String[] files)
{
public FileKeyPairProvider(String[] files) {
this.files = files;
}
public String[] getFiles()
{
public FileKeyPairProvider(String[] files, PasswordFinder passwordFinder) {
this.files = files;
this.passwordFinder = passwordFinder;
}
public String[] getFiles() {
return files;
}
public void setFiles(String[] files)
{
public void setFiles(String[] files) {
this.files = files;
}
public PasswordFinder getPasswordFinder() {
return passwordFinder;
}
@Override
public Iterable<KeyPair> loadKeys()
{
public void setPasswordFinder(PasswordFinder passwordFinder) {
this.passwordFinder = passwordFinder;
}
public Iterable<KeyPair> loadKeys() {
if (!SecurityUtils.isBouncyCastleRegistered()) {
throw new IllegalStateException("BouncyCastle must be registered as a JCE provider");
}
return new Iterable<KeyPair>()
{
return new Iterable<KeyPair>() {
@Override
public Iterator<KeyPair> iterator()
{
return new Iterator<KeyPair>()
{
public Iterator<KeyPair> iterator() {
return new Iterator<KeyPair>() {
private final Iterator<String> iterator = Arrays.asList(files).iterator();
private KeyPair nextKeyPair;
private boolean nextKeyPairSet = false;
@Override
public boolean hasNext()
{
public boolean hasNext() {
return nextKeyPairSet || setNextObject();
}
@Override
public KeyPair next()
{
public KeyPair next() {
if (!nextKeyPairSet) {

@@ -118,18 +107,9 @@ if (!setNextObject()) {

}
@Override
public void remove()
{
public void remove() {
throw new UnsupportedOperationException();
}
private boolean setNextObject()
{
private boolean setNextObject() {
while (iterator.hasNext()) {
String file = iterator.next();
File f = new File(file);
if (!f.isFile()) {
log.debug("File does not exist, skipping {}", file);
continue;
}
nextKeyPair = doLoadKey(file);

@@ -149,49 +129,6 @@ if (nextKeyPair != null) {

private KeyPair doLoadKey(String file)
{
protected KeyPair doLoadKey(String file) {
try {
try (PemReader r = new PemReader(new InputStreamReader(new FileInputStream(file)))) {
PemObject pemObject = r.readPemObject();
if ("OPENSSH PRIVATE KEY".equals(pemObject.getType())) {
// This reads a properly OpenSSH formatted ed25519 private key file.
// It is currently unused because the SSHD library in play doesn't work with proper keys.
// This is kept in the hope that in the future the library offers proper support.
try {
byte[] privateKeyContent = pemObject.getContent();
AsymmetricKeyParameter privateKeyParameters = OpenSSHPrivateKeyUtil.parsePrivateKeyBlob(privateKeyContent);
if (privateKeyParameters instanceof Ed25519PrivateKeyParameters) {
OpenSSHPrivateKeySpec privkeySpec = new OpenSSHPrivateKeySpec(privateKeyContent);
Ed25519PublicKeyParameters publicKeyParameters = ((Ed25519PrivateKeyParameters)privateKeyParameters).generatePublicKey();
OpenSSHPublicKeySpec pubKeySpec = new OpenSSHPublicKeySpec(OpenSSHPublicKeyUtil.encodePublicKey(publicKeyParameters));
KeyFactory kf = KeyFactory.getInstance("Ed25519", "BC");
PrivateKey privateKey = kf.generatePrivate(privkeySpec);
PublicKey publicKey = kf.generatePublic(pubKeySpec);
return new KeyPair(publicKey, privateKey);
}
else {
log.warn("OpenSSH format is only supported for Ed25519 key type. Unable to read key " + file);
}
}
catch (Exception e) {
log.warn("Unable to read key " + file, e);
}
return null;
}
if ("EDDSA PRIVATE KEY".equals(pemObject.getType())) {
// This reads the ed25519 key from a file format that we created in SshDaemon.
// The type EDDSA PRIVATE KEY was given by us and nothing official.
byte[] privateKeyContent = pemObject.getContent();
PrivateKeyEntryDecoder<? extends PublicKey,? extends PrivateKey> decoder = SecurityUtils.getOpenSSHEDDSAPrivateKeyEntryDecoder();
PrivateKey privateKey = decoder.decodePrivateKey(null, privateKeyContent, 0, privateKeyContent.length);
PublicKey publicKey = SecurityUtils. recoverEDDSAPublicKey(privateKey);
return new KeyPair(publicKey, privateKey);
}
}
try (PEMParser r = new PEMParser(new InputStreamReader(new FileInputStream(file)))) {
PEMParser r = new PEMParser(new InputStreamReader(new FileInputStream(file)));
try {
Object o = r.readObject();

@@ -201,16 +138,18 @@

pemConverter.setProvider("BC");
if (passwordFinder != null && o instanceof PEMEncryptedKeyPair) {
JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder();
PEMDecryptorProvider pemDecryptor = decryptorBuilder.build(passwordFinder.getPassword());
o = pemConverter.getKeyPair(((PEMEncryptedKeyPair) o).decryptKeyPair(pemDecryptor));
}
if (o instanceof PEMKeyPair) {
o = pemConverter.getKeyPair((PEMKeyPair)o);
return (KeyPair)o;
return (KeyPair) o;
} else if (o instanceof KeyPair) {
return (KeyPair) o;
}
else if (o instanceof KeyPair) {
return (KeyPair)o;
}
else {
log.warn("Cannot read unsupported PEM object of type: " + o.getClass().getCanonicalName());
}
} finally {
r.close();
}
}
catch (Exception e) {
} catch (Exception e) {
log.warn("Unable to read key " + file, e);

@@ -217,0 +156,0 @@ }

@@ -24,21 +24,21 @@ /*

@Override
public boolean canConnect(Type type, SshdSocketAddress address, Session session) {
return false;
}
@Override
public boolean canConnect(Type type, SshdSocketAddress address, Session session) {
return false;
}
@Override
public boolean canForwardAgent(Session session, String requestType) {
return false;
}
@Override
public boolean canForwardAgent(Session session) {
return false;
}
@Override
public boolean canForwardX11(Session session, String requestType) {
return false;
}
@Override
public boolean canForwardX11(Session session) {
return false;
}
@Override
public boolean canListen(SshdSocketAddress address, Session session) {
return false;
}
@Override
public boolean canListen(SshdSocketAddress address, Session session) {
return false;
}
}

@@ -18,3 +18,2 @@ /*

import java.io.ByteArrayOutputStream;
import java.io.File;

@@ -27,3 +26,2 @@ import java.io.FileOutputStream;

import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.text.MessageFormat;

@@ -33,19 +31,9 @@ import java.util.List;

import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import org.apache.sshd.common.config.keys.KeyEntryResolver;
import org.apache.sshd.common.io.IoServiceFactoryFactory;
import org.apache.sshd.common.io.mina.MinaServiceFactoryFactory;
import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.common.util.security.bouncycastle.BouncyCastleSecurityProviderRegistrar;
import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar;
import org.apache.sshd.common.util.security.eddsa.OpenSSHEd25519PrivateKeyEntryDecoder;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.pubkey.CachingPublicKeyAuthenticator;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.util.OpenSSHPrivateKeyUtil;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import org.bouncycastle.openssl.PEMWriter;
import org.eclipse.jgit.internal.JGitText;

@@ -72,3 +60,3 @@ import org.slf4j.Logger;

private static final Logger log = LoggerFactory.getLogger(SshDaemon.class);
private final Logger log = LoggerFactory.getLogger(SshDaemon.class);

@@ -111,11 +99,6 @@ private static final String AUTH_PUBLICKEY = "publickey";

// Ensure that Bouncy Castle is our JCE provider
SecurityUtils.registerSecurityProvider(new BouncyCastleSecurityProviderRegistrar());
SecurityUtils.setRegisterBouncyCastle(true);
if (SecurityUtils.isBouncyCastleRegistered()) {
log.info("BouncyCastle is registered as a JCE provider");
log.debug("BouncyCastle is registered as a JCE provider");
}
// Add support for ED25519_SHA512
SecurityUtils.registerSecurityProvider(new EdDSASecurityProviderRegistrar());
if (SecurityUtils.isProviderRegistered("EdDSA")) {
log.info("EdDSA is registered as a JCE provider");
}

@@ -125,10 +108,6 @@ // Generate host RSA and DSA keypairs and create the host keypair provider

File dsaKeyStore = new File(gitblit.getBaseFolder(), "ssh-dsa-hostkey.pem");
File ecdsaKeyStore = new File(gitblit.getBaseFolder(), "ssh-ecdsa-hostkey.pem");
File eddsaKeyStore = new File(gitblit.getBaseFolder(), "ssh-eddsa-hostkey.pem");
File ed25519KeyStore = new File(gitblit.getBaseFolder(), "ssh-ed25519-hostkey.pem");
generateKeyPair(rsaKeyStore, "RSA", 2048);
generateKeyPair(ecdsaKeyStore, "ECDSA", 256);
generateKeyPair(eddsaKeyStore, "EdDSA", 0);
generateKeyPair(dsaKeyStore, "DSA", 0);
FileKeyPairProvider hostKeyPairProvider = new FileKeyPairProvider();
hostKeyPairProvider.setFiles(new String [] { ecdsaKeyStore.getPath(), eddsaKeyStore.getPath(), ed25519KeyStore.getPath(), rsaKeyStore.getPath(), dsaKeyStore.getPath() });
hostKeyPairProvider.setFiles(new String [] { rsaKeyStore.getPath(), dsaKeyStore.getPath(), dsaKeyStore.getPath() });

@@ -190,3 +169,3 @@

sshd.setFileSystemFactory(new DisabledFilesystemFactory());
sshd.setForwardingFilter(new NonForwardingFilter());
sshd.setTcpipForwardingFilter(new NonForwardingFilter());
sshd.setCommandFactory(new SshCommandFactory(gitblit, workQueue));

@@ -268,3 +247,3 @@ sshd.setShellFactory(new WelcomeShell(gitblit));

static void generateKeyPair(File file, String algorithm, int keySize) {
private void generateKeyPair(File file, String algorithm, int keySize) {
if (file.exists()) {

@@ -292,34 +271,4 @@ return;

FileOutputStream os = new FileOutputStream(file);
PemWriter w = new PemWriter(new OutputStreamWriter(os));
if (algorithm.equals("ED25519")) {
// This generates a proper OpenSSH formatted ed25519 private key file.
// It is currently unused because the SSHD library in play doesn't work with proper keys.
// This is kept in the hope that in the future the library offers proper support.
AsymmetricKeyParameter keyParam = PrivateKeyFactory.createKey(kp.getPrivate().getEncoded());
byte[] encKey = OpenSSHPrivateKeyUtil.encodePrivateKey(keyParam);
w.writeObject(new PemObject("OPENSSH PRIVATE KEY", encKey));
}
else if (algorithm.equals("EdDSA")) {
// This saves the ed25519 key in a file format that the current SSHD library can work with.
// We call it EDDSA PRIVATE KEY, but that string is given by us and nothing official.
PrivateKey privateKey = kp.getPrivate();
if (privateKey instanceof EdDSAPrivateKey) {
OpenSSHEd25519PrivateKeyEntryDecoder encoder = (OpenSSHEd25519PrivateKeyEntryDecoder)SecurityUtils.getOpenSSHEDDSAPrivateKeyEntryDecoder();
EdDSAPrivateKey dsaPrivateKey = (EdDSAPrivateKey)privateKey;
// Jumping through some hoops here, because the decoder expects the key type as a string at the
// start, but the encoder doesn't put it in. So we have to put it in ourselves.
ByteArrayOutputStream encos = new ByteArrayOutputStream();
String type = encoder.encodePrivateKey(encos, dsaPrivateKey);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
KeyEntryResolver.encodeString(bos, type);
encos.writeTo(bos);
w.writeObject(new PemObject("EDDSA PRIVATE KEY", bos.toByteArray()));
}
else {
log.warn("Unable to encode EdDSA key, got key type " + privateKey.getClass().getCanonicalName());
}
}
else {
w.writeObject(new JcaMiscPEMGenerator(kp));
}
PEMWriter w = new PEMWriter(new OutputStreamWriter(os));
w.writeObject(kp);
w.flush();

@@ -329,4 +278,5 @@ w.close();

log.warn(MessageFormat.format("Unable to generate {0} keypair", algorithm), e);
return;
}
}
}

@@ -84,11 +84,2 @@ /*

public void detachPublicKey()
{
if (rawData == null) {
// Make sure the raw data is available
getRawData();
}
publicKey = null;
}
public String getAlgorithm() {

@@ -95,0 +86,0 @@ return getPublicKey().getAlgorithm();

@@ -60,7 +60,2 @@ /*

@Override
public Command get() {
return create();
}
private static class SendMessage implements Command, SessionAware {

@@ -67,0 +62,0 @@

@@ -158,6 +158,6 @@ /*

}
} catch (IOException e) {
logger.error(MessageFormat.format("Bugtraq config for {0} is invalid!", repositoryName), e);
} catch (ConfigInvalidException e) {
logger.warn("Bugtraq config for {} is invalid!", repositoryName, e);
} catch (Exception e) {
logger.warn("Failed to parse message through Bugtraq.", e);
logger.error(MessageFormat.format("Bugtraq config for {0} is invalid!", repositoryName), e);
}

@@ -164,0 +164,0 @@

@@ -108,4 +108,2 @@ /*

int i = 0;
int l = 0;
while (i < inStr.length()) {

@@ -123,14 +121,8 @@ if (inStr.charAt(i) == '&') {

} else if (changeSpace && inStr.charAt(i) == '\t') {
for (int j = 0; j < tabLength - l; j++) {
for (int j = 0; j < tabLength; j++) {
retStr.append("&nbsp;");
}
l = -1;
} else {
retStr.append(inStr.charAt(i));
}
l = (l + 1) % tabLength;
if (inStr.charAt(i) == '\n') {
l = 0;
}
i++;

@@ -137,0 +129,0 @@ }

@@ -75,3 +75,3 @@ /*

import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.cert.X509CRLHolder;

@@ -86,2 +86,3 @@ import org.bouncycastle.cert.X509v2CRLBuilder;

import org.bouncycastle.openssl.PEMEncryptor;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;

@@ -449,5 +450,5 @@ import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder;

// PEM encoded X509
JcaPEMWriter pemWriter = null;
PEMWriter pemWriter = null;
try {
pemWriter = new JcaPEMWriter(new FileWriter(tmpFile));
pemWriter = new PEMWriter(new FileWriter(tmpFile));
pemWriter.writeObject(cert);

@@ -565,5 +566,5 @@ pemWriter.flush();

JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
certBuilder.addExtension(Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(pair.getPublic()));
certBuilder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));
certBuilder.addExtension(Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey()));
certBuilder.addExtension(X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(pair.getPublic()));
certBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
certBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey()));

@@ -577,3 +578,3 @@ // support alternateSubjectNames for SSL certificates

GeneralNames subjectAltName = new GeneralNames(altNames.toArray(new GeneralName [altNames.size()]));
certBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAltName);
certBuilder.addExtension(X509Extension.subjectAlternativeName, false, subjectAltName);
}

@@ -636,6 +637,6 @@

JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
caBuilder.addExtension(Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(caPair.getPublic()));
caBuilder.addExtension(Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caPair.getPublic()));
caBuilder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true));
caBuilder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign));
caBuilder.addExtension(X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(caPair.getPublic()));
caBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caPair.getPublic()));
caBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(true));
caBuilder.addExtension(X509Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign));

@@ -870,10 +871,10 @@ JcaX509CertificateConverter converter = new JcaX509CertificateConverter().setProvider(BC);

JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
certBuilder.addExtension(Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(pair.getPublic()));
certBuilder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));
certBuilder.addExtension(Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey()));
certBuilder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyEncipherment | KeyUsage.digitalSignature));
certBuilder.addExtension(X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(pair.getPublic()));
certBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
certBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey()));
certBuilder.addExtension(X509Extension.keyUsage, true, new KeyUsage(KeyUsage.keyEncipherment | KeyUsage.digitalSignature));
if (!StringUtils.isEmpty(clientMetadata.emailAddress)) {
GeneralNames subjectAltName = new GeneralNames(
new GeneralName(GeneralName.rfc822Name, clientMetadata.emailAddress));
certBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAltName);
certBuilder.addExtension(X509Extension.subjectAlternativeName, false, subjectAltName);
}

@@ -880,0 +881,0 @@

@@ -738,4 +738,2 @@ gb.repository = Repository

gb.addSshKey = SSH Key hinzuf\u00fcgen
gb.addSshKeyErrorEmpty = SSH Public Key leer. Bitte geben Sie einen g\u00fcltigen SSH Public Key an
gb.addSshKeyErrorFormat = SSH Public Key Format ung�ltig. Bitte geben Sie einen g\u00fcltigen SSH Public Key an
gb.key = Key

@@ -742,0 +740,0 @@ gb.sshKeyComment = Kommentar

@@ -741,4 +741,2 @@ gb.repository = repository

gb.addSshKey = Add SSH Key
gb.addSshKeyErrorEmpty = SSH public key empty. Please provide a valid SSH public key
gb.addSshKeyErrorFormat = Not a valid SSH public key format. Please provide a valid SSH public key
gb.key = Key

@@ -745,0 +743,0 @@ gb.sshKeyComment = Comment

@@ -174,7 +174,2 @@ /*

// load clipboard library to copy repository URL
addBottomScript("../../clipboard/clipboard.min.js");
// instantiate clipboard
addBottomScript("../../clipboard/gitblit-ctcbtn.js");
// set stateless page preference

@@ -181,0 +176,0 @@ setStatelessHint(true);

@@ -64,5 +64,5 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

</wicket:fragment>
</wicket:extend>
</wicket:extend>
</body>
</html>

@@ -589,10 +589,16 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

</wicket:fragment>
<!-- JavaScript automatic copy to clipboard -->
<wicket:fragment wicket:id="clippyPanel">
<span class="tooltipped tooltipped-n">
<img class="ctcbtn" wicket:id="copyIcon" wicket:message="title:gb.copyToClipboard" />
</span>
</wicket:fragment>
<!-- flash-based button-press copy & paste -->
<wicket:fragment wicket:id="clippyPanel">
<object wicket:message="title:gb.copyToClipboard" style="vertical-align:middle;"
wicket:id="clippy"
width="14"
height="14"
bgcolor="#ffffff"
quality="high"
wmode="transparent"
scale="noscale"
allowScriptAccess="sameDomain"></object>
</wicket:fragment>

@@ -599,0 +605,0 @@ </wicket:extend>

@@ -15,10 +15,8 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<div class="btn-toolbar" style="margin: 0px;">
<div class="btn-group repositoryUrlContainer tooltipped tooltipped-w">
<img style="max-width:inherit; vertical-align: middle;padding: 0px 0px 1px 3px;" wicket:id="accessRestrictionIcon"></img>
<div class="btn-group repositoryUrlContainer">
<img style="vertical-align: middle;padding: 0px 0px 1px 3px;" wicket:id="accessRestrictionIcon"></img>
<span wicket:id="menu"></span>
<div class="repositoryUrl">
<span wicket:id="primaryUrl">[repository primary url]</span>
<span class="tooltipped tooltipped-n">
<span class="hidden-phone hidden-tablet" wicket:id="copyFunction"></span>
</span>
<span class="hidden-phone hidden-tablet" wicket:id="copyFunction"></span>
</div>

@@ -39,3 +37,3 @@ <span class="hidden-phone hidden-tablet repositoryUrlRightCap" wicket:id="primaryUrlPermission">[repository primary url permission]</span>

<div class="btn-toolbar" style="margin: 4px 0px 0px 0px;">
<div class="btn-group tooltipped tooltipped-w" wicket:id="appMenus">
<div class="btn-group" wicket:id="appMenus">
<span wicket:id="appMenu"></span>

@@ -92,5 +90,13 @@ </div>

<!-- JavaScript automatic copy to clipboard -->
<!-- flash-based button-press copy & paste -->
<wicket:fragment wicket:id="clippyPanel">
<img class="ctcbtn" style="max-width:inherit;" wicket:id="copyIcon" wicket:message="title:gb.copyToClipboard" />
<object wicket:message="title:gb.copyToClipboard" style="vertical-align:middle;"
wicket:id="clippy"
width="14"
height="14"
bgcolor="#ffffff"
quality="high"
wmode="transparent"
scale="noscale"
allowScriptAccess="sameDomain"></object>
</wicket:fragment>

@@ -97,0 +103,0 @@

@@ -28,3 +28,2 @@ /*

import org.apache.wicket.RequestCycle;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.basic.Label;

@@ -145,3 +144,4 @@ import org.apache.wicket.markup.html.image.ContextImage;

Fragment fragment = new Fragment("repoUrl", "actionFragment", this);
Component content = new Label("content", repoUrl.url).setOutputMarkupId(true);
Component content = new Label("content", repoUrl.url).setRenderBodyOnly(true);
WicketUtils.setCssClass(content, "commandMenuItem");
fragment.add(content);

@@ -155,3 +155,3 @@ item.add(fragment);

fragment.add(permissionLabel);
fragment.add(createCopyFragment(repoUrl.url, content.getMarkupId()));
fragment.add(createCopyFragment(repoUrl.url));
}

@@ -205,5 +205,3 @@ };

Label primaryUrlLabel = new Label("primaryUrl", primaryUrl.url);
primaryUrlLabel.setOutputMarkupId(true);
urlPanel.add(primaryUrlLabel);
urlPanel.add(new Label("primaryUrl", primaryUrl.url).setRenderBodyOnly(true));

@@ -214,3 +212,3 @@ Label permissionLabel = new Label("primaryUrlPermission", primaryUrl.hasPermission() ? primaryUrl.permission.toString() : externalPermission);

urlPanel.add(permissionLabel);
urlPanel.add(createCopyFragment(primaryUrl.url, primaryUrlLabel.getMarkupId()));
urlPanel.add(createCopyFragment(primaryUrl.url));

@@ -327,3 +325,2 @@ return urlPanel;

Label content = new Label("content", command);
content.setOutputMarkupId(true);
WicketUtils.setCssClass(content, "commandMenuItem");

@@ -334,3 +331,3 @@ fragment.add(content);

// copy function for command
fragment.add(createCopyFragment(command, content.getMarkupId()));
fragment.add(createCopyFragment(command));
}

@@ -359,13 +356,12 @@ }};

protected Fragment createCopyFragment(String text, String target) {
protected Fragment createCopyFragment(String text) {
if (app().settings().getBoolean(Keys.web.allowFlashCopyToClipboard, true)) {
// javascript: browser JS API based copy to clipboard
// clippy: flash-based copy & paste
Fragment copyFragment = new Fragment("copyFunction", "clippyPanel", this);
ContextImage img = WicketUtils.newImage("copyIcon", "clippy.png");
// Add the ID of the target element that holds the text to copy to clipboard
img.add(new SimpleAttributeModifier("data-clipboard-target", "#"+target));
copyFragment.add(img);
String baseUrl = WicketUtils.getGitblitURL(getRequest());
ShockWaveComponent clippy = new ShockWaveComponent("clippy", baseUrl + "/clippy.swf");
clippy.setValue("flashVars", "text=" + StringUtils.encodeURL(text));
copyFragment.add(clippy);
return copyFragment;
}
else {
} else {
// javascript: manual copy & paste with modal browser prompt dialog

@@ -372,0 +368,0 @@ Fragment copyFragment = new Fragment("copyFunction", "jsPanel", this);

@@ -40,4 +40,3 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<div wicket:id="addKeyComment"></div>
<div wicket:id="addKeyFeedback"></div>
<div class="form-actions"><input class="btn btn-appmenu" type="submit" value="Add" wicket:message="value:gb.add" wicket:id="addKeyButton" /></div>

@@ -44,0 +43,0 @@ </form>

@@ -22,4 +22,2 @@ /*

import com.gitblit.wicket.WicketUtils;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;

@@ -69,27 +67,4 @@ import org.apache.wicket.ajax.markup.html.AjaxLink;

final IModel<String> keyFeedback = Model.of("");
final List<SshKey> keys = new ArrayList<SshKey>(app().keys().getKeys(user.username));
// Create list data provider that gets rid of the (not serializable EdDSA) PublicKey.
final ListDataProvider<SshKey> dp = new ListDataProvider<SshKey>(keys) {
@Override
public IModel<SshKey> model(final SshKey key) {
return new IModel<SshKey>() {
@Override
public SshKey getObject() {
return key;
}
@Override
public void setObject(SshKey object) {
// Cannot get set
}
@Override
public void detach() {
key.detachPublicKey();
}
};
}
};
final ListDataProvider<SshKey> dp = new ListDataProvider<SshKey>(keys);
final DataView<SshKey> keysView = new DataView<SshKey>("keys", dp) {

@@ -120,3 +95,2 @@ private static final long serialVersionUID = 1L;

}
keyFeedback.setObject("");
}

@@ -155,6 +129,2 @@ };

Component addKeyFeedback = new Label("addKeyFeedback", keyFeedback).setOutputMarkupId(true);
WicketUtils.setCssStyle(addKeyFeedback, "color: red; font-weight: bold;");
addKeyForm.add(addKeyFeedback);
addKeyForm.add(new AjaxButton("addKeyButton") {

@@ -171,4 +141,2 @@

// do not submit empty key
keyFeedback.setObject(getString("gb.addSshKeyErrorEmpty"));
target.addComponent(addKeyFeedback);
return;

@@ -182,4 +150,2 @@ }

// failed to parse the key
keyFeedback.setObject(getString("gb.addSshKeyErrorFormat"));
target.addComponent(addKeyFeedback);
return;

@@ -206,8 +172,5 @@ }

keyFeedback.setObject("");
// update the panel
target.addComponent(SshKeysPanel.this);
}
else keyFeedback.setObject("Key not added.");
}

@@ -214,0 +177,0 @@ });

@@ -91,3 +91,3 @@ #!/usr/bin/env python3

if args.patchset is None or args.patchset == 0:
if args.patchset is None or args.patchset is 0:
branch = 'ticket/{:d}'.format(args.id)

@@ -108,3 +108,3 @@ illegals = set(branches) & {'ticket'}

if args.patchset is None or args.patchset == 0:
if args.patchset is None or args.patchset is 0:
# checkout the current ticket patchset

@@ -136,3 +136,3 @@ if args.force:

# pull the patchset from the remote repository
if args.patchset is None or args.patchset == 0:
if args.patchset is None or args.patchset is 0:
print("Pulling ticket {} from the '{}' repository".format(args.id, args.remote))

@@ -556,7 +556,7 @@ patchset_ref = 'ticket/{:d}'.format(args.id)

merge = __call(['git', 'merge', '--ff-only', branch, 'FETCH_HEAD'], echo=True, fail=False)
if len(merge) == 1:
if len(merge) is 1:
up_to_date = merge[0].lower().index('up-to-date') > 0
if up_to_date:
return
elif len(merge) == 0:
elif len(merge) is 0:
print('')

@@ -624,3 +624,3 @@ print("Your '{}' branch has diverged from patchset {} on the '{}' repository.".format(branch, patchset, remote))

line_str = str(line).strip()
if len(line_str) == 0:
if len(line_str) is 0:
break

@@ -631,3 +631,3 @@ lines.append(line_str)

p.wait()
if fail and p.returncode != 0:
if fail and p.returncode is not 0:
exit(p.returncode)

@@ -634,0 +634,0 @@

@@ -2411,172 +2411,2 @@ body {

font-variant: normal;
}
/*
Copy-to-clipboard tooltip styling from Github's primer.css
https://primer.style/css/components/tooltips
Adjusted to not hover but fade-in/out on clipboard events.
*/
.tooltipped {
position:relative
}
.tooltipped:after {
position: absolute;
z-index: 1000000;
padding: 5px 8px;
font: normal normal 11px/1.5 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol";
color: #fff;
background: rgba(42, 42, 42, .8);
text-align: center;
text-decoration: none;
text-shadow: none;
text-transform: none;
letter-spacing: normal;
word-wrap: break-word;
white-space: pre;
pointer-events: none;
content: attr(data-tt-text);
border-radius: 3px;
-webkit-font-smoothing:subpixel-antialiased;
opacity: 0;
transition: 0.5s opacity;
}
.tooltipped:before {
position: absolute;
z-index: 1000001;
width: 0;
height: 0;
color: rgba(42, 42, 42, .8);
pointer-events: none;
content: "";
border:5px solid transparent;
opacity: 0;
transition: 0.5s opacity;
}
.tooltipped-active:before, .tooltipped-active:after {
opacity: 1;
text-decoration:none
}
.tooltipped-s:after, .tooltipped-se:after, .tooltipped-sw:after {
top: 100%;
right: 50%;
margin-top:5px
}
.tooltipped-s:before, .tooltipped-se:before, .tooltipped-sw:before {
top: auto;
right: 50%;
bottom: -5px;
margin-right: -5px;
border-bottom-color:rgba(42, 42, 42, .8)
}
.tooltipped-se:after {
right: auto;
left: 50%;
margin-left:-15px
}
.tooltipped-sw:after {
margin-right:-15px
}
.tooltipped-n:after, .tooltipped-ne:after, .tooltipped-nw:after {
right: 50%;
bottom: 100%;
margin-bottom:5px
}
.tooltipped-n:before, .tooltipped-ne:before, .tooltipped-nw:before {
top: -5px;
right: 50%;
bottom: auto;
margin-right: -5px;
border-top-color:rgba(42, 42, 42, .8)
}
.tooltipped-ne:after {
right: auto;
left: 50%;
margin-left:-15px
}
.tooltipped-nw:after {
margin-right:-15px
}
.tooltipped-s:after, .tooltipped-n:after {
-webkit-transform: translateX(50%);
-ms-transform: translateX(50%);
transform:translateX(50%)
}
.tooltipped-w:after {
right: 100%;
bottom: 50%;
margin-right: 5px;
-webkit-transform: translateY(50%);
-ms-transform: translateY(50%);
transform:translateY(50%)
}
.tooltipped-w:before {
top: 50%;
bottom: 50%;
left: -5px;
margin-top: -5px;
border-left-color:rgba(42, 42, 42, .8)
}
.tooltipped-e:after {
bottom: 50%;
left: 100%;
margin-left: 5px;
-webkit-transform: translateY(50%);
-ms-transform: translateY(50%);
transform:translateY(50%)
}
.tooltipped-e:before {
top: 50%;
right: -5px;
bottom: 50%;
margin-top: -5px;
border-right-color:rgba(42, 42, 42, .8)
}
.tooltipped-sticky:before, .tooltipped-sticky:after {
display:inline-block
}
.fullscreen-overlay-enabled.dark-theme .tooltipped:after {
color: #000;
background:rgba(200, 200, 200, .8)
}
.fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-s:before, .fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-se:before, .fullscreen-overlay-enabled.dark-theme .tooltipped .tooltipped-sw:before {
border-bottom-color:rgba(200, 200, 200, .8)
}
.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-n:before, .fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-ne:before, .fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-nw:before {
border-top-color:rgba(200, 200, 200, .8)
}
.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-e:before {
border-right-color:rgba(200, 200, 200, .8)
}
.fullscreen-overlay-enabled.dark-theme .tooltipped.tooltipped-w:before {
border-left-color:rgba(200, 200, 200, .8)
}
}

@@ -35,3 +35,2 @@ /*

import java.util.List;
import java.util.StringTokenizer;

@@ -48,3 +47,3 @@ import junit.framework.TestCase;

public void testSimpleWithExtendedLink() throws BugtraqException {
final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/JRA-%BUGID%", null, "JRA-\\d+", "\\d+", null, null));
final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/JRA-%BUGID%", null, "JRA-\\d+", "\\d+", null));
doTest(formatter, "JRA-7399: Email subject formatting", l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(": Email subject formatting"));

@@ -56,3 +55,3 @@ doTest(formatter, " JRA-7399, JRA-7398: Email subject formatting", t(" "), l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(", "), l("JRA-7398", "https://jira.atlassian.com/browse/JRA-7398"), t(": Email subject formatting"));

public void testLinkText() throws BugtraqException {
final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/JRA-%BUGID%", null, "JRA-\\d+", "\\d+", "JIRA-%BUGID%", null));
final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/JRA-%BUGID%", null, "JRA-\\d+", "\\d+", "JIRA-%BUGID%"));
doTest(formatter, " JRA-7399, JRA is text, JRA-7398: Email subject formatting", t(" "), l("JIRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(", JRA is text, "), l("JIRA-7398", "https://jira.atlassian.com/browse/JRA-7398"), t(": Email subject formatting"));

@@ -62,4 +61,4 @@ }

public void testTwoNonIntersectingConfigurations() throws BugtraqException {
final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/%BUGID%", null, null, "JRA-\\d+", null, null),
createEntry("https://issues.apache.org/jira/browse/%BUGID%", null, null, "VELOCITY-\\d+", null, null));
final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/%BUGID%", null, null, "JRA-\\d+", null),
createEntry("https://issues.apache.org/jira/browse/%BUGID%", null, null, "VELOCITY-\\d+", null));
doTest(formatter, "JRA-7399, VELOCITY-847: fix", l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(", "), l("VELOCITY-847", "https://issues.apache.org/jira/browse/VELOCITY-847"), t(": fix"));

@@ -71,4 +70,4 @@ doTest(formatter, " JRA-7399: fix/VELOCITY-847", t(" "), l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(": fix/"), l("VELOCITY-847", "https://issues.apache.org/jira/browse/VELOCITY-847"));

public void testTwoIntersectingConfigurations() throws BugtraqException {
final BugtraqFormatter formatter = createFormatter(createEntry("https://host1/%BUGID%", null, null, "A[AB]", null, null),
createEntry("https://host2/%BUGID%", null, null, "BA[A]?", null, null));
final BugtraqFormatter formatter = createFormatter(createEntry("https://host1/%BUGID%", null, null, "A[AB]", null),
createEntry("https://host2/%BUGID%", null, null, "BA[A]?", null));
doTest(formatter, "AA: fix", l("AA", "https://host1/AA"), t(": fix"));

@@ -88,30 +87,10 @@ doTest(formatter, "AB: fix", l("AB", "https://host1/AB"), t(": fix"));

public void testMultipleProjects() throws BugtraqException {
final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/%PROJECT%-%BUGID%", null, "%PROJECT%-\\d+", "\\d+", null, "JRA,JRB,JRC"));
doTest(formatter, "JRA-7399: Email subject formatting", l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(": Email subject formatting"));
doTest(formatter, " JRA-7399, JRB-7398: Email subject formatting", t(" "), l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(", "), l("JRB-7398", "https://jira.atlassian.com/browse/JRB-7398"), t(": Email subject formatting"));
doTest(formatter, "Fixed JRC-7399", t("Fixed "), l("JRC-7399", "https://jira.atlassian.com/browse/JRC-7399"));
}
// Utils ==================================================================
private BugtraqFormatter createFormatter(BugtraqConfigEntry ... entries) {
private BugtraqFormatter createFormatter(BugtraqEntry ... entries) {
return new BugtraqFormatter(new BugtraqConfig(Arrays.asList(entries)));
}
private BugtraqConfigEntry createEntry(String url, @Nullable String filterRegex, @Nullable String linkRegex, @NotNull String idRegex, @Nullable String linkText, @Nullable String projectsList) throws BugtraqException {
final List<String> projects;
if (projectsList != null) {
projects = new ArrayList<>();
final StringTokenizer tokenizer = new StringTokenizer(projectsList, ",", false);
while (tokenizer.hasMoreTokens()) {
projects.add(tokenizer.nextToken());
}
}
else {
projects = null;
}
return new BugtraqConfigEntry(url, idRegex, linkRegex, filterRegex, linkText, projects);
private BugtraqEntry createEntry(String url, @Nullable String filterRegex, @Nullable String linkRegex, @NotNull String idRegex, @Nullable String linkText) throws BugtraqException {
return new BugtraqEntry(url, idRegex, linkRegex, filterRegex, linkText);
}

@@ -118,0 +97,0 @@

@@ -31,3 +31,3 @@ /*

import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.junit.BeforeClass;

@@ -34,0 +34,0 @@ import org.junit.Test;

@@ -39,3 +39,3 @@ /*

import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.eclipse.jgit.lib.Config;

@@ -42,0 +42,0 @@ import org.eclipse.jgit.storage.file.FileBasedConfig;

@@ -64,35 +64,7 @@ /*

public void testEscapeForHtml() throws Exception {
String input = "\t & < > \"";
String outputNoChange = "\t &amp; &lt; &gt; &quot;";
String outputChange = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&nbsp;&lt;&nbsp;&gt;&nbsp;&quot;";
String input = "& < > \" \t";
String outputNoChange = "&amp; &lt; &gt; &quot; \t";
String outputChange = "&amp;&nbsp;&lt;&nbsp;&gt;&nbsp;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
assertEquals(outputNoChange, StringUtils.escapeForHtml(input, false));
assertEquals(outputChange, StringUtils.escapeForHtml(input, true));
input = "a\tb";
outputNoChange = "a\tb";
outputChange = "a&nbsp;&nbsp;&nbsp;b";
assertEquals(outputNoChange, StringUtils.escapeForHtml(input, false));
assertEquals(outputChange, StringUtils.escapeForHtml(input, true));
input = "\ta b\t";
outputNoChange = "\ta b\t";
outputChange = "&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;b&nbsp;";
assertEquals(outputNoChange, StringUtils.escapeForHtml(input, false));
assertEquals(outputChange, StringUtils.escapeForHtml(input, true));
input = "\t <> \t";
outputNoChange = "\t &lt;&gt; \t";
outputChange = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
assertEquals(outputNoChange, StringUtils.escapeForHtml(input, false));
assertEquals(outputChange, StringUtils.escapeForHtml(input, true));
String tabs = "\t";
int tabSpaces;
int expectedLength;
for (int i = 0; i < 50; i++) {
tabSpaces = 4 - i % 4;
expectedLength = (i + tabSpaces) * 6; // &nbsp; = 6 chars
assertEquals(expectedLength, StringUtils.escapeForHtml(tabs, true).length());
tabs = " " + tabs;
}
}

@@ -99,0 +71,0 @@

@@ -18,5 +18,2 @@ /*

import com.gitblit.Constants;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.TeamModel;
import org.junit.Test;

@@ -26,4 +23,2 @@

import java.util.List;
/**

@@ -59,46 +54,2 @@ * @author Alfred Schmid

@Test
public void getRepositoryPermissionsMultipleTeams()
{
TeamModel aTeam = new TeamModel("A team");
aTeam.addRepositoryPermission("RW+:acerepo.git");
aTeam.addRepositoryPermission("V:boobrepo.git");
TeamModel bTeam = new TeamModel("Team B");
bTeam.addRepositoryPermission("R:acerepo.git");
bTeam.addRepositoryPermission("RWC:boobrepo.git");
UserModel user = new UserModel("tessiur");
user.teams.add(aTeam);
user.teams.add(bTeam);
user.addRepositoryPermission("RW+:myrepo.git");
List<RegistrantAccessPermission> repoPerms = user.getRepositoryPermissions();
int found = 0;
for (RegistrantAccessPermission p : repoPerms) {
switch (p.registrant) {
case "acerepo.git":
assertEquals("Expected REWIND(RW+) permission for " + p.registrant, Constants.AccessPermission.REWIND, p.permission);
found++;
break;
case "boobrepo.git":
assertEquals("Expected CREATE(RWC) permission for " + p.registrant, Constants.AccessPermission.CREATE, p.permission);
found++;
break;
case "myrepo.git":
assertEquals("Expected REWIND(RW+) permission for " + p.registrant, Constants.AccessPermission.REWIND, p.permission);
found++;
break;
default:
fail("Unknown repository registrant " + p.registrant);
break;
}
}
assertEquals("Repostory permissions missing in list.", 3, found);
}
}
# Security Policy
## Reporting a Vulnerability
The Gitblit team takes security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
To report a security issue, please send an email to the following email address and include the word "SECURITY" in the subject line.
```
gitblitorg@gmail.com
```
# Nightly build of a snapshot version
# and a docker image which is pushed
# to a docker registry
name: Nightly image build and push
on:
workflow_dispatch:
inputs:
forced:
description: 'Force run, independent of new commits'
required: false
default: 'false'
schedule:
- cron: '33 1 * * *'
jobs:
# Check if new commits were added since the last time this workflow ran.
# The Github cache is used for this, using the SHA as the key.
check_commits:
name: Check for new commits
runs-on: ubuntu-latest
outputs:
build: ${{ steps.cache-sha.outputs.cache-hit == false }}
steps:
- name: Cache marker for latest commit
uses: actions/cache@v3
id: cache-sha
with:
key: sha-${{ github.sha }}
path: timestamp.txt
- name: Register latest commit
if: ${{ steps.cache-sha.outputs.cache-hit == false }}
run: |
echo "Current commit $GITHUB_SHA has no cache hit."
date > timestamp.txt
echo "Build job should be triggered now"
cat timestamp.txt
- name: Stop on no new commit
if: ${{ steps.cache-sha.outputs.cache-hit }}
run: |
echo "Current commit $GITHUB_SHA was already seen."
echo "Build job should be skipped."
[ -f timestamp.txt ] && cat timestamp.txt
# Build Gitblit GO so that it can be packed into a docker image.
# The built tarball is saved as an artefact, it can be downloaded
# by interested parties.
# We could even do better and check if paths of source files changed,
# but that is not that easy, so we build on any commit.
build:
name: build GO
runs-on: ubuntu-latest
needs: check_commits
if: ${{ needs.check_commits.outputs.build == 'true' || github.event.inputs.forced == 'true' }}
steps:
- name: Checkout Gitblit
uses: actions/checkout@v3
with:
submodules: true
- name: Setup Java 8
uses: actions/setup-java@v3
with:
java-version: 8
distribution: 'temurin'
- name: Report Java version
run: |
java -version
javac -version
- name: Build GO with Ant
run: ant buildGO
- name: Save built Gitblit package
if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' }}
uses: actions/upload-artifact@v3
with:
name: gitblit-nightly
path: build/target/gitblit-*-SNAPSHOT.tar.gz
# This is a gating job, which checks if the secrets necessary for pushing an image
# to the docker hub are present in the repository. This way this workflow can be
# present in repos which cannot upload to the docker hub.
secret-gate:
name: Gate job checking for docker hub secret
runs-on: ubuntu-latest
needs: build
outputs:
build_docker: ${{steps.check-dh-login.outputs.secrets_present}}
steps:
- name: Check if we have the necessary data for docker
id: check-dh-login
run: |
if [[ -n "${{secrets.DOCKERHUB_GB_TOKEN}}" && -n "${{secrets.DOCKERHUB_GB_USER}}" ]] ; then
echo "secrets_present=true" >> $GITHUB_OUTPUT
else
echo "No Docker Hub login data found. Skipping Docker."
fi
# Only if the gating job signals success will this job run and build and push the docker image
# built for the current snapshot version of Gitblit.
docker:
name: Build and push nightly docker image
runs-on: ubuntu-latest
if: needs.secret-gate.outputs.build_docker == 'true' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop')
needs: secret-gate
env:
GH_ORG: gitblit
GITBLIT_VERSION: SNAPSHOT
steps:
- name: Checkout gitblit-docker
uses: actions/checkout@v3
with:
repository: ${{ env.GH_ORG }}/gitblit-docker
ref: master
fetch-depth: 2
- name: Download Gitblit nightly build
uses: actions/download-artifact@v3
id: get-gb
with:
name: gitblit-nightly
- name: Extract snapshot version
id: gb-version
run: |
for file in $(ls -1 ${{steps.get-gb.outputs.download-path}}) ; do
if [[ "$file" = gitblit-*.gz ]] ; then gbver=$file ; fi
done
gbver=${gbver%.tar.gz}
gbver=${gbver##*gitblit-}
echo "Version detected: $gbver"
echo "GITBLIT_VERSION=$gbver" >> "${GITHUB_ENV}"
echo "gb-version=$gbver" >> $GITHUB_OUTPUT
- name: Generate Dockerfile for snapshot image
run: |
generate/generate_dockerfile.sh -v ${{ steps.gb-version.outputs.gb-version }} > generate/Dockerfile
echo "BUILD_DATE=$(date +%Y-%m-%dT%H:%M:%S)" >> "${GITHUB_ENV}"
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_GB_USER }}
password: ${{ secrets.DOCKERHUB_GB_TOKEN }}
- name: Build snapshot docker image
uses: docker/build-push-action@v3
with:
file: generate/Dockerfile
context: .
load: true
tags: gitblit/gitblit:nightly
labels: |
org.label-schema.vcs-ref=${{github.sha}}
org.label-schema.build-date=${{env.BUILD_DATE}}
org.opencontainers.image.revision=${{ env.GITBLIT_GIT_SHA }}
org.opencontainers.image.created=${{ env.BUILD_DATE }}
- name: Install Goss for testing the docker image
uses: e1himself/goss-installation-action@v1.0.4
with:
version: 'v0.3.16'
- name: Test docker container - normal mode
env:
GOSS_WAIT_OPTS: "-r 15s -s 5s > /dev/null"
run: |
dgoss run -p 8080:8080 -p 8443:8443 gitblit/gitblit:nightly
- name: Test docker container - bind mount
env:
GOSS_WAIT_OPTS: "-r 15s -s 5s > /dev/null"
run: |
mkdir gitblit-data
mkdir gitblit-data/etc
echo "This should not be overwritten" > gitblit-data/etc/gitblit.properties
echo "include = gitblit-docker.properties" >> gitblit-data/etc/gitblit.properties
sed -e '/mode: / d' -e '/group: / d' goss.yaml > gitblit-data/goss.yaml
cp goss_wait.yaml gitblit-data/
GOSS_FILES_PATH=gitblit-data dgoss run -p 8080:8080 -p 8443:8443 -v "$PWD/gitblit-data":/var/opt/gitblit gitblit/gitblit:nightly
[ -d gitblit-data/srv/git ] || exit 1
[ -f gitblit-data/etc/defaults.properties ] || exit 1
grep --quiet "This should not be overwritten" gitblit-data/etc/gitblit.properties || exit 1
sudo rm -rf gitblit-data
- name: Test docker container - tmpfs
env:
GOSS_WAIT_OPTS: "-r 15s -s 5s > /dev/null"
run: |
dgoss run -p 8080:8080 -p 8443:8443 --tmpfs /var/opt/gitblit/temp gitblit/gitblit:nightly
# Delete the artifact unless this is the official Gitblit repo
- uses: geekyeggo/delete-artifact@v2
if: ${{ github.repository != 'gitblit/gitblit' }}
with:
name: gitblit-nightly
failOnError: false
- name: Push docker image to registry
uses: docker/build-push-action@v3
with:
file: generate/Dockerfile
context: .
push: true
tags: gitblit/gitblit:nightly
labels: |
org.label-schema.vcs-ref=${{github.sha}}
org.label-schema.build-date=${{env.BUILD_DATE}}
/*
* Copyright (c) 2013 by syntevo GmbH. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of syntevo GmbH nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.syntevo.bugtraq;
import java.util.*;
import org.jetbrains.annotations.*;
public final class BugtraqConfigEntry {
// Fields =================================================================
private final String url;
private final List<String> projects;
private final List<BugtraqEntry> entries;
// Setup ==================================================================
public BugtraqConfigEntry(@NotNull String url, @NotNull String logIdRegex, @Nullable String logLinkRegex, @Nullable String logFilterRegex, @Nullable String logLinkText, @Nullable List<String> projects) throws BugtraqException {
this.url = url;
this.projects = projects;
this.entries = new ArrayList<>();
if (projects == null) {
entries.add(new BugtraqEntry(url, logIdRegex, logLinkRegex, logFilterRegex, logLinkText));
}
else {
for (String project : projects) {
final String projectUrl = this.url.replace("%PROJECT%", project);
final String projectLogIdRegex = logIdRegex.replace("%PROJECT%", project);
final String projectLogLinkRegex = logLinkRegex != null ? logLinkRegex.replace("%PROJECT%", project) : null;
final String projectLogFilterRegex = logFilterRegex != null ? logFilterRegex.replace("%PROJECT%", project) : null;
final String projectLogLinkText = logLinkText != null ? logLinkText.replace("%PROJECT%", project) : null;
entries.add(new BugtraqEntry(projectUrl, projectLogIdRegex, projectLogLinkRegex, projectLogFilterRegex, projectLogLinkText));
}
}
}
// Accessing ==============================================================
@NotNull
public String getUrl() {
return url;
}
@Nullable
public List<String> getProjects() {
return projects != null ? Collections.unmodifiableList(projects) : null;
}
public List<BugtraqEntry> getEntries() {
return entries;
}
}
<!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="fr"
lang="fr">
<body>
<wicket:extend>
<div class="container">
<div class="markdown">
<div class="row">
<div class="span10 offset1">
<h3><center>D&eacute;p&ocirc;t vide</center></h3>
<div class="alert alert-info">
<span wicket:id="repository" style="font-weight: bold;">[repository]</span> est un d&eacute;p&ocirc;t vide, Gitblit ne peut pas le visualiser.
<p></p>
S'il vous pla&icirc;t, envoyer quelques commits dans <span wicket:id="pushurl"></span>
<hr/>
Après avoir envoy&eacute; (push) des commits, vous pouvez <b>rafra&icirc;chir</b> cette page pour visualiser votre d&eacute;p&ocirc;t.
</div>
<h3><center>Cr&eacute;er un nouveau r&eacute;f&eacute;rentiel en ligne de commande</center></h3>
<pre wicket:id="createSyntax"></pre>
<h3><center>D&eacute;poser un d&eacute;p&ocirc;t existant en ligne de commande</center></h3>
<pre wicket:id="existingSyntax"></pre>
<div class="span8 offset1">
<h2><center>Apprendre Git</center></h2>
<p>Si vous n'&ecirc;tes pas sûr de vous sur l'utilisation de ces commandes, envisagez de consulter le <a href="http://book.git-scm.com">Git Community Book (Livre de la communaut&eacute; Git)</a> pour mieux comprendre comment utiliser Git.</p>
<h4>Clients Git "Open Source"</h4>
<table>
<tbody>
<tr><td><a href="http://git-scm.com">Git</a></td><td>Version officielle de Git, en ligne de commande</td></tr>
<tr><td><a href="http://tortoisegit.googlecode.com">TortoiseGit</a></td><td>Int&eacute;gration de Git dans l'explorateur de fichiers Windows (n&eacute;cessite l'application officielle Git, en ligne de commande)</td></tr>
<tr><td><a href="http://eclipse.org/egit">Eclipse/EGit</a></td><td>Module Git pour l'IDE Eclipse (bas&eacute; sur JGit, comme Gitblit)</td></tr>
<tr><td><a href="http://gitextensions.github.io">Git Extensions</a></td><td>Client pour Git &eacute;crit en C#, int&eacute;gr&eacute; &agrave; l'Explorateur de fichier de Windows et &agrave; Visual Studio</td></tr>
<tr><td><a href="http://rowanj.github.io/gitx/">GitX-dev</a></td><td>Client Git pour Mac OS X</td></tr>
</tbody>
</table>
<h4>Clients Git propri&eacute;taire</h4>
<table>
<tbody>
<tr><td><a href="http://www.syntevo.com/smartgithg">SmartGit/Hg</a></td><td>Un client Git et Mercurial &eacute;crit Java pour Windows, Mac, et Linux</td></tr>
<tr><td><a href="http://www.sourcetreeapp.com/">SourceTree</a></td><td>Un client Git et Mercurial gratuit pour Windows et Mac</td></tr>
<tr><td><a href="http://www.git-tower.com/">Tower</a></td><td>Client Git pour Mac OS</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</wicket:extend>
</body>
</html>
/*!
* clipboard.js v2.0.11
* https://clipboardjs.com/
*
* Licensed MIT © Zeno Rocha
*/
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{container:document.body},n="";return"string"==typeof t?n=o(t,e):t instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(null==t?void 0:t.type)?n=o(t.value,e):(n=r()(t),c("copy")),n};function l(t){return(l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var s=function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},e=t.action,n=void 0===e?"copy":e,o=t.container,e=t.target,t=t.text;if("copy"!==n&&"cut"!==n)throw new Error('Invalid "action" value, use either "copy" or "cut"');if(void 0!==e){if(!e||"object"!==l(e)||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===n&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===n&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes')}return t?f(t,{container:o}):e?"cut"===n?a(e):f(e,{container:o}):void 0};function p(t){return(p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function d(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function y(t,e){return(y=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function h(n){var o=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}();return function(){var t,e=v(n);return t=o?(t=v(this).constructor,Reflect.construct(e,arguments,t)):e.apply(this,arguments),e=this,!(t=t)||"object"!==p(t)&&"function"!=typeof t?function(t){if(void 0!==t)return t;throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}(e):t}}function v(t){return(v=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function m(t,e){t="data-clipboard-".concat(t);if(e.hasAttribute(t))return e.getAttribute(t)}var b=function(){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&y(t,e)}(r,i());var t,e,n,o=h(r);function r(t,e){var n;return function(t){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}(this),(n=o.call(this)).resolveOptions(e),n.listenClick(t),n}return t=r,n=[{key:"copy",value:function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{container:document.body};return f(t,e)}},{key:"cut",value:function(t){return a(t)}},{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof t?[t]:t,e=!!document.queryCommandSupported;return t.forEach(function(t){e=e&&!!document.queryCommandSupported(t)}),e}}],(e=[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===p(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=u()(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget,n=this.action(e)||"copy",t=s({action:n,container:this.container,target:this.target(e),text:this.text(e)});this.emit(t?"success":"error",{action:n,text:t,trigger:e,clearSelection:function(){e&&e.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(t){return m("action",t)}},{key:"defaultTarget",value:function(t){t=m("target",t);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(t){return m("text",t)}},{key:"destroy",value:function(){this.listener.destroy()}}])&&d(t.prototype,e),n&&d(t,n),r}()},828:function(t){var e;"undefined"==typeof Element||Element.prototype.matches||((e=Element.prototype).matches=e.matchesSelector||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector),t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}},438:function(t,e,n){var u=n(828);function i(t,e,n,o,r){var i=function(e,n,t,o){return function(t){t.delegateTarget=u(t.target,n),t.delegateTarget&&o.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}}t.exports=function(t,e,n,o,r){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,o,r)}))}},879:function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},370:function(t,e,n){var f=n(879),l=n(438);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!f.string(e))throw new TypeError("Second argument must be a String");if(!f.fn(n))throw new TypeError("Third argument must be a Function");if(f.node(t))return c=e,a=n,(u=t).addEventListener(c,a),{destroy:function(){u.removeEventListener(c,a)}};if(f.nodeList(t))return o=t,r=e,i=n,Array.prototype.forEach.call(o,function(t){t.addEventListener(r,i)}),{destroy:function(){Array.prototype.forEach.call(o,function(t){t.removeEventListener(r,i)})}};if(f.string(t))return t=t,e=e,n=n,l(document.body,t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var o,r,i,u,c,a}},817:function(t){t.exports=function(t){var e,n="SELECT"===t.nodeName?(t.focus(),t.value):"INPUT"===t.nodeName||"TEXTAREA"===t.nodeName?((e=t.hasAttribute("readonly"))||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),e||t.removeAttribute("readonly"),t.value):(t.hasAttribute("contenteditable")&&t.focus(),n=window.getSelection(),(e=document.createRange()).selectNodeContents(t),n.removeAllRanges(),n.addRange(e),n.toString());return n}},279:function(t){function e(){}e.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,u=o.length;i<u;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=e,t.exports.TinyEmitter=e}},r={},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,{a:e}),e},o.d=function(t,e){for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o(686).default;function o(t){if(r[t])return r[t].exports;var e=r[t]={exports:{}};return n[t](e,e.exports,o),e.exports}var n,r});
// Instantiate the clipboarding
var clipboard = new ClipboardJS('.ctcbtn');
clipboard.on('success', function (e) {
showTooltip(e.trigger, "Copied!");
});
clipboard.on('error', function (e) {
showTooltip(e.trigger, fallbackMessage(e.action));
});
// Attach events to buttons to clear tooltip again
var btns = document.querySelectorAll('.ctcbtn');
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener('mouseleave', clearTooltip);
btns[i].addEventListener('blur', clearTooltip);
}
function findTooltipped(elem) {
do {
if (elem.classList.contains('tooltipped')) return elem;
elem = elem.parentElement;
} while (elem != null);
return null;
}
// Show or hide tooltip by setting the tooltipped-active class
// on a parent that contains tooltipped. Since the copy button
// could be and image, or be hidden after clicking, the tooltipped
// element might be higher in the hierarchy.
var ttset;
function showTooltip(elem, msg) {
let ttelem = findTooltipped(elem);
if (ttelem != null) {
ttelem.classList.add('tooltipped-active');
ttelem.setAttribute('data-tt-text', msg);
ttset=Date.now();
}
else {
console.warn("Could not find any tooltipped element for clipboard button.", elem);
}
}
function clearTooltip(e) {
let ttelem = findTooltipped(e.currentTarget);
if (ttelem != null) {
let now = Date.now();
if (now - ttset < 500) {
// Give the tooltip some time to display
setTimeout(function(){ttelem.classList.remove('tooltipped-active')}, 1000)
}
else {
ttelem.classList.remove('tooltipped-active');
}
}
else {
console.warn("Could not find any tooltipped element for clipboard button.", e.currentTarget);
}
}
// If the API is not supported, at least fall back to a message saying
// that now that the text is selected, Ctrl-C can be used.
// This is still a problem in the repo URL dropdown. When it is hidden, Ctrl-C doesn't work.
function fallbackMessage(action) {
var actionMsg = "";
if (/Mac/i.test(navigator.userAgent)) {
actionMsg = "Press ⌘-C to copy";
}
else {
actionMsg = "Press Ctrl-C to copy";
}
return actionMsg;
}
package com.gitblit.transport.ssh;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.security.KeyPair;
import java.util.Iterator;
import static org.junit.Assert.*;
public class FileKeyPairProviderTest
{
@Rule
public TemporaryFolder testFolder = new TemporaryFolder();
private void generateKeyPair(File file, String algorithm, int keySize) {
if (file.exists()) {
file.delete();
}
SshDaemon.generateKeyPair(file, algorithm, keySize);
}
@Test
public void loadKeysEddsa() throws IOException
{
File file = testFolder.newFile("eddsa.pem");
generateKeyPair(file, "EdDSA", 0);
FileKeyPairProvider hostKeyPairProvider = new FileKeyPairProvider();
hostKeyPairProvider.setFiles(new String [] { file.getPath() });
Iterable<KeyPair> keyPairs = hostKeyPairProvider.loadKeys();
Iterator<KeyPair> iterator = keyPairs.iterator();
assertTrue(iterator.hasNext());
KeyPair keyPair = iterator.next();
assertNotNull(keyPair);
assertEquals("Unexpected key pair type", "EdDSA", keyPair.getPrivate().getAlgorithm());
}
@Test
public void loadKeysEd25519() throws IOException
{
File file = testFolder.newFile("ed25519.pem");
generateKeyPair(file, "ED25519", 0);
FileKeyPairProvider hostKeyPairProvider = new FileKeyPairProvider();
hostKeyPairProvider.setFiles(new String [] { file.getPath() });
Iterable<KeyPair> keyPairs = hostKeyPairProvider.loadKeys();
Iterator<KeyPair> iterator = keyPairs.iterator();
assertTrue(iterator.hasNext());
KeyPair keyPair = iterator.next();
assertNotNull(keyPair);
assertEquals("Unexpected key pair type", "Ed25519", keyPair.getPrivate().getAlgorithm());
}
@Test
public void loadKeysECDSA() throws IOException
{
File file = testFolder.newFile("ecdsa.pem");
generateKeyPair(file, "ECDSA", 0);
FileKeyPairProvider hostKeyPairProvider = new FileKeyPairProvider();
hostKeyPairProvider.setFiles(new String [] { file.getPath() });
Iterable<KeyPair> keyPairs = hostKeyPairProvider.loadKeys();
Iterator<KeyPair> iterator = keyPairs.iterator();
assertTrue(iterator.hasNext());
KeyPair keyPair = iterator.next();
assertNotNull(keyPair);
assertEquals("Unexpected key pair type", "ECDSA", keyPair.getPrivate().getAlgorithm());
}
@Test
public void loadKeysRSA() throws IOException
{
File file = testFolder.newFile("rsa.pem");
generateKeyPair(file, "RSA", 4096);
FileKeyPairProvider hostKeyPairProvider = new FileKeyPairProvider();
hostKeyPairProvider.setFiles(new String [] { file.getPath() });
Iterable<KeyPair> keyPairs = hostKeyPairProvider.loadKeys();
Iterator<KeyPair> iterator = keyPairs.iterator();
assertTrue(iterator.hasNext());
KeyPair keyPair = iterator.next();
assertNotNull(keyPair);
assertEquals("Unexpected key pair type", "RSA", keyPair.getPrivate().getAlgorithm());
}
@Test
public void loadKeysDefault() throws IOException
{
File rsa = testFolder.newFile("rsa.pem");
generateKeyPair(rsa, "RSA", 2048);
File ecdsa = testFolder.newFile("ecdsa.pem");
generateKeyPair(ecdsa, "ECDSA", 0);
File eddsa = testFolder.newFile("eddsa.pem");
generateKeyPair(eddsa, "EdDSA", 0);
File ed25519 = testFolder.newFile("ed25519.pem");
generateKeyPair(ed25519, "ED25519", 0);
FileKeyPairProvider hostKeyPairProvider = new FileKeyPairProvider();
hostKeyPairProvider.setFiles(new String [] { ecdsa.getPath(), eddsa.getPath(), rsa.getPath(), ed25519.getPath() });
Iterable<KeyPair> keyPairs = hostKeyPairProvider.loadKeys();
Iterator<KeyPair> iterator = keyPairs.iterator();
assertTrue(iterator.hasNext());
KeyPair keyPair = iterator.next();
assertNotNull(keyPair);
assertEquals("Unexpected key pair type", "ECDSA", keyPair.getPrivate().getAlgorithm());
assertTrue(iterator.hasNext());
keyPair = iterator.next();
assertNotNull(keyPair);
assertEquals("Unexpected key pair type", "EdDSA", keyPair.getPrivate().getAlgorithm());
assertTrue(iterator.hasNext());
keyPair = iterator.next();
assertNotNull(keyPair);
assertEquals("Unexpected key pair type", "RSA", keyPair.getPrivate().getAlgorithm());
assertTrue(iterator.hasNext());
keyPair = iterator.next();
assertNotNull(keyPair);
assertEquals("Unexpected key pair type", "Ed25519", keyPair.getPrivate().getAlgorithm());
assertFalse(iterator.hasNext());
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet