# Conflicts:
#	models/migrations/migrations.go
#	models/migrations/v62.go
This commit is contained in:
kolaente 2018-05-02 22:08:30 +02:00
commit 0f8a212918
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
39 changed files with 117 additions and 139 deletions

View File

@ -249,6 +249,7 @@ pipeline:
docker:
image: plugins/docker:17.12
secrets: [ docker_username, docker_password ]
pull: true
repo: gitea/gitea
default_tags: true

View File

@ -230,6 +230,12 @@ func runServ(c *cli.Context) error {
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
}
if !user.IsActive || user.ProhibitLogin {
fail("Your account is not active or has been disabled by Administrator",
"User %s is disabled and have no access to repository %s",
user.Name, repoPath)
}
mode, err := models.AccessLevel(user.ID, repo)
if err != nil {
fail("Internal error", "Failed to check access: %v", err)

View File

@ -177,6 +177,8 @@ var migrations = []Migration{
// v61 -> v62
NewMigration("add size column for attachments", addSizeToAttachment),
// v62 -> v63
NewMigration("add last used passcode column for TOTP", addLastUsedPasscodeTOTP),
// v63 -> v64
NewMigration("add issue_dependencies", addIssueDependencies),
}

View File

@ -6,95 +6,17 @@ package migrations
import (
"fmt"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func addIssueDependencies(x *xorm.Engine) (err error) {
type IssueDependency struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"NOT NULL"`
IssueID int64 `xorm:"NOT NULL"`
DependencyID int64 `xorm:"NOT NULL"`
Created time.Time `xorm:"-"`
CreatedUnix int64 `xorm:"INDEX created"`
Updated time.Time `xorm:"-"`
UpdatedUnix int64 `xorm:"updated"`
func addLastUsedPasscodeTOTP(x *xorm.Engine) error {
type TwoFactor struct {
LastUsedPasscode string `xorm:"VARCHAR(10)"`
}
if err = x.Sync(new(IssueDependency)); err != nil {
return fmt.Errorf("Error creating issue_dependency_table column definition: %v", err)
if err := x.Sync2(new(TwoFactor)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
// Update Comment definition
// This (copied) struct does only contain fields used by xorm as the only use here is to update the database
// CommentType defines the comment type
type CommentType int
// TimeStamp defines a timestamp
type TimeStamp int64
type Comment struct {
ID int64 `xorm:"pk autoincr"`
Type CommentType
PosterID int64 `xorm:"INDEX"`
IssueID int64 `xorm:"INDEX"`
LabelID int64
OldMilestoneID int64
MilestoneID int64
OldAssigneeID int64
AssigneeID int64
OldTitle string
NewTitle string
DependentIssueID int64
CommitID int64
Line int64
Content string `xorm:"TEXT"`
CreatedUnix TimeStamp `xorm:"INDEX created"`
UpdatedUnix TimeStamp `xorm:"INDEX updated"`
// Reference issue in commit message
CommitSHA string `xorm:"VARCHAR(40)"`
}
if err = x.Sync(new(Comment)); err != nil {
return fmt.Errorf("Error updating issue_comment table column definition: %v", err)
}
// RepoUnit describes all units of a repository
type RepoUnit struct {
ID int64
RepoID int64 `xorm:"INDEX(s)"`
Type int `xorm:"INDEX(s)"`
Config map[string]interface{} `xorm:"JSON"`
CreatedUnix int64 `xorm:"INDEX CREATED"`
Created time.Time `xorm:"-"`
}
//Updating existing issue units
units := make([]*RepoUnit, 0, 100)
err = x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
if err != nil {
return fmt.Errorf("Query repo units: %v", err)
}
for _, unit := range units {
if unit.Config == nil {
unit.Config = make(map[string]interface{})
}
if _, ok := unit.Config["EnableDependencies"]; !ok {
unit.Config["EnableDependencies"] = setting.Service.DefaultEnableDependencies
}
if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil {
return err
}
}
return err
return nil
}

1
models/migrations/v63.go Normal file
View File

@ -0,0 +1 @@
package migrations

View File

@ -163,6 +163,7 @@ func NewRepoContext() {
type Repository struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s)"`
OwnerName string `xorm:"-"`
Owner *User `xorm:"-"`
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"INDEX NOT NULL"`
@ -225,9 +226,17 @@ func (repo *Repository) MustOwner() *User {
return repo.mustOwner(x)
}
// MustOwnerName always returns valid owner name to avoid
// conceptually impossible error handling.
// It returns "error" and logs error details when error
// occurs.
func (repo *Repository) MustOwnerName() string {
return repo.mustOwnerName(x)
}
// FullName returns the repository full name
func (repo *Repository) FullName() string {
return repo.MustOwner().Name + "/" + repo.Name
return repo.MustOwnerName() + "/" + repo.Name
}
// HTMLURL returns the repository HTML URL
@ -479,6 +488,41 @@ func (repo *Repository) mustOwner(e Engine) *User {
return repo.Owner
}
func (repo *Repository) getOwnerName(e Engine) error {
if len(repo.OwnerName) > 0 {
return nil
}
if repo.Owner != nil {
repo.OwnerName = repo.Owner.Name
return nil
}
u := new(User)
has, err := e.ID(repo.OwnerID).Cols("name").Get(u)
if err != nil {
return err
} else if !has {
return ErrUserNotExist{repo.OwnerID, "", 0}
}
repo.OwnerName = u.Name
return nil
}
// GetOwnerName returns the repository owner name
func (repo *Repository) GetOwnerName() error {
return repo.getOwnerName(x)
}
func (repo *Repository) mustOwnerName(e Engine) string {
if err := repo.getOwnerName(e); err != nil {
log.Error(4, "Error loading repository owner name: %v", err)
return "error"
}
return repo.OwnerName
}
// ComposeMetas composes a map of metas for rendering external issue tracker URL.
func (repo *Repository) ComposeMetas() map[string]string {
unit, err := repo.GetUnit(UnitTypeExternalTracker)
@ -590,7 +634,7 @@ func (repo *Repository) GetBaseRepo() (err error) {
}
func (repo *Repository) repoPath(e Engine) string {
return RepoPath(repo.mustOwner(e).Name, repo.Name)
return RepoPath(repo.mustOwnerName(e), repo.Name)
}
// RepoPath returns the repository path
@ -2145,7 +2189,7 @@ func ReinitMissingRepositories() error {
// SyncRepositoryHooks rewrites all repositories' pre-receive, update and post-receive hooks
// to make sure the binary and custom conf path are up-to-date.
func SyncRepositoryHooks() error {
return x.Where("id > 0").Iterate(new(Repository),
return x.Cols("owner_id", "name").Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
if err := createDelegateHooks(bean.(*Repository).RepoPath()); err != nil {
return fmt.Errorf("SyncRepositoryHook: %v", err)

View File

@ -23,12 +23,13 @@ import (
// TwoFactor represents a two-factor authentication token.
type TwoFactor struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"UNIQUE"`
Secret string
ScratchToken string
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"UNIQUE"`
Secret string
ScratchToken string
LastUsedPasscode string `xorm:"VARCHAR(10)"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
}
// GenerateScratchToken recreates the scratch token the user is using.

View File

@ -652,7 +652,7 @@ func NewGhostUser() *User {
}
var (
reservedUsernames = []string{"assets", "css", "explore", "img", "js", "less", "plugins", "debug", "raw", "install", "api", "avatars", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new", ".", ".."}
reservedUsernames = []string{"assets", "css", "explore", "img", "js", "less", "plugins", "debug", "raw", "install", "api", "avatars", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "error", "new", ".", ".."}
reservedUserPatterns = []string{"*.keys"}
)

View File

@ -67,7 +67,7 @@ func WikiPath(userName, repoName string) string {
// WikiPath returns wiki data path for given repository.
func (repo *Repository) WikiPath() string {
return WikiPath(repo.MustOwner().Name, repo.Name)
return WikiPath(repo.MustOwnerName(), repo.Name)
}
// HasWiki returns true if repository has wiki.

View File

@ -153,6 +153,7 @@ func TestRepository_LocalWikiPath(t *testing.T) {
}
func TestRepository_AddWikiPage(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
const wikiContent = "This is the wiki content"
const commitMsg = "Commit message"
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
@ -161,23 +162,30 @@ func TestRepository_AddWikiPage(t *testing.T) {
"Another page",
"Here's a <tag> and a/slash",
} {
PrepareTestEnv(t)
assert.NoError(t, repo.AddWikiPage(doer, wikiName, wikiContent, commitMsg))
expectedPath := path.Join(repo.LocalWikiPath(), WikiNameToFilename(wikiName))
assert.True(t, com.IsExist(expectedPath))
wikiName := wikiName
t.Run("test wiki exist: "+wikiName, func(t *testing.T) {
t.Parallel()
assert.NoError(t, repo.AddWikiPage(doer, wikiName, wikiContent, commitMsg))
expectedPath := path.Join(repo.LocalWikiPath(), WikiNameToFilename(wikiName))
assert.True(t, com.IsExist(expectedPath))
})
}
// test for already-existing wiki name
PrepareTestEnv(t)
err := repo.AddWikiPage(doer, "Home", wikiContent, commitMsg)
assert.Error(t, err)
assert.True(t, IsErrWikiAlreadyExist(err))
t.Run("check wiki already exist", func(t *testing.T) {
t.Parallel()
// test for already-existing wiki name
err := repo.AddWikiPage(doer, "Home", wikiContent, commitMsg)
assert.Error(t, err)
assert.True(t, IsErrWikiAlreadyExist(err))
})
// test for reserved wiki name
PrepareTestEnv(t)
err = repo.AddWikiPage(doer, "_edit", wikiContent, commitMsg)
assert.Error(t, err)
assert.True(t, IsErrWikiReservedName(err))
t.Run("check wiki reserved name", func(t *testing.T) {
t.Parallel()
// test for reserved wiki name
err := repo.AddWikiPage(doer, "_edit", wikiContent, commitMsg)
assert.Error(t, err)
assert.True(t, IsErrWikiReservedName(err))
})
}
func TestRepository_EditWikiPage(t *testing.T) {

View File

@ -330,7 +330,6 @@ issues.num_participants=%d участника
issues.attachment.open_tab=`Щракнете за да прегледате "%s" в нов раздел`
issues.attachment.download=`Щракнете за да изтеглите "%s"`
pulls.new=Нова заявка за сливане
pulls.filter_branch=Филтър по клон
pulls.no_results=Няма резултати.

View File

@ -329,7 +329,6 @@ issues.num_participants=%d účastníků
issues.attachment.open_tab=`Klikněte pro zobrazení "%s" v nové záložce`
issues.attachment.download=`Klikněte pro stažení "%s"`
pulls.new=Nový požadavek na natažení
pulls.filter_branch=Filtrovat větev
pulls.no_results=Nebyly nalezeny žádné výsledky.

View File

@ -687,7 +687,6 @@ issues.add_time_minutes=Minuten
issues.cancel_tracking=Abbrechen
issues.cancel_tracking_history=hat die Zeiterfassung %s abgebrochen
pulls.new=Neuer Pull-Request
pulls.compare_changes=Neuer Pull-Request
pulls.compare_compare=pull von

View File

@ -419,7 +419,6 @@ issues.add_time_hours=Horas
issues.add_time_minutes=Minutos
issues.cancel_tracking=Cancelar
pulls.new=Nuevo Pull Request
pulls.filter_branch=Filtrar rama
pulls.no_results=Sin resultados.

View File

@ -314,7 +314,6 @@ issues.label.filter_sort.alphabetically=Aakkosjärjestyksessä
issues.label.filter_sort.reverse_alphabetically=Käänteisessä aakkosjärjestyksessä
issues.num_participants=%d osallistujaa
pulls.new=Uusi pull pyyntö
pulls.filter_branch=Suodata branch
pulls.no_results=Tuloksia ei löytynyt.

View File

@ -435,7 +435,6 @@ issues.add_time_minutes=Minutes
issues.cancel_tracking=Annuler
issues.cancel_tracking_history=`a annulé le suivi de temps pour %s`
pulls.new=Nouvelle demande d'ajout
pulls.filter_branch=Filtre de branche
pulls.no_results=Aucun résultat trouvé.

View File

@ -443,7 +443,6 @@ issues.add_time_minutes=Perc
issues.cancel_tracking=Megszakítva
issues.cancel_tracking_history=`törölte az időzítőt %s`
pulls.new=Egyesítési kérés
pulls.filter_branch=Ágra szűrés
pulls.no_results=Nincs találat.

View File

@ -435,7 +435,6 @@ issues.add_time_minutes=Menit
issues.cancel_tracking=Batal
issues.cancel_tracking_history=`batalkan pelacakan waktu %s`
pulls.new=Permintaan Tarik Baru
pulls.filter_branch=Penyaringan cabang
pulls.no_results=Hasil tidak ditemukan.

View File

@ -380,7 +380,6 @@ issues.label_edit=Modifica
issues.label_delete=Elimina
issues.num_participants=%d Partecipanti
pulls.new=Nuova Pull Request
pulls.filter_branch=Filtra branch
pulls.no_results=Nessun risultato trovato.

View File

@ -434,7 +434,6 @@ issues.add_time_minutes=分
issues.cancel_tracking=キャンセル
issues.cancel_tracking_history=`が %s にタイムトラッキングを中断`
pulls.new=新しいプルリクエスト
pulls.filter_branch=フィルターブランチ
pulls.no_results=結果が見つかりませんでした。

View File

@ -405,7 +405,6 @@ issues.add_time_hours=시간
issues.add_time_minutes=
issues.cancel_tracking=취소
pulls.new=새 풀 리퀘스트
pulls.filter_branch=Filter Branch
pulls.no_results=결과 없음

View File

@ -238,7 +238,6 @@ issues.save=Saugoti
[org]

View File

@ -443,7 +443,6 @@ issues.add_time_minutes=Minūtes
issues.cancel_tracking=Atcelt
issues.cancel_tracking_history=` atcēla laika uzskaiti %s`
pulls.new=Jauns izmaiņu pieprasījums
pulls.filter_branch=Filtrēt atzarus
pulls.no_results=Nekas netika atrasts.

View File

@ -114,7 +114,6 @@ admin_password=Passord
[org]

View File

@ -432,7 +432,6 @@ issues.add_time_minutes=Minuten
issues.cancel_tracking=Annuleren
issues.cancel_tracking_history=`tijd bijhouden geannuleerd: %s`
pulls.new=Nieuwe Pull aanvraag
pulls.filter_branch=Filter branch
pulls.no_results=Geen resultaten gevonden.

View File

@ -64,7 +64,6 @@
[org]

View File

@ -102,7 +102,6 @@ smtp_host=SMTP-vert
[org]

View File

@ -435,7 +435,6 @@ issues.add_time_minutes=Minuty
issues.cancel_tracking=Anuluj
issues.cancel_tracking_history=`anulowanie śledzenie czasu %s`
pulls.new=Nowy pull request
pulls.filter_branch=Filtruj branch
pulls.no_results=Nie znaleziono wyników.

View File

@ -736,8 +736,22 @@ issues.add_time_minutes=Minutos
issues.add_time_sum_to_small=Nenhum tempo foi inserido.
issues.cancel_tracking=Cancelar
issues.cancel_tracking_history=`cancelou contador de tempo %s`
issues.time_spent_total=Tempo total gasto
issues.time_spent_from_all_authors=`Tempo total gasto: %s`
issues.due_date=Data limite
issues.invalid_due_date_format=Formato da data limite inválido, deve ser 'aaaa-mm-dd'.
issues.error_modifying_due_date=Ocorreu um erro ao modificar a data limite.
issues.error_removing_due_date=Ocorreu um erro ao remover a data limite.
issues.due_date_form=Data limite, formato aaaa-mm-dd
issues.due_date_form_add=Adicionar data limite
issues.due_date_form_update=Modificar data limite
issues.due_date_form_remove=Remover data limite
issues.due_date_not_writer=Você precisa ter pelo menos permissão de escrita neste repositório para atualizar a data limite desta issue.
issues.due_date_not_set=Data limite não informada.
issues.due_date_added=adicionou a data limite %s %s
issues.due_date_modified=modificou a data limite para %s %s %s
issues.due_date_remove=removeu a data limite %s %s
issues.due_date_overdue=Em atraso
pulls.desc=Habilitar solicitações de merge e revisões de código.
pulls.new=Novo pull request
@ -784,7 +798,7 @@ milestones.title=Título
milestones.desc=Descrição
milestones.due_date=Prazo (opcional)
milestones.clear=Limpar
milestones.invalid_due_date_format=Formato de data inválido; deve ser 'aaaa-mm-dd'.
milestones.invalid_due_date_format=Formato da data limite deve ser 'aaaa-mm-dd'.
milestones.create_success=O marco '%s' foi criado.
milestones.edit=Editar marco
milestones.edit_subheader=Marcos organizam as issues e acompanham o progresso.

View File

@ -571,7 +571,6 @@ issues.add_time_minutes=Минуты
issues.cancel_tracking=Отмена
issues.cancel_tracking_history=`отменил отслеживание %s`
pulls.new=Новый Pull Request
pulls.filter_branch=Фильтр по ветке
pulls.no_results=Результатов не найдено.

View File

@ -64,7 +64,6 @@
[org]

View File

@ -329,7 +329,6 @@ issues.num_participants=%d учесника
issues.attachment.open_tab=`Кликните "%s" да видите у новом прозору`
issues.attachment.download=`Кликните да преузмете "%s"`
pulls.new=Нови захтев за спајање
pulls.filter_branch=Филтер по грани
pulls.no_results=Нема резултата.

View File

@ -419,7 +419,6 @@ issues.unsubscribe=Avsluta prenumerationen
issues.add_time_hours=Timmar
issues.add_time_minutes=Minuter
pulls.new=Ny Pull-Förfrågan
pulls.filter_branch=Filtrera gren
pulls.no_results=Inga resultat hittades.

View File

@ -433,7 +433,6 @@ issues.add_time_minutes=Dakika
issues.cancel_tracking=İptal
issues.cancel_tracking_history=` %s zaman izleyicisi iptal edildi `
pulls.new=Yeni Değişiklik İsteği
pulls.filter_branch=Dal filtrele
pulls.no_results=Sonuç bulunamadı.

View File

@ -480,7 +480,6 @@ issues.add_time_hours=Години
issues.add_time_minutes=Хвилини
issues.cancel_tracking=Відміна
pulls.new=Новий запит на злиття
pulls.compare_changes=Новий запит на злиття
pulls.filter_branch=Фільтр по гілці

View File

@ -443,7 +443,6 @@ issues.add_time_minutes=分钟
issues.cancel_tracking=取消
issues.cancel_tracking_history=`取消时间跟踪 %s`
pulls.new=创建合并请求
pulls.filter_branch=过滤分支
pulls.no_results=未找到结果

View File

@ -410,7 +410,6 @@ issues.attachment.download=`點擊下載 '%s'`
issues.subscribe=訂閱
issues.unsubscribe=取消訂閱
pulls.new=建立合併請求
pulls.filter_branch=過濾分支
pulls.no_results=未找到結果

View File

@ -434,7 +434,6 @@ issues.add_time_minutes=分鐘
issues.cancel_tracking=取消
issues.cancel_tracking_history=`取消時間追蹤 %s`
pulls.new=建立合併請求
pulls.filter_branch=過濾分支
pulls.no_results=未找到結果

View File

@ -221,7 +221,7 @@ func TwoFactorPost(ctx *context.Context, form auth.TwoFactorAuthForm) {
return
}
if ok {
if ok && twofa.LastUsedPasscode != form.Passcode {
remember := ctx.Session.Get("twofaRemember").(bool)
u, err := models.GetUserByID(id)
if err != nil {
@ -243,6 +243,12 @@ func TwoFactorPost(ctx *context.Context, form auth.TwoFactorAuthForm) {
}
}
twofa.LastUsedPasscode = form.Passcode
if err = models.UpdateTwoFactor(twofa); err != nil {
ctx.ServerError("UserSignIn", err)
return
}
handleSignIn(ctx, u, remember)
return
}