Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Setting "Default Language" when creating user #1198

Merged
merged 3 commits into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions .classpath
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<classpathentry kind="lib" path="ext/httpcore-4.3.3.jar" sourcepath="ext/src/httpcore-4.3.3.jar" />
<classpathentry kind="lib" path="ext/commons-logging-1.1.3.jar" sourcepath="ext/src/commons-logging-1.1.3.jar" />
<classpathentry kind="lib" path="ext/commons-codec-1.7.jar" sourcepath="ext/src/commons-codec-1.7.jar" />
<classpathentry kind="lib" path="ext/org.eclipse.jdt.annotation-1.1.0.jar" />
<classpathentry kind="lib" path="ext/org.eclipse.jdt.annotation-1.1.0.jar" sourcepath="ext/src/org.eclipse.jdt.annotation-1.1.0.jar" />
<classpathentry kind="lib" path="ext/org.eclipse.jgit.http.server-4.1.1.201511131810-r.jar" sourcepath="ext/src/org.eclipse.jgit.http.server-4.1.1.201511131810-r.jar" />
<classpathentry kind="lib" path="ext/bcprov-jdk15on-1.52.jar" sourcepath="ext/src/bcprov-jdk15on-1.52.jar" />
<classpathentry kind="lib" path="ext/bcmail-jdk15on-1.52.jar" sourcepath="ext/src/bcmail-jdk15on-1.52.jar" />
Expand Down Expand Up @@ -94,10 +94,5 @@
<classpathentry kind="lib" path="ext/mockito-core-1.10.19.jar" sourcepath="ext/src/mockito-core-1.10.19.jar" />
<classpathentry kind="lib" path="ext/objenesis-2.1.jar" sourcepath="ext/src/objenesis-2.1.jar" />
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" />
<classpathentry kind="src" path="src/main/dagger">
<attributes>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin/classes" />
</classpath>
4 changes: 3 additions & 1 deletion gitblit.iml
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,9 @@
<root url="jar://$MODULE_DIR$/ext/org.eclipse.jdt.annotation-1.1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
<SOURCES>
<root url="jar://$MODULE_DIR$/ext/src/org.eclipse.jdt.annotation-1.1.0.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
Expand Down
111 changes: 111 additions & 0 deletions src/main/distrib/data/certs/instructions.tmpl_zh_TW
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
********************************************************************************
Gitblit 伺服器 $serverHostname 所需之 SSL 用戶端憑證
********************************************************************************

$userDisplayname 您好,

伺服器 $serverHostname 所需要的私鑰,公鑰以及Gitblit簽證檔案(CA)存放於 $username.p12, PKCS#12 certificate store[1] 以及 $username.pem.

兩種證書皆受密碼保護.
密碼提示: $storePasswordHint


Git 憑證匯入步驟
=============================================

附件之 PEM 檔案可以直接匯入至您的git程式裡.

git config [--global] http.sslCert path/to/$username.pem

PEM檔案受密碼保護,因此匯入過程會提示多次. 如果您偏好不使用密碼,您需要另外匯出無密碼之私鑰後,再匯入git程式裡.

openssl rsa -in path/to/$username.pem -out path/to/$username.key
git config [--global] http.sslKey path/to/$username.key

此外,您應該妥善保管已經解除密碼保護之私鑰.

註:
如果沒有匯出私鑰, 有些早期git版本將會發生匯入失敗問題,例如:Ubuntu 12.04 with git 1.7.9.5.


Firefox 憑證匯入步驟
=============================================

Firefox 有自己的證書管理介面.

1. 點選 "選項->進階->憑證"
2. 點選 "檢視憑證清單"
3. 切換至 "您的憑證"
4. 點選 "匯入(M)"
5. 選擇電腦中的憑證檔案 $username.p12
6. 輸入憑證檔案所需的密碼
7. 切換至"憑證機構"
8. 找到 "Gitblit Certificate Authority" 憑證
9. 點選"編輯信任(E)"
10.選擇信任網站.


Chrome/IE (Windows) 憑證匯入步驟
=============================================

在Windows作業系統下, Chrome 與 IE 共用相同的憑證設定.

IE
------------------------------------
1. 選擇 "網際網路選項->內容"
2. 點選"憑證"

Chrome
------------------------------------
1. 選擇 "設定->顯示進階設定->HTTP/SSL"
2. 點選"管理憑證"

共同步驟 (Windows)
------------------------------------
3. 切換至 "個人"
4. 點選"匯入(I)"
5. 依照指示匯入.
請切換匯入檔案類型為p12並且找到 $username.p12 這個憑證檔案
6. 輸入憑證檔案保護密碼
7. 由於主要發放憑證單位(CA)與個人憑證檔案皆儲存於 $username.p12, 因此匯入時候,必須選擇 "自動根據憑證類型來選擇憑證存放區".
如果選擇預設值匯入, 將不會安裝主要發放憑證單位(CA)


Chrome (Linux) Installation Instructions
=============================================

On Linux, Chrome maintains it's own certificate store.

1. Navigate to Settings->Show Advanced Settings->HTTP/SSL
2. Click the "Manage Certificates..." button
3. Navigate your filesystem and select $username.p12
4. At the password prompt enter the certificate store password
You have now imported your private key, public certificate, and the CA certificate
but now we must manually set the trust settings of the CA certificate.
5. Switch to the "Authorities" tab
6. Scroll down and find "Gitblit-> Gitblit Certificate Authority"
7. Select it and click "Edit Trust..."
8. Check "This certificate can identify websites" and click OK.


Chrome/Safari (Mac OS X) Installation Instructions
=============================================

On Mac OS X, Chrome and Safari both use Keychain Access to store certificates
so configuring one will automatically apply for both.

1. Double-click $username.pem
2. At the password prompt enter the certificate store password
You have now imported your private key, public certificate, and the CA certificate
but now we must manually set the trust settings of the CA certificate.
3. Find the Gitblit Certificate Authority certificate, it should have a red
indicator meaning untrusted, and double-click it.
4. Open the "Trust" disclosure triangle and change "When using this certificate"
to "Always Trust".
5. Close the certificate view and enter your system password to save the changes
to your keychain.


[1] PKCS#12 is one of the standard container formats for sharing private keys and
public certificates.
[2] http://www.openssl.org
5 changes: 5 additions & 0 deletions src/main/distrib/data/certs/mail.tmpl_zh_TW
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$userDisplayname 您好

伺服器 $serverHostname 所需要的私鑰,公鑰以及Gitblit簽證檔案(CA)已經全部打包並且以zip壓縮檔方式寄給您.

此外,檔案還附上各瀏覽器設定步驟供您參考.
19 changes: 16 additions & 3 deletions src/main/java/com/gitblit/authority/GitblitAuthority.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.mail.Message;
import javax.swing.ImageIcon;
Expand Down Expand Up @@ -98,6 +100,7 @@
import com.gitblit.utils.X509Utils.RevocationReason;
import com.gitblit.utils.X509Utils.X509Log;
import com.gitblit.utils.X509Utils.X509Metadata;
import com.gitblit.wicket.GitBlitWebSession;

/**
* Simple GUI tool for administering Gitblit client certificates.
Expand Down Expand Up @@ -447,7 +450,7 @@ public boolean newCertificate(UserCertificateModel ucm, X509Metadata metadata, b
}

File caKeystoreFile = new File(folder, X509Utils.CA_KEY_STORE);
File zip = X509Utils.newClientBundle(metadata, caKeystoreFile, caKeystorePassword, GitblitAuthority.this);
File zip = X509Utils.newClientBundle(user,metadata, caKeystoreFile, caKeystorePassword, GitblitAuthority.this);

// save latest expiration date
if (ucm.expires == null || metadata.notAfter.before(ucm.expires)) {
Expand Down Expand Up @@ -850,9 +853,19 @@ private boolean sendEmail(UserModel user, X509Metadata metadata, File zip) {
try {
if (mail.isReady()) {
Mailing mailing = Mailing.newPlain();
mailing.subject = "Your Gitblit client certificate for " + metadata.serverHostname;
if( user.getPreferences().getLocale()!=null )
mailing.subject = MessageFormat.format(ResourceBundle.getBundle("com.gitblit.wicket.GitBlitWebApp",user.getPreferences().getLocale()).getString("gb.emailClientCertificateSubject"), metadata.serverHostname);
else
mailing.subject = MessageFormat.format(ResourceBundle.getBundle("com.gitblit.wicket.GitBlitWebApp", Locale.ENGLISH).getString("gb.emailClientCertificateSubject") , metadata.serverHostname);
mailing.setRecipients(user.emailAddress);
String body = X509Utils.processTemplate(new File(folder, X509Utils.CERTS + File.separator + "mail.tmpl"), metadata);
File fileMailTmp = null;
String body = null;
if( (fileMailTmp = new File(folder, X509Utils.CERTS + File.separator + "mail.tmpl"+"_"+user.getPreferences().getLocale())).exists())
body = X509Utils.processTemplate(fileMailTmp, metadata);
else{
fileMailTmp = new File(folder, X509Utils.CERTS + File.separator + "mail.tmpl");
body = X509Utils.processTemplate(fileMailTmp, metadata);
}
if (StringUtils.isEmpty(body)) {
body = MessageFormat.format("Hi {0}\n\nHere is your client certificate bundle.\nInside the zip file are installation instructions.", user.getDisplayName());
}
Expand Down
32 changes: 30 additions & 2 deletions src/main/java/com/gitblit/utils/X509Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,25 @@ public static void addTrustedCertificate(String alias, X509Certificate cert, Fil
*/
public static File newClientBundle(X509Metadata clientMetadata, File caKeystoreFile,
String caKeystorePassword, X509Log x509log) {
return newClientBundle(null,clientMetadata,caKeystoreFile,caKeystorePassword,x509log);
}

/**
* Creates a new client certificate PKCS#12 and PEM store. Any existing
* stores are destroyed. After generation, the certificates are bundled
* into a zip file with a personalized README file.
*
* The zip file reference is returned.
*
* @param user
* @param clientMetadata a container for dynamic parameters needed for generation
* @param caKeystoreFile
* @param caKeystorePassword
* @param x509log
* @return a zip file containing the P12, PEM, and personalized README
*/
public static File newClientBundle(com.gitblit.models.UserModel user,X509Metadata clientMetadata, File caKeystoreFile,
String caKeystorePassword, X509Log x509log) {
try {
// read the Gitblit CA key and certificate
KeyStore store = openKeyStore(caKeystoreFile, caKeystorePassword);
Expand All @@ -755,8 +774,17 @@ public static File newClientBundle(X509Metadata clientMetadata, File caKeystoreF
x509log.log(MessageFormat.format("New client certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getSubjectDN().getName()));

// process template message
String readme = processTemplate(new File(caKeystoreFile.getParentFile(), "instructions.tmpl"), clientMetadata);

String readme = null;
String sInstructionsFileName = "instructions.tmpl";
if( user == null )
readme = processTemplate(new File(caKeystoreFile.getParentFile(),sInstructionsFileName), clientMetadata);
else{
File fileInstructionsTmp = null;
if( (fileInstructionsTmp = new File(caKeystoreFile.getParentFile(),sInstructionsFileName+"_"+user.getPreferences().getLocale())).exists() )
readme = processTemplate(fileInstructionsTmp,clientMetadata);
else
readme = processTemplate(new File(caKeystoreFile.getParentFile(),sInstructionsFileName),clientMetadata);
}
// Create a zip bundle with the p12, pem, and a personalized readme
File zipFile = new File(targetFolder, clientMetadata.commonName + ".zip");
if (zipFile.exists()) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
Original file line number Diff line number Diff line change
Expand Up @@ -783,3 +783,4 @@ gb.deletePatchsetSuccess = Deleted Patchset {0}.
gb.deletePatchsetFailure = Error deleting Patchset {0}.
gb.referencedByCommit = Referenced by commit.
gb.referencedByTicket = Referenced by ticket.
gb.emailClientCertificateSubject = Your Gitblit client certificate for {0}
Original file line number Diff line number Diff line change
Expand Up @@ -781,3 +781,4 @@ gb.deletePatchsetSuccess = \u5df2\u522a\u9664 Patchset {0}.
gb.deletePatchsetFailure = \u522a\u9664 Patchset {0} \u932f\u8aa4.
gb.referencedByCommit = Referenced by commit.
gb.referencedByTicket = Referenced by ticket.
gb.emailClientCertificateSubject = \u4F3A\u670D\u5668 {0} \u9023\u7DDA\u6191\u8B49
11 changes: 6 additions & 5 deletions src/main/java/com/gitblit/wicket/pages/EditUserPage.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@
<tr><th><wicket:message key="gb.confirmPassword"></wicket:message></th><td class="edit"><input type="password" wicket:id="confirmPassword" size="30" tabindex="3" /></td></tr>
<tr><th><wicket:message key="gb.displayName"></wicket:message></th><td class="edit"><input type="text" wicket:id="displayName" size="30" tabindex="4" /></td></tr>
<tr><th><wicket:message key="gb.emailAddress"></wicket:message></th><td class="edit"><input type="text" wicket:id="emailAddress" size="30" tabindex="5" /></td></tr>
<tr><th><wicket:message key="gb.canAdmin"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canAdmin" tabindex="6" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canAdminDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.canCreate"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canCreate" tabindex="7" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canCreateDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.canFork"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canFork" tabindex="8" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canForkDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.excludeFromFederation"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="excludeFromFederation" tabindex="9" /> &nbsp;<span class="help-inline"><wicket:message key="gb.excludeFromFederationDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.disableUser"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="disabled" tabindex="10" /> &nbsp;<span class="help-inline"><wicket:message key="gb.disableUserDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.languagePreference"></wicket:message></th><td class="edit"><select wicket:id="language" ></select></td></tr>
<tr><th><wicket:message key="gb.canAdmin"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canAdmin" tabindex="7" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canAdminDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.canCreate"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canCreate" tabindex="8" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canCreateDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.canFork"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="canFork" tabindex="9" /> &nbsp;<span class="help-inline"><wicket:message key="gb.canForkDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.excludeFromFederation"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="excludeFromFederation" tabindex="10" /> &nbsp;<span class="help-inline"><wicket:message key="gb.excludeFromFederationDescription"></wicket:message></span></label></td></tr>
<tr><th><wicket:message key="gb.disableUser"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="disabled" tabindex="11" /> &nbsp;<span class="help-inline"><wicket:message key="gb.disableUserDescription"></wicket:message></span></label></td></tr>
</tbody>
</table>
</div>
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/com/gitblit/wicket/pages/EditUserPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.apache.wicket.PageParameters;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.extensions.markup.html.form.palette.Palette;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.util.CollectionModel;
import org.apache.wicket.model.util.ListModel;
Expand Down Expand Up @@ -108,6 +111,30 @@ protected void setupPage(final UserModel userModel) {
final Palette<String> teams = new Palette<String>("teams", new ListModel<String>(
new ArrayList<String>(userTeams)), new CollectionModel<String>(app().users()
.getAllTeamNames()), new StringChoiceRenderer(), 10, false);
Locale locale = userModel.getPreferences().getLocale();
if (locale == null) {
locale = Locale.ENGLISH;
}

List<Language> languages = UserPage.getLanguages();
Language preferredLanguage = null;
if (locale != null) {
String localeCode = locale.getLanguage();
if (!StringUtils.isEmpty(locale.getCountry())) {
localeCode += "_" + locale.getCountry();
}

for (Language lang : languages) {
if (lang.code.equals(localeCode)) {
// language_COUNTRY match
preferredLanguage = lang;
} else if (preferredLanguage != null && lang.code.startsWith(locale.getLanguage())) {
// language match
preferredLanguage = lang;
}
}
}
final IModel<Language> language = Model.of(preferredLanguage);
Form<UserModel> form = new Form<UserModel>("editForm", model) {

private static final long serialVersionUID = 1L;
Expand All @@ -123,6 +150,10 @@ protected void onSubmit() {
error(getString("gb.pleaseSetUsername"));
return;
}
Language lang = language.getObject();
if (lang != null) {
userModel.getPreferences().setLocale(lang.code);
}
// force username to lower-case
userModel.username = userModel.username.toLowerCase();
String username = userModel.username;
Expand Down Expand Up @@ -251,7 +282,10 @@ protected void onSubmit() {
form.add(confirmPasswordField.setEnabled(editCredentials));
form.add(new TextField<String>("displayName").setEnabled(editDisplayName));
form.add(new TextField<String>("emailAddress").setEnabled(editEmailAddress));


DropDownChoice<Language> choice = new DropDownChoice<Language>("language",language,languages );
form.add( choice.setEnabled(languages.size()>0) );
if (userModel.canAdmin() && !userModel.canAdmin) {
// user inherits Admin permission
// display a disabled-yet-checked checkbox
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/gitblit/wicket/pages/Language.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.gitblit.wicket.pages;

import java.io.Serializable;

public class Language implements Serializable {

private static final long serialVersionUID = 1L;

final String name;
final String code;

public Language(String name, String code) {
this.name = name;
this.code = code;
}

@Override
public String toString() {
return name + " (" + code + ")";
}
}
Loading