add personal access token panel #12
parent
21b9d5fa1f
commit
8c9338a537
@ -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
|
||||||
|
}
|
@ -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)
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
0.5.7.1110 Beta
|
0.5.8.1112 Beta
|
@ -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" .}}
|
Loading…
Reference in New Issue