1
0
Fork 0
forked from forgejo/forgejo

Merge branch 'master' into feat/approval-new

# Conflicts:
#	models/error.go
#	models/migrations/migrations.go
#	models/models.go
#	public/js/index.js
This commit is contained in:
Jonas Franz 2018-05-19 18:17:01 +02:00
commit a8dc699e74
No known key found for this signature in database
GPG key ID: 506AEEBE80BEDECD
251 changed files with 41347 additions and 145 deletions

View file

@ -1238,6 +1238,28 @@ func (err ErrExternalLoginUserNotExist) Error() string {
return fmt.Sprintf("external login user link does not exists [userID: %d, loginSourceID: %d]", err.UserID, err.LoginSourceID)
}
// ____ ________________________________ .__ __ __ .__
// | | \_____ \_ _____/\______ \ ____ ____ |__| _______/ |_____________ _/ |_|__| ____ ____
// | | // ____/| __) | _// __ \ / ___\| |/ ___/\ __\_ __ \__ \\ __\ |/ _ \ / \
// | | // \| \ | | \ ___// /_/ > |\___ \ | | | | \// __ \| | | ( <_> ) | \
// |______/ \_______ \___ / |____|_ /\___ >___ /|__/____ > |__| |__| (____ /__| |__|\____/|___| /
// \/ \/ \/ \/_____/ \/ \/ \/
// ErrU2FRegistrationNotExist represents a "ErrU2FRegistrationNotExist" kind of error.
type ErrU2FRegistrationNotExist struct {
ID int64
}
func (err ErrU2FRegistrationNotExist) Error() string {
return fmt.Sprintf("U2F registration does not exist [id: %d]", err.ID)
}
// IsErrU2FRegistrationNotExist checks if an error is a ErrU2FRegistrationNotExist.
func IsErrU2FRegistrationNotExist(err error) bool {
_, ok := err.(ErrU2FRegistrationNotExist)
return ok
}
// __________ .__
// \______ \ _______ _|__| ______ _ __
// | _// __ \ \/ / |/ __ \ \/ \/ /

View file

@ -0,0 +1,7 @@
-
id: 1
name: "U2F Key"
user_id: 1
counter: 0
created_unix: 946684800
updated_unix: 946684800

View file

@ -182,6 +182,8 @@ var migrations = []Migration{
NewMigration("add language column for user setting", addLanguageSetting),
// v64 -> v65
NewMigration("add multiple assignees", addMultipleAssignees),
// v65 -> v66
NewMigration("add u2f", addU2FReg),
// v66 -> v67
NewMigration("add review", addReview),
}

19
models/migrations/v65.go Normal file
View file

@ -0,0 +1,19 @@
package migrations
import (
"code.gitea.io/gitea/modules/util"
"github.com/go-xorm/xorm"
)
func addU2FReg(x *xorm.Engine) error {
type U2FRegistration struct {
ID int64 `xorm:"pk autoincr"`
Name string
UserID int64 `xorm:"INDEX"`
Raw []byte
Counter uint32
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
}
return x.Sync2(&U2FRegistration{})
}

View file

@ -120,6 +120,7 @@ func init() {
new(LFSLock),
new(Reaction),
new(IssueAssignees),
new(U2FRegistration),
new(Review),
)

120
models/u2f.go Normal file
View file

@ -0,0 +1,120 @@
// Copyright 2018 The Gitea 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 (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
"github.com/tstranex/u2f"
)
// U2FRegistration represents the registration data and counter of a security key
type U2FRegistration struct {
ID int64 `xorm:"pk autoincr"`
Name string
UserID int64 `xorm:"INDEX"`
Raw []byte
Counter uint32
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
}
// TableName returns a better table name for U2FRegistration
func (reg U2FRegistration) TableName() string {
return "u2f_registration"
}
// Parse will convert the db entry U2FRegistration to an u2f.Registration struct
func (reg *U2FRegistration) Parse() (*u2f.Registration, error) {
r := new(u2f.Registration)
return r, r.UnmarshalBinary(reg.Raw)
}
func (reg *U2FRegistration) updateCounter(e Engine) error {
_, err := e.ID(reg.ID).Cols("counter").Update(reg)
return err
}
// UpdateCounter will update the database value of counter
func (reg *U2FRegistration) UpdateCounter() error {
return reg.updateCounter(x)
}
// U2FRegistrationList is a list of *U2FRegistration
type U2FRegistrationList []*U2FRegistration
// ToRegistrations will convert all U2FRegistrations to u2f.Registrations
func (list U2FRegistrationList) ToRegistrations() []u2f.Registration {
regs := make([]u2f.Registration, len(list))
for _, reg := range list {
r, err := reg.Parse()
if err != nil {
log.Fatal(4, "parsing u2f registration: %v", err)
continue
}
regs = append(regs, *r)
}
return regs
}
func getU2FRegistrationsByUID(e Engine, uid int64) (U2FRegistrationList, error) {
regs := make(U2FRegistrationList, 0)
return regs, e.Where("user_id = ?", uid).Find(&regs)
}
// GetU2FRegistrationByID returns U2F registration by id
func GetU2FRegistrationByID(id int64) (*U2FRegistration, error) {
return getU2FRegistrationByID(x, id)
}
func getU2FRegistrationByID(e Engine, id int64) (*U2FRegistration, error) {
reg := new(U2FRegistration)
if found, err := e.ID(id).Get(reg); err != nil {
return nil, err
} else if !found {
return nil, ErrU2FRegistrationNotExist{ID: id}
}
return reg, nil
}
// GetU2FRegistrationsByUID returns all U2F registrations of the given user
func GetU2FRegistrationsByUID(uid int64) (U2FRegistrationList, error) {
return getU2FRegistrationsByUID(x, uid)
}
func createRegistration(e Engine, user *User, name string, reg *u2f.Registration) (*U2FRegistration, error) {
raw, err := reg.MarshalBinary()
if err != nil {
return nil, err
}
r := &U2FRegistration{
UserID: user.ID,
Name: name,
Counter: 0,
Raw: raw,
}
_, err = e.InsertOne(r)
if err != nil {
return nil, err
}
return r, nil
}
// CreateRegistration will create a new U2FRegistration from the given Registration
func CreateRegistration(user *User, name string, reg *u2f.Registration) (*U2FRegistration, error) {
return createRegistration(x, user, name, reg)
}
// DeleteRegistration will delete U2FRegistration
func DeleteRegistration(reg *U2FRegistration) error {
return deleteRegistration(x, reg)
}
func deleteRegistration(e Engine, reg *U2FRegistration) error {
_, err := e.Delete(reg)
return err
}

61
models/u2f_test.go Normal file
View file

@ -0,0 +1,61 @@
package models
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/tstranex/u2f"
)
func TestGetU2FRegistrationByID(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
res, err := GetU2FRegistrationByID(1)
assert.NoError(t, err)
assert.Equal(t, "U2F Key", res.Name)
_, err = GetU2FRegistrationByID(342432)
assert.Error(t, err)
assert.True(t, IsErrU2FRegistrationNotExist(err))
}
func TestGetU2FRegistrationsByUID(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
res, err := GetU2FRegistrationsByUID(1)
assert.NoError(t, err)
assert.Len(t, res, 1)
assert.Equal(t, "U2F Key", res[0].Name)
}
func TestU2FRegistration_TableName(t *testing.T) {
assert.Equal(t, "u2f_registration", U2FRegistration{}.TableName())
}
func TestU2FRegistration_UpdateCounter(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
reg := AssertExistsAndLoadBean(t, &U2FRegistration{ID: 1}).(*U2FRegistration)
reg.Counter = 1
assert.NoError(t, reg.UpdateCounter())
AssertExistsIf(t, true, &U2FRegistration{ID: 1, Counter: 1})
}
func TestCreateRegistration(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
user := AssertExistsAndLoadBean(t, &User{ID: 1}).(*User)
res, err := CreateRegistration(user, "U2F Created Key", &u2f.Registration{Raw: []byte("Test")})
assert.NoError(t, err)
assert.Equal(t, "U2F Created Key", res.Name)
assert.Equal(t, []byte("Test"), res.Raw)
AssertExistsIf(t, true, &U2FRegistration{Name: "U2F Created Key", UserID: user.ID})
}
func TestDeleteRegistration(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
reg := AssertExistsAndLoadBean(t, &U2FRegistration{ID: 1}).(*U2FRegistration)
assert.NoError(t, DeleteRegistration(reg))
AssertNotExistsBean(t, &U2FRegistration{ID: 1})
}