add personal access token panel #12

This commit is contained in:
Unknwon committed 2014-11-12 06:48:50 -05:00
1 parent 21b9d5fa1f
commit 8c9338a537
20 files changed
+311 -62

No files matched your search

+2 -4
View File
@@ -64,7 +64,7 @@ func checkVersion() {
// Check dependency version.
macaronVer := git.MustParseVersion(strings.Join(strings.Split(macaron.Version(), ".")[:3], "."))
if macaronVer.LessThan(git.MustParseVersion("0.4.0")) {
if macaronVer.LessThan(git.MustParseVersion("0.4.2")) {
log.Fatal(4, "Package macaron version is too old, did you forget to update?(github.com/Unknwon/macaron)")
}
i18nVer := git.MustParseVersion(i18n.Version())
@@ -199,6 +199,7 @@ func runWeb(*cli.Context) {
m.Get("/ssh", user.SettingsSSHKeys)
m.Post("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost)
m.Get("/social", user.SettingsSocial)
m.Combo("/applications").Get(user.SettingsApplications).Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
m.Route("/delete", "GET,POST", user.SettingsDelete)
}, reqSignIn)
m.Group("/user", func() {
@@ -210,9 +211,6 @@ func runWeb(*cli.Context) {
m.Get("/logout", user.SignOut)
})
// FIXME: Legacy
m.Get("/user/:username", ignSignIn, user.Profile)
// Gravatar service.
avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg")
os.MkdirAll("public/img/avatar/", os.ModePerm)
+11
View File
@@ -184,6 +184,7 @@ profile = Profile
password = Password
ssh_keys = SSH Keys
social = Social Accounts
applications = Applications
orgs = Organizations
delete = Delete Account
uid = Uid
@@ -224,6 +225,16 @@ social_desc = This is a list of associated social accounts. Remove any binding t
unbind = Unbind
unbind_success = Social account has been unbound.
manage_access_token = Manage Personal Access Tokens
generate_new_token = Generate New Token
tokens_desc = Tokens you have generated that can be used to access the Gogs API.
new_token_desc = As for now, every token will have full access to your account.
token_name = Token Name
generate_token = Generate Token
generate_token_succees = New access token has been generated successfully! Make sure to copy your new personal access token now. You won't be able to see it again!
delete_token = Delete
delete_token_success = Personal access token has been deleted successfully! Don't forget to update your applications as well.
delete_account = Delete Your Account
delete_prompt = The operation will delete your account permanently, and <strong>CANNOT</strong> be undone!
confirm_delete_account = Confirm Deletion
+1 -1
View File
@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const APP_VER = "0.5.7.1110 Beta"
const APP_VER = "0.5.8.1112 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
+2 -1
View File
@@ -39,7 +39,8 @@ var (
)
func init() {
tables = append(tables, new(User), new(PublicKey), new(Follow), new(Oauth2),
tables = append(tables,
new(User), new(PublicKey), new(Follow), new(Oauth2), new(AccessToken),
new(Repository), new(Watch), new(Star), new(Action), new(Access),
new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone),
new(Mirror), new(Release), new(LoginSource), new(Webhook),
+3 -3
View File
@@ -236,10 +236,10 @@ func GetPublicKeyById(keyId int64) (*PublicKey, error) {
return key, nil
}
// ListPublicKey returns a list of all public keys that user has.
func ListPublicKey(uid int64) ([]*PublicKey, error) {
// ListPublicKeys returns a list of public keys belongs to given user.
func ListPublicKeys(uid int64) ([]*PublicKey, error) {
keys := make([]*PublicKey, 0, 5)
err := x.Find(&keys, &PublicKey{OwnerId: uid})
err := x.Where("owner_id=?", uid).Find(&keys)
if err != nil {
return nil, err
}
+69
View File
@@ -0,0 +1,69 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"errors"
"time"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/uuid"
)
var (
ErrAccessTokenNotExist = errors.New("Access token does not exist")
)
// AccessToken represents a personal access token.
type AccessToken struct {
Id int64
Uid int64
Name string
Sha1 string `xorm:"UNIQUE VARCHAR(40)"`
Created time.Time `xorm:"CREATED"`
Updated time.Time
HasRecentActivity bool `xorm:"-"`
HasUsed bool `xorm:"-"`
}
// NewAccessToken creates new access token.
func NewAccessToken(t *AccessToken) error {
t.Sha1 = base.EncodeSha1(uuid.NewV4().String())
_, err := x.Insert(t)
return err
}
// GetAccessTokenBySha returns access token by given sha1.
func GetAccessTokenBySha(sha string) (*AccessToken, error) {
t := &AccessToken{Sha1: sha}
has, err := x.Get(t)
if err != nil {
return nil, err
} else if !has {
return nil, ErrAccessTokenNotExist
}
return t, nil
}
// ListAccessTokens returns a list of access tokens belongs to given user.
func ListAccessTokens(uid int64) ([]*AccessToken, error) {
tokens := make([]*AccessToken, 0, 5)
err := x.Where("uid=?", uid).Desc("id").Find(&tokens)
if err != nil {
return nil, err
}
for _, t := range tokens {
t.HasUsed = t.Updated.After(t.Created)
t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now())
}
return tokens, nil
}
// DeleteAccessTokenById deletes access token by given ID.
func DeleteAccessTokenById(id int64) error {
_, err := x.Id(id).Delete(new(AccessToken))
return err
}
+23 -5
View File
@@ -20,7 +20,7 @@ import (
)
// SignedInId returns the id of signed in user.
func SignedInId(header http.Header, sess session.Store) int64 {
func SignedInId(req *http.Request, sess session.Store) int64 {
if !models.HasEngine {
return 0
}
@@ -38,20 +38,38 @@ func SignedInId(header http.Header, sess session.Store) int64 {
}
return id
}
// API calls also need to check access token.
if strings.HasPrefix(req.URL.Path, "/api/") {
auHead := req.Header.Get("Authorization")
if len(auHead) > 0 {
auths := strings.Fields(auHead)
if len(auths) == 2 && auths[0] == "token" {
t, err := models.GetAccessTokenBySha(auths[1])
if err != nil {
if err != models.ErrAccessTokenNotExist {
log.Error(4, "GetAccessTokenBySha: %v", err)
}
return 0
}
return t.Uid
}
}
}
return 0
}
// SignedInUser returns the user object of signed user.
func SignedInUser(header http.Header, sess session.Store) *models.User {
func SignedInUser(req *http.Request, sess session.Store) *models.User {
if !models.HasEngine {
return nil
}
uid := SignedInId(header, sess)
uid := SignedInId(req, sess)
if uid <= 0 {
if setting.Service.EnableReverseProxyAuth {
webAuthUser := header.Get(setting.ReverseProxyAuthUser)
webAuthUser := req.Header.Get(setting.ReverseProxyAuthUser)
if len(webAuthUser) > 0 {
u, err := models.GetUserByName(webAuthUser)
if err != nil {
@@ -65,7 +83,7 @@ func SignedInUser(header http.Header, sess session.Store) *models.User {
}
// Check with basic auth.
baHead := header.Get("Authorization")
baHead := req.Header.Get("Authorization")
if len(baHead) > 0 {
auths := strings.Fields(baHead)
if len(auths) == 2 && auths[0] == "Basic" {
-19
View File
@@ -1,19 +0,0 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
"github.com/Unknwon/macaron"
"github.com/macaron-contrib/binding"
)
type AddSSHKeyForm struct {
SSHTitle string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
}
func (f *AddSSHKeyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}
+17
View File
@@ -95,3 +95,20 @@ type ChangePasswordForm struct {
func (f *ChangePasswordForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}
type AddSSHKeyForm struct {
SSHTitle string `form:"title" binding:"Required"`
Content string `form:"content" binding:"Required"`
}
func (f *AddSSHKeyForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}
type NewAccessTokenForm struct {
Name string `form:"name" binding:"Required"`
}
func (f *NewAccessTokenForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}
+7
View File
@@ -33,6 +33,13 @@ func EncodeMd5(str string) string {
return hex.EncodeToString(m.Sum(nil))
}
// Encode string to sha1 hex value.
func EncodeSha1(str string) string {
h := sha1.New()
h.Write([]byte(str))
return hex.EncodeToString(h.Sum(nil))
}
func BasicAuthDecode(encoded string) (user string, name string, err error) {
var s []byte
s, err = base64.StdEncoding.DecodeString(encoded)
+1 -1
View File
@@ -172,7 +172,7 @@ func Contexter() macaron.Handler {
ctx.Data["PageStartTime"] = time.Now()
// Get user from session if logined.
ctx.User = auth.SignedInUser(ctx.Req.Header, ctx.Session)
ctx.User = auth.SignedInUser(ctx.Req.Request, ctx.Session)
if ctx.User != nil {
ctx.IsSigned = true
+31 -8
View File
@@ -1699,18 +1699,21 @@ The register and sign-in page style
#repo-hooks-panel,
#repo-hooks-history-panel,
#user-social-panel,
#user-applications-panel,
#user-ssh-panel {
margin-bottom: 20px;
}
#repo-hooks-panel .setting-list,
#repo-hooks-history-panel .setting-list,
#user-social-panel .setting-list,
#user-applications-panel .setting-list,
#user-ssh-panel .setting-list {
background-color: #FFF;
}
#repo-hooks-panel .setting-list li,
#repo-hooks-history-panel .setting-list li,
#user-social-panel .setting-list li,
#user-applications-panel .setting-list li,
#user-ssh-panel .setting-list li {
padding: 8px 20px;
border-bottom: 1px solid #eaeaea;
@@ -1718,18 +1721,21 @@ The register and sign-in page style
#repo-hooks-panel .setting-list li.ssh:hover,
#repo-hooks-history-panel .setting-list li.ssh:hover,
#user-social-panel .setting-list li.ssh:hover,
#user-applications-panel .setting-list li.ssh:hover,
#user-ssh-panel .setting-list li.ssh:hover {
background-color: #ffffEE;
}
#repo-hooks-panel .setting-list li i,
#repo-hooks-history-panel .setting-list li i,
#user-social-panel .setting-list li i,
#user-applications-panel .setting-list li i,
#user-ssh-panel .setting-list li i {
padding-right: 5px;
}
#repo-hooks-panel .active-icon,
#repo-hooks-history-panel .active-icon,
#user-social-panel .active-icon,
#user-applications-panel .active-icon,
#user-ssh-panel .active-icon {
width: 10px;
height: 10px;
@@ -1741,43 +1747,60 @@ The register and sign-in page style
#repo-hooks-panel .ssh-content,
#repo-hooks-history-panel .ssh-content,
#user-social-panel .ssh-content,
#user-applications-panel .ssh-content,
#user-ssh-panel .ssh-content {
margin-left: 24px;
}
#repo-hooks-panel .ssh-content .octicon,
#repo-hooks-history-panel .ssh-content .octicon,
#user-social-panel .ssh-content .octicon,
#user-applications-panel .ssh-content .octicon,
#user-ssh-panel .ssh-content .octicon {
margin-right: 4px;
}
#repo-hooks-panel .ssh-content .print,
#repo-hooks-history-panel .ssh-content .print,
#user-social-panel .ssh-content .print,
#user-applications-panel .ssh-content .print,
#user-ssh-panel .ssh-content .print,
#repo-hooks-panel .ssh-content .access,
#repo-hooks-history-panel .ssh-content .access,
#user-social-panel .ssh-content .access,
#user-applications-panel .ssh-content .access,
#user-ssh-panel .ssh-content .access,
#repo-hooks-panel .ssh-content .activity,
#repo-hooks-history-panel .ssh-content .activity,
#user-social-panel .ssh-content .activity,
#user-applications-panel .ssh-content .activity,
#user-ssh-panel .ssh-content .activity {
color: #888;
}
#repo-hooks-panel .ssh-delete-btn,
#repo-hooks-history-panel .ssh-delete-btn,
#user-social-panel .ssh-delete-btn,
#user-ssh-panel .ssh-delete-btn {
#repo-hooks-panel .ssh-content .access,
#repo-hooks-history-panel .ssh-content .access,
#user-social-panel .ssh-content .access,
#user-applications-panel .ssh-content .access,
#user-ssh-panel .ssh-content .access {
max-width: 500px;
}
#repo-hooks-panel .ssh-btn,
#repo-hooks-history-panel .ssh-btn,
#user-social-panel .ssh-btn,
#user-applications-panel .ssh-btn,
#user-ssh-panel .ssh-btn {
margin-top: 6px;
}
#user-ssh-add-form .panel-body {
.form-settings-add .panel-body {
background-color: #FFF;
padding: 30px 0;
}
#user-ssh-add-form .ipt {
.form-settings-add .ipt {
width: 500px;
}
#user-ssh-add-form textarea {
.form-settings-add textarea {
height: 120px;
margin-left: 3px;
}
#user-ssh-add-form .field {
.form-settings-add .field {
margin-bottom: 24px;
}
.pr-main {
+7 -4
View File
@@ -300,8 +300,11 @@ function initCore() {
$.magnificPopup.close();
});
// Collapse.
// Plugins.
$('.collapse').hide();
$('.tipsy-tooltip').tipsy({
fade: true
});
}
function initUserSetting() {
@@ -329,9 +332,9 @@ function initUserSetting() {
$profile_form.submit();
});
// Show add SSH key panel.
$('#ssh-add').click(function () {
$('#user-ssh-add-form').removeClass("hide");
// Show panels.
$('.show-form-btn').click(function () {
$($(this).data('target-form')).removeClass("hide");
});
// Confirmation of delete account.
+1 -1
View File
@@ -1,4 +1,4 @@
function Tabs(e){function t(e){console.log("hide",e),e.removeClass("js-tab-nav-show"),$(e.data("tab-target")).removeClass("js-tab-show").hide()}function n(e){console.log("show",e),e.addClass("js-tab-nav-show"),$(e.data("tab-target")).addClass("js-tab-show").show()}var r=$(e);if(r.length){var i=r.find(".js-tab-nav-show");i.length&&$(i.data("tab-target")).addClass("js-tab-show"),r.on("click",".js-tab-nav",function(e){e.preventDefault();var o=$(this);o.hasClass("js-tab-nav-show")||(i=r.find(".js-tab-nav-show").eq(0),t(i),n(o))}),console.log("init tabs @",e)}}function Preview(e,t){function n(e){return e.find(".js-preview-input").eq(0)}function r(e){return e.hasClass("js-preview-container")?e:e.find(".js-preview-container").eq(0)}var i=$(e),o=$(t),a=n(o);if(!a.length)return void console.log("[preview]: no preview input");var s=r(o);return s.length?(i.on("click",function(){$.post("/api/v1/markdown",{text:a.val()},function(e){s.html(e)})}),void console.log("[preview]: init preview @",e,"&",t)):void console.log("[preview]: no preview container")}function initCore(){Gogs.renderMarkdown(),Gogs.renderCodeView(),$(".js-tab-nav").click(function(e){$(this).hasClass("js-tab-nav-show")||($(this).parent().find(".js-tab-nav-show").each(function(){$(this).removeClass("js-tab-nav-show"),$($(this).data("tab-target")).hide()}),$(this).addClass("js-tab-nav-show"),$($(this).data("tab-target")).show()),e.preventDefault()}),$(document).on("click",".popup-modal-dismiss",function(e){e.preventDefault(),$.magnificPopup.close()}),$(".collapse").hide()}function initUserSetting(){var t=$("#username"),n=$("#user-profile-form");$("#change-username-btn").magnificPopup({modal:!0,callbacks:{open:function(){t.data("uname")==t.val()&&($.magnificPopup.close(),n.submit())}}}).click(function(){return t.data("uname")!=t.val()?(e.preventDefault(),!0):void 0}),$("#change-username-submit").click(function(){$.magnificPopup.close(),n.submit()}),$("#ssh-add").click(function(){$("#user-ssh-add-form").removeClass("hide")}),$("#delete-account-btn").magnificPopup({modal:!0}).click(function(e){return e.preventDefault(),!0}),$("#delete-account-submit").click(function(){$.magnificPopup.close(),$("#delete-account-form").submit()})}function initRepoCreate(){$("#repo-create-owner-list").on("click","li",function(){if(!$(this).hasClass("checked")){var e=$(this).data("uid");$("#repo-owner-id").val(e),$("#repo-owner-avatar").attr("src",$(this).find("img").attr("src")),$("#repo-owner-name").text($(this).text().trim()),$(this).parent().find(".checked").removeClass("checked"),$(this).addClass("checked"),console.log("set repo owner to uid :",e,$(this).text().trim())}}),$("#auth-button").click(function(e){$("#repo-migrate-auth").slideToggle("fast"),e.preventDefault()}),console.log("initRepoCreate")}function initRepo(){$("#repo-clone-ssh").click(function(){$(this).removeClass("btn-gray").addClass("btn-blue"),$("#repo-clone-https").removeClass("btn-blue").addClass("btn-gray"),$("#repo-clone-url").val($(this).data("link")),$(".clone-url").text($(this).data("link"))}),$("#repo-clone-https").click(function(){$(this).removeClass("btn-gray").addClass("btn-blue"),$("#repo-clone-ssh").removeClass("btn-blue").addClass("btn-gray"),$("#repo-clone-url").val($(this).data("link")),$(".clone-url").text($(this).data("link"))});var e=$("#repo-clone-copy");e.hover(function(){Gogs.bindCopy($(this))}),e.tipsy({fade:!0})}function initHookTypeChange(){$("select#hook-type").on("change",function(){hookTypes=["Gogs","Slack"];var e=$(this).val();hookTypes.forEach(function(t){e===t?$("div#"+t.toLowerCase()).toggleShow():$("div#"+t.toLowerCase()).toggleHide()})})}function initRepoSetting(){var t=$("#repo_name"),n=$("#repo-setting-form");$("#change-reponame-btn").magnificPopup({modal:!0,callbacks:{open:function(){t.data("repo-name")==t.val()&&($.magnificPopup.close(),n.submit())}}}).click(function(){return t.data("repo-name")!=t.val()?(e.preventDefault(),!0):void 0}),$("#change-reponame-submit").click(function(){$.magnificPopup.close(),n.submit()}),initHookTypeChange(),$("#transfer-repo-btn").magnificPopup({modal:!0}),$("#transfer-repo-submit").click(function(){$.magnificPopup.close(),$("#transfer-repo-form").submit()}),$("#delete-repo-btn").magnificPopup({modal:!0}),$("#delete-repo-submit").click(function(){$.magnificPopup.close(),$("#delete-repo-form").submit()}),$("#repo-collab-list hr:last-child").remove();var r=$("#repo-collaborator").next().next().find("ul");$("#repo-collaborator").on("keyup",function(){var e=$(this);return e.val()?void Gogs.searchUsers(e.val(),r):void r.toggleHide()}).on("focus",function(){$(this).val()?r.toggleShow():r.toggleHide()}).next().next().find("ul").on("click","li",function(){$("#repo-collaborator").val($(this).text()),r.toggleHide()})}function initOrgSetting(){var t=$("#orgname"),n=$("#org-setting-form");$("#change-orgname-btn").magnificPopup({modal:!0,callbacks:{open:function(){t.data("orgname")==t.val()&&($.magnificPopup.close(),n.submit())}}}).click(function(){returLine truncated
function Tabs(e){function t(e){console.log("hide",e),e.removeClass("js-tab-nav-show"),$(e.data("tab-target")).removeClass("js-tab-show").hide()}function n(e){console.log("show",e),e.addClass("js-tab-nav-show"),$(e.data("tab-target")).addClass("js-tab-show").show()}var r=$(e);if(r.length){var i=r.find(".js-tab-nav-show");i.length&&$(i.data("tab-target")).addClass("js-tab-show"),r.on("click",".js-tab-nav",function(e){e.preventDefault();var o=$(this);o.hasClass("js-tab-nav-show")||(i=r.find(".js-tab-nav-show").eq(0),t(i),n(o))}),console.log("init tabs @",e)}}function Preview(e,t){function n(e){return e.find(".js-preview-input").eq(0)}function r(e){return e.hasClass("js-preview-container")?e:e.find(".js-preview-container").eq(0)}var i=$(e),o=$(t),a=n(o);if(!a.length)return void console.log("[preview]: no preview input");var s=r(o);return s.length?(i.on("click",function(){$.post("/api/v1/markdown",{text:a.val()},function(e){s.html(e)})}),void console.log("[preview]: init preview @",e,"&",t)):void console.log("[preview]: no preview container")}function initCore(){Gogs.renderMarkdown(),Gogs.renderCodeView(),$(".js-tab-nav").click(function(e){$(this).hasClass("js-tab-nav-show")||($(this).parent().find(".js-tab-nav-show").each(function(){$(this).removeClass("js-tab-nav-show"),$($(this).data("tab-target")).hide()}),$(this).addClass("js-tab-nav-show"),$($(this).data("tab-target")).show()),e.preventDefault()}),$(document).on("click",".popup-modal-dismiss",function(e){e.preventDefault(),$.magnificPopup.close()}),$(".collapse").hide(),$(".tipsy-tooltip").tipsy({fade:!0})}function initUserSetting(){var t=$("#username"),n=$("#user-profile-form");$("#change-username-btn").magnificPopup({modal:!0,callbacks:{open:function(){t.data("uname")==t.val()&&($.magnificPopup.close(),n.submit())}}}).click(function(){return t.data("uname")!=t.val()?(e.preventDefault(),!0):void 0}),$("#change-username-submit").click(function(){$.magnificPopup.close(),n.submit()}),$(".show-form-btn").click(function(){$($(this).data("target-form")).removeClass("hide")}),$("#delete-account-btn").magnificPopup({modal:!0}).click(function(e){return e.preventDefault(),!0}),$("#delete-account-submit").click(function(){$.magnificPopup.close(),$("#delete-account-form").submit()})}function initRepoCreate(){$("#repo-create-owner-list").on("click","li",function(){if(!$(this).hasClass("checked")){var e=$(this).data("uid");$("#repo-owner-id").val(e),$("#repo-owner-avatar").attr("src",$(this).find("img").attr("src")),$("#repo-owner-name").text($(this).text().trim()),$(this).parent().find(".checked").removeClass("checked"),$(this).addClass("checked"),console.log("set repo owner to uid :",e,$(this).text().trim())}}),$("#auth-button").click(function(e){$("#repo-migrate-auth").slideToggle("fast"),e.preventDefault()}),console.log("initRepoCreate")}function initRepo(){$("#repo-clone-ssh").click(function(){$(this).removeClass("btn-gray").addClass("btn-blue"),$("#repo-clone-https").removeClass("btn-blue").addClass("btn-gray"),$("#repo-clone-url").val($(this).data("link")),$(".clone-url").text($(this).data("link"))}),$("#repo-clone-https").click(function(){$(this).removeClass("btn-gray").addClass("btn-blue"),$("#repo-clone-ssh").removeClass("btn-blue").addClass("btn-gray"),$("#repo-clone-url").val($(this).data("link")),$(".clone-url").text($(this).data("link"))});var e=$("#repo-clone-copy");e.hover(function(){Gogs.bindCopy($(this))}),e.tipsy({fade:!0})}function initHookTypeChange(){$("select#hook-type").on("change",function(){hookTypes=["Gogs","Slack"];var e=$(this).val();hookTypes.forEach(function(t){e===t?$("div#"+t.toLowerCase()).toggleShow():$("div#"+t.toLowerCase()).toggleHide()})})}function initRepoSetting(){var t=$("#repo_name"),n=$("#repo-setting-form");$("#change-reponame-btn").magnificPopup({modal:!0,callbacks:{open:function(){t.data("repo-name")==t.val()&&($.magnificPopup.close(),n.submit())}}}).click(function(){return t.data("repo-name")!=t.val()?(e.preventDefault(),!0):void 0}),$("#change-reponame-submit").click(function(){$.magnificPopup.close(),n.submit()}),initHookTypeChange(),$("#transfer-repo-btn").magnificPopup({modal:!0}),$("#transfer-repo-submit").click(function(){$.magnificPopup.close(),$("#transfer-repo-form").submit()}),$("#delete-repo-btn").magnificPopup({modal:!0}),$("#delete-repo-submit").click(function(){$.magnificPopup.close(),$("#delete-repo-form").submit()}),$("#repo-collab-list hr:last-child").remove();var r=$("#repo-collaborator").next().next().find("ul");$("#repo-collaborator").on("keyup",function(){var e=$(this);return e.val()?void Gogs.searchUsers(e.val(),r):void r.toggleHide()}).on("focus",function(){$(this).val()?r.toggleShow():r.toggleHide()}).next().next().find("ul").on("click","li",function(){$("#repo-collaborator").val($(this).text()),r.toggleHide()})}function initOrgSetting(){var t=$("#orgname"),n=$("#org-setting-form");$("#change-orgname-btn").magnificPopup({modal:!0,callbacks:{open:function(){t.data("orgname")==t.val()&&($.magnificPoLine truncated
}),w.getById?(C.find.ID=function(e,t){if(typeof t.getElementById!==G&&_){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},C.filter.ID=function(e){var t=e.replace(wt,Ct);return function(e){return e.getAttribute("id")===t}}):(delete C.find.ID,C.filter.ID=function(e){var t=e.replace(wt,Ct);return function(e){var n=typeof e.getAttributeNode!==G&&e.getAttributeNode("id");return n&&n.value===t}}),C.find.TAG=w.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==G?t.getElementsByTagName(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},C.find.CLASS=w.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==G&&_?t.getElementsByClassName(e):void 0},O=[],H=[],(w.qsa=$.test(n.querySelectorAll))&&(i(function(e){e.innerHTML="<select msallowclip=''><option selected=''></option></select>",e.querySelectorAll("[msallowclip^='']").length&&H.push("[*^$]="+it+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||H.push("\\["+it+"*(?:value|"+rt+")"),e.querySelectorAll(":checked").length||H.push(":checked")}),i(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&H.push("name"+it+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||H.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),H.push(",.*:")})),(w.matchesSelector=$.test(q=P.matches||P.webkitMatchesSelector||P.mozMatchesSelector||P.oMatchesSelector||P.msMatchesSelector))&&i(function(e){w.disconnectedMatch=q.call(e,"div"),q.call(e,"[s!='']:x"),O.push("!=",lt)}),H=H.length&&new RegExp(H.join("|")),O=O.length&&new RegExp(O.join("|")),t=$.test(P.compareDocumentPosition),M=t||$.test(P.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},Z=t?function(e,t){if(e===t)return D=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r?r:(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&r||!w.sortDetached&&t.compareDocumentPosition(e)===r?e===n||e.ownerDocument===F&&M(F,e)?-1:t===n||t.ownerDocument===F&&M(F,t)?1:A?nt.call(A,e)-nt.call(A,t):0:4&r?-1:1)}:function(e,t){if(e===t)return D=!0,0;var r,i=0,o=e.parentNode,s=t.parentNode,l=[e],c=[t];if(!o||!s)return e===n?-1:t===n?1:o?-1:s?1:A?nt.call(A,e)-nt.call(A,t):0;if(o===s)return a(e,t);for(r=e;r=r.parentNode;)l.unshift(r);for(r=t;r=r.parentNode;)c.unshift(r);for(;l[i]===c[i];)i++;return i?a(l[i],c[i]):l[i]===F?-1:c[i]===F?1:0},n):R},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==R&&j(e),n=n.replace(ft,"='$1']"),!(!w.matchesSelector||!_||O&&O.test(n)||H&&H.test(n)))try{var r=q.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,R,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==R&&j(e),M(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==R&&j(e);var n=C.attrHandle[t.toLowerCase()],r=n&&Q.call(C.attrHandle,t.toLowerCase())?n(e,t,!_):void 0;return void 0!==r?r:w.attributes||!_?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(D=!w.detectDuplicates,A=!w.sortStable&&e.slice(0),e.sort(Z),D){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return A=null,e},S=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=S(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=S(t);return n},C=t.selectors={cacheLength:50,createPseudo:r,match:mt,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(wt,Ct),e[3]=(e[3]||e[4]||e[5]||"").replace(wt,Ct),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return mt.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&pt.test(n)&&(t=T(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(wt,Ct).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=W[e+" "];return t||(t=new RegExp("(^|"+it+")"+e+"("+it+"|$)"))&&W(e,fLine truncated
})),!1):void ot.event.add(this,"beforeactivate._change",function(e){var t=e.target;jt.test(t.nodeName)&&!ot._data(t,"changeBubbles")&&(ot.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||ot.event.simulate("change",this.parentNode,e,!0)}),ot._data(t,"changeBubbles",!0))})},handle:function(e){var t=e.target;return this!==t||e.isSimulated||e.isTrigger||"radio"!==t.type&&"checkbox"!==t.type?e.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return ot.event.remove(this,"._change"),!jt.test(this.nodeName)}}),rt.focusinBubbles||ot.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){ot.event.simulate(t,e.target,ot.event.fix(e),!0)};ot.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=ot._data(r,t);i||r.addEventListener(e,n,!0),ot._data(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=ot._data(r,t)-1;i?ot._data(r,t,i):(r.removeEventListener(e,n,!0),ot._removeData(r,t))}}}),ot.fn.extend({on:function(e,t,n,r,i){var o,a;if("object"==typeof e){"string"!=typeof t&&(n=n||t,t=void 0);for(o in e)this.on(o,t,n,e[o],i);return this}if(null==n&&null==r?(r=t,n=t=void 0):null==r&&("string"==typeof t?(r=n,n=void 0):(r=n,n=t,t=void 0)),r===!1)r=p;else if(!r)return this;return 1===i&&(a=r,r=function(e){return ot().off(e),a.apply(this,arguments)},r.guid=a.guid||(a.guid=ot.guid++)),this.each(function(){ot.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,ot(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return(t===!1||"function"==typeof t)&&(n=t,t=void 0),n===!1&&(n=p),this.each(function(){ot.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){ot.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?ot.event.trigger(e,t,n,!0):void 0}});var Ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",Ot=/ jQuery\d+="(?:null|\d+)"/g,qt=new RegExp("<(?:"+Ht+")[\\s/>]","i"),Mt=/^\s+/,zt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Ft=/<([\w:]+)/,It=/<tbody/i,Bt=/<|&#?\w+;/,Wt=/<(?:script|style|link)/i,Ut=/checked\s*(?:[^=]|=\s*.checked.)/i,Xt=/^$|\/(?:java|ecma)script/i,Zt=/^true\/(.*)/,Gt=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Vt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:rt.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},Qt=m(mt),Yt=Qt.appendChild(mt.createElement("div"));Vt.optgroup=Vt.option,Vt.tbody=Vt.tfoot=Vt.colgroup=Vt.caption=Vt.thead,Vt.th=Vt.td,ot.extend({clone:function(e,t,n){var r,i,o,a,s,l=ot.contains(e.ownerDocument,e);if(rt.html5Clone||ot.isXMLDoc(e)||!qt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Yt.innerHTML=e.outerHTML,Yt.removeChild(o=Yt.firstChild)),!(rt.noCloneEvent&&rt.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||ot.isXMLDoc(e)))for(r=g(o),s=g(e),a=0;null!=(i=s[a]);++a)r[a]&&S(i,r[a]);if(t)if(n)for(s=s||g(e),r=r||g(o),a=0;null!=(i=s[a]);a++)C(i,r[a]);else C(e,o);return r=g(o,"script"),r.length>0&&w(r,!l&&g(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){for(var i,o,a,s,l,c,u,d=e.length,f=m(t),p=[],h=0;d>h;h++)if(o=e[h],o||0===o)if("object"===ot.type(o))ot.merge(p,o.nodeType?[o]:o);else if(Bt.test(o)){for(s=s||f.appendChild(t.createElement("div")),l=(Ft.exec(o)||["",""])[1].toLowerCase(),u=Vt[l]||Vt._default,s.innerHTML=u[1]+o.replace(zt,"<$1></$2>")+u[2],i=u[0];i--;)s=s.lastChild;if(!rt.leadingWhitespace&&Mt.test(o)&&p.push(t.createTextNode(Mt.exec(o)[0])),!rt.tbody)for(o="table"!==l||It.test(o)?"<table>"!==u[1]||It.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;i--;)ot.nodeName(c=o.childNodes[i],"tbody")&&!c.childNodes.length&&o.removeChild(c);for(ot.merge(p,s.childNodes),s.textContent="";s.firstChild;)s.removeChild(s.firstChild);s=f.lastChild}else p.push(t.createTextNode(o));for(s&&f.removeChild(s),rt.appendChecked||ot.grep(g(p,"input"),v),h=0;o=p[h++];)if((!r||-1===ot.inArray(o,r))&&(a=ot.contains(o.ownerDocument,o),s=g(f.appendChild(o),"script"),a&&w(s),n))for(i=0;o=s[i++];)Xt.test(o.type||"")&&n.push(o);return s=null,f},cleanData:function(e,t){for(var n,r,i,o,a=0,s=ot.expando,l=ot.cache,c=rt.deleteExpando,u=ot.event.special;null!=(n=e[a]);a++)if((t||ot.acceptData(n))&&(i=n[s],o=i&&l[i])){if(o.events)for(r in o.events)u[r]?ot.event.remove(n,r):ot.removeEvent(n,r,o.handle);l[i]&&(delete l[i],c?delete n[s]:typeof n.removeAttribute!==St?n.removeAttribute(s):n[s]=null,V.push(i))}Line truncated
for(i in d.headers)w.setRequestHeader(i,d.headers[i]);if(d.beforeSend&&(d.beforeSend.call(f,w,d)===!1||2===b))return w.abort();x="abort";for(i in{success:1,error:1,complete:1})w[i](d[i]);if(c=F(Wn,d,t,w)){w.readyState=1,l&&p.trigger("ajaxSend",[w,d]),d.async&&d.timeout>0&&(s=setTimeout(function(){w.abort("timeout")},d.timeout));try{b=1,c.send(v,n)}catch(C){if(!(2>b))throw C;n(-1,C)}}else n(-1,"No Transport");return w},getJSON:function(e,t,n){return ot.get(e,t,n,"json")},getScript:function(e,t){return ot.get(e,void 0,t,"script")}}),ot.each(["get","post"],function(e,t){ot[t]=function(e,n,r,i){return ot.isFunction(n)&&(i=i||r,r=n,n=void 0),ot.ajax({url:e,type:t,dataType:i,data:n,success:r})}}),ot.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ot.fn[t]=function(e){return this.on(t,e)}}),ot._evalUrl=function(e){return ot.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},ot.fn.extend({wrapAll:function(e){if(ot.isFunction(e))return this.each(function(t){ot(this).wrapAll(e.call(this,t))});if(this[0]){var t=ot(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return this.each(ot.isFunction(e)?function(t){ot(this).wrapInner(e.call(this,t))}:function(){var t=ot(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=ot.isFunction(e);return this.each(function(n){ot(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){ot.nodeName(this,"body")||ot(this).replaceWith(this.childNodes)}).end()}}),ot.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0||!rt.reliableHiddenOffsets()&&"none"===(e.style&&e.style.display||ot.css(e,"display"))},ot.expr.filters.visible=function(e){return!ot.expr.filters.hidden(e)};var Zn=/%20/g,Gn=/\[\]$/,Vn=/\r?\n/g,Qn=/^(?:submit|button|image|reset|file)$/i,Yn=/^(?:input|select|textarea|keygen)/i;ot.param=function(e,t){var n,r=[],i=function(e,t){t=ot.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=ot.ajaxSettings&&ot.ajaxSettings.traditional),ot.isArray(e)||e.jquery&&!ot.isPlainObject(e))ot.each(e,function(){i(this.name,this.value)});else for(n in e)U(n,e[n],t,i);return r.join("&").replace(Zn,"+")},ot.fn.extend({serialize:function(){return ot.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=ot.prop(this,"elements");return e?ot.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!ot(this).is(":disabled")&&Yn.test(this.nodeName)&&!Qn.test(e)&&(this.checked||!Dt.test(e))}).map(function(e,t){var n=ot(this).val();return null==n?null:ot.isArray(n)?ot.map(n,function(e){return{name:t.name,value:e.replace(Vn,"\r\n")}}):{name:t.name,value:n.replace(Vn,"\r\n")}}).get()}}),ot.ajaxSettings.xhr=void 0!==e.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&X()||Z()}:X;var Kn=0,Jn={},er=ot.ajaxSettings.xhr();e.ActiveXObject&&ot(e).on("unload",function(){for(var e in Jn)Jn[e](void 0,!0)}),rt.cors=!!er&&"withCredentials"in er,er=rt.ajax=!!er,er&&ot.ajaxTransport(function(e){if(!e.crossDomain||rt.cors){var t;return{send:function(n,r){var i,o=e.xhr(),a=++Kn;if(o.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)o[i]=e.xhrFields[i];e.mimeType&&o.overrideMimeType&&o.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(i in n)void 0!==n[i]&&o.setRequestHeader(i,n[i]+"");o.send(e.hasContent&&e.data||null),t=function(n,i){var s,l,c;if(t&&(i||4===o.readyState))if(delete Jn[a],t=void 0,o.onreadystatechange=ot.noop,i)4!==o.readyState&&o.abort();else{c={},s=o.status,"string"==typeof o.responseText&&(c.text=o.responseText);try{l=o.statusText}catch(u){l=""}s||!e.isLocal||e.crossDomain?1223===s&&(s=204):s=c.text?200:404}c&&r(s,l,c,o.getAllResponseHeaders())},e.async?4===o.readyState?setTimeout(t):o.onreadystatechange=Jn[a]=t:t()},abort:function(){t&&t(void 0,!0)}}}}),ot.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return ot.globalEval(e),e}}}),ot.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),ot.ajaxTransport("script",function(e){if(e.crossDomain){var t,n=mt.head||ot("head")[0]||mt.documentElement;return{send:function(r,i){t=mt.createElement("script"),t.async=!0,e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t.parentNode&&t.parentNode.removeChild(t),t=null,n||i(200,"success")Line truncated
+7 -2
View File
@@ -68,6 +68,7 @@
#repo-hooks-panel,
#repo-hooks-history-panel,
#user-social-panel,
#user-applications-panel,
#user-ssh-panel {
margin-bottom: 20px;
.setting-list {
@@ -97,16 +98,20 @@
margin-right: 4px;
}
.print,
.access,
.activity {
color: #888;
}
.access {
max-width: 500px;
}
}
.ssh-delete-btn {
.ssh-btn {
margin-top: 6px;
}
}
#user-ssh-add-form {
.form-settings-add {
.panel-body {
background-color: #FFF;
padding: 30px 0;
+66 -9
View File
@@ -18,13 +18,14 @@ import (
)
const (
SETTINGS_PROFILE base.TplName = "user/settings/profile"
SETTINGS_PASSWORD base.TplName = "user/settings/password"
SETTINGS_SSH_KEYS base.TplName = "user/settings/sshkeys"
SETTINGS_SOCIAL base.TplName = "user/settings/social"
SETTINGS_DELETE base.TplName = "user/settings/delete"
NOTIFICATION base.TplName = "user/notification"
SECURITY base.TplName = "user/security"
SETTINGS_PROFILE base.TplName = "user/settings/profile"
SETTINGS_PASSWORD base.TplName = "user/settings/password"
SETTINGS_SSH_KEYS base.TplName = "user/settings/sshkeys"
SETTINGS_SOCIAL base.TplName = "user/settings/social"
SETTINGS_APPLICATIONS base.TplName = "user/settings/applications"
SETTINGS_DELETE base.TplName = "user/settings/delete"
NOTIFICATION base.TplName = "user/notification"
SECURITY base.TplName = "user/security"
)
func Settings(ctx *middleware.Context) {
@@ -129,7 +130,7 @@ func SettingsSSHKeys(ctx *middleware.Context) {
ctx.Data["PageIsSettingsSSHKeys"] = true
var err error
ctx.Data["Keys"], err = models.ListPublicKey(ctx.User.Id)
ctx.Data["Keys"], err = models.ListPublicKeys(ctx.User.Id)
if err != nil {
ctx.Handle(500, "ssh.ListPublicKey", err)
return
@@ -144,7 +145,7 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
ctx.Data["PageIsSettingsSSHKeys"] = true
var err error
ctx.Data["Keys"], err = models.ListPublicKey(ctx.User.Id)
ctx.Data["Keys"], err = models.ListPublicKeys(ctx.User.Id)
if err != nil {
ctx.Handle(500, "ssh.ListPublicKey", err)
return
@@ -235,6 +236,62 @@ func SettingsSocial(ctx *middleware.Context) {
ctx.HTML(200, SETTINGS_SOCIAL)
}
func SettingsApplications(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsUserSettings"] = true
ctx.Data["PageIsSettingsApplications"] = true
// Delete access token.
remove, _ := com.StrTo(ctx.Query("remove")).Int64()
if remove > 0 {
if err := models.DeleteAccessTokenById(remove); err != nil {
ctx.Handle(500, "DeleteAccessTokenById", err)
return
}
ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
return
}
tokens, err := models.ListAccessTokens(ctx.User.Id)
if err != nil {
ctx.Handle(500, "ListAccessTokens", err)
return
}
ctx.Data["Tokens"] = tokens
ctx.HTML(200, SETTINGS_APPLICATIONS)
}
// FIXME: split to two different functions and pages to handle access token and oauth2
func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenForm) {
ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsUserSettings"] = true
ctx.Data["PageIsSettingsApplications"] = true
switch ctx.Query("type") {
case "token":
if ctx.HasError() {
ctx.HTML(200, SETTINGS_APPLICATIONS)
return
}
t := &models.AccessToken{
Uid: ctx.User.Id,
Name: form.Name,
}
if err := models.NewAccessToken(t); err != nil {
ctx.Handle(500, "NewAccessToken", err)
return
}
ctx.Flash.Success(ctx.Tr("settings.generate_token_succees"))
ctx.Flash.Info(t.Sha1)
}
ctx.Redirect(setting.AppSubUrl + "/user/settings/applications")
}
func SettingsDelete(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsUserSettings"] = true
+1 -1
View File
@@ -1 +1 @@
0.5.7.1110 Beta
0.5.8.1112 Beta
+56
View File
@@ -0,0 +1,56 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
<div id="setting-wrapper" class="main-wrapper">
<div id="user-profile-setting" class="container clear">
{{template "user/settings/nav" .}}
<div class="grid-4-5 left">
<div class="setting-content">
{{template "ng/base/alert" .}}
<div id="setting-content">
<div id="user-applications-panel" class="panel panel-radius">
<div class="panel-header">
<a class="show-form-btn" data-target-form="#access-add-form">
<button class="btn btn-medium btn-black btn-radius right">{{.i18n.Tr "settings.generate_new_token"}}</button>
</a>
<strong>{{.i18n.Tr "settings.manage_access_token"}}</strong>
</div>
<ul class="panel-body setting-list">
<li>{{.i18n.Tr "settings.tokens_desc"}}</li>
{{range .Tokens}}
<li class="ssh clear">
<span class="active-icon left label label-{{if .HasRecentActivity}}green{{else}}gray{{end}} label-radius"></span>
<i class="fa fa-send fa-2x left"></i>
<div class="ssh-content left">
<p><strong>{{.Name}}</strong></p>
<p class="activity"><i>{{$.i18n.Tr "settings.add_on"}} {{DateFormat .Created "M d, Y"}} — <i class="octicon octicon-info"></i>{{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{DateFormat .Updated "M d, Y"}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i></p>
</div>
<a href="{{AppSubUrl}}/user/settings/applications?remove={{.Id}}">
<button class="btn btn-small btn-red btn-radius ssh-btn right">{{$.i18n.Tr "settings.delete_token"}}</button>
</a>
</li>
{{end}}
</ul>
</div>
<br>
<form class="panel panel-radius form form-align form-settings-add hide" id="access-add-form" action="{{AppSubUrl}}/user/settings/applications" method="post">
{{.CsrfTokenHtml}}
<p class="panel-header"><strong>{{.i18n.Tr "settings.generate_new_token"}}</strong></p>
<div class="panel-body">
<div class="text-center panel-desc">{{.i18n.Tr "settings.new_token_desc"}}</div>
<input type="hidden" name="type" value="token">
<p class="field">
<label class="req" for="token-name">{{.i18n.Tr "settings.token_name"}}</label>
<input class="ipt ipt-radius" id="token-name" name="name" required />
</p>
<p class="field">
<label></label>
<button class="btn btn-green btn-medium btn-radius" id="ssh-add-btn">{{.i18n.Tr "settings.generate_token"}}</button>
</p>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{{template "ng/base/footer" .}}
+1
View File
@@ -6,6 +6,7 @@
<li {{if .PageIsSettingsPassword}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/password">{{.i18n.Tr "settings.password"}}</a></li>
<li {{if .PageIsSettingsSSHKeys}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/ssh">{{.i18n.Tr "settings.ssh_keys"}}</a></li>
<li {{if .PageIsSettingsSocial}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/social">{{.i18n.Tr "settings.social"}}</a></li>
<li {{if .PageIsSettingsApplications}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/applications">{{.i18n.Tr "settings.applications"}}</a></li>
<li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/delete">{{.i18n.Tr "settings.delete"}}</a></li>
</ul>
</div>
+5 -3
View File
@@ -9,7 +9,9 @@
<div id="user-ssh-setting-content">
<div id="user-ssh-panel" class="panel panel-radius">
<div class="panel-header">
<a class="btn btn-small btn-black btn-header btn-radius right" id="ssh-add">{{.i18n.Tr "settings.add_key"}}</a>
<a class="show-form-btn" data-target-form="#user-ssh-add-form">
<button class="btn btn-medium btn-black btn-radius right">{{.i18n.Tr "settings.add_key"}}</button>
</a>
<strong>{{.i18n.Tr "settings.manage_ssh_keys"}}</strong>
</div>
<ul class="panel-body setting-list">
@@ -27,7 +29,7 @@
{{$.CsrfTokenHtml}}
<input name="_method" type="hidden" value="DELETE">
<input name="id" type="hidden" value="{{.Id}}">
<button class="right ssh-delete-btn btn btn-red btn-radius btn-small">{{$.i18n.Tr "settings.delete_key"}}</button>
<button class="right ssh-btn btn btn-red btn-radius btn-small">{{$.i18n.Tr "settings.delete_key"}}</button>
</form>
</li>
{{end}}
@@ -35,7 +37,7 @@
</div>
<p>{{.i18n.Tr "settings.ssh_helper" "https://help.github.com/articles/generating-ssh-keys" "https://help.github.com/ssh-issues/" | Str2html}}</p>
<br>
<form class="panel panel-radius form form-align hide" id="user-ssh-add-form" action="{{AppSubUrl}}/user/settings/ssh" method="post">
<form class="panel panel-radius form form-align form-settings-add hide" id="user-ssh-add-form" action="{{AppSubUrl}}/user/settings/ssh" method="post">
{{.CsrfTokenHtml}}
<p class="panel-header"><strong>{{.i18n.Tr "settings.add_new_key"}}</strong></p>
<div class="panel-body">