1
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-04-18 00:47:48 -04:00

add models and services

This commit is contained in:
Lunny Xiao 2022-10-07 22:43:56 +08:00 committed by Jason Song
parent 4af45f7bc9
commit ab4f539453
6 changed files with 201 additions and 0 deletions

54
models/auth/secret.go Normal file
View File

@ -0,0 +1,54 @@
// Copyright 2022 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 auth
import (
"fmt"
"regexp"
"code.gitea.io/gitea/modules/timeutil"
)
type ErrSecretNameInvalid struct {
Name string
}
func (err ErrSecretNameInvalid) Error() string {
return fmt.Sprintf("secret name %s is invalid", err.Name)
}
type ErrSecretDataInvalid struct {
Data string
}
func (err ErrSecretDataInvalid) Error() string {
return fmt.Sprintf("secret data %s is invalid", err.Data)
}
var nameRE = regexp.MustCompile("[^a-zA-Z0-9-_.]+")
type Secret struct {
ID int64
UserID int64 `xorm:"index"`
RepoID int64 `xorm:"index"`
Name string
Data string
PullRequest bool
CreatedUnix timeutil.TimeStamp
}
// Validate validates the required fields and formats.
func (s *Secret) Validate() error {
switch {
case len(s.Name) == 0:
return ErrSecretNameInvalid{Name: s.Name}
case len(s.Data) == 0:
return ErrSecretDataInvalid{Data: s.Data}
case nameRE.MatchString(s.Name):
return ErrSecretNameInvalid{Name: s.Name}
default:
return nil
}
}

View File

@ -4,6 +4,12 @@
package db
import (
"context"
"xorm.io/builder"
)
// SearchOrderBy is used to sort the result
type SearchOrderBy string
@ -28,3 +34,14 @@ const (
SearchOrderByForks SearchOrderBy = "num_forks ASC"
SearchOrderByForksReverse SearchOrderBy = "num_forks DESC"
)
func FindObjects[Object any](ctx context.Context, cond builder.Cond, opts *ListOptions, objects *[]*Object) error {
sess := GetEngine(ctx).Where(cond)
if opts != nil && opts.PageSize > 0 {
if opts.Page < 1 {
opts.Page = 1
}
sess.Limit(opts.PageSize, opts.PageSize * (opts.Page - 1))
}
return sess.Find(objects)
}

View File

@ -46,6 +46,7 @@ import (
org_service "code.gitea.io/gitea/services/org"
repo_service "code.gitea.io/gitea/services/repository"
wiki_service "code.gitea.io/gitea/services/wiki"
secret_service "code.gitea.io/gitea/services/secrets"
)
const (
@ -1113,6 +1114,13 @@ func DeployKeys(ctx *context.Context) {
}
ctx.Data["Deploykeys"] = keys
tokens, err := secret_service.FindRepoSecrets(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.ServerError("FindRepoSecrets", err)
return
}
ctx.Data["Tokens"] = tokens
ctx.HTML(http.StatusOK, tplDeployKeys)
}

View File

@ -5,9 +5,14 @@
package secrets
import (
"context"
"fmt"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/setting"
"xorm.io/builder"
)
// MasterKeyProviderType is the type of master key provider
@ -96,3 +101,45 @@ func DecryptString(enc string) (string, error) {
return encProvider.DecryptString(enc, key)
}
func InsertRepoSecret(ctx context.Context, repoID int64, key, data string, pullRequest bool) error {
v, err := EncryptString( data)
if err != nil {
return err
}
return db.Insert(ctx, &auth_model.Secret{
RepoID: repoID,
Name: key,
Data: v,
PullRequest: pullRequest,
})
}
func InsertOrgSecret(ctx context.Context, userID int64, key, data string, pullRequest bool) error {
v, err := EncryptString(data)
if err != nil {
return err
}
return db.Insert(ctx, &auth_model.Secret{
UserID: userID,
Name: key,
Data: v,
PullRequest: pullRequest,
})
}
func DeleteSecretByID(ctx context.Context, id int64) error {
_, err := db.DeleteByBean(ctx, &auth_model.Secret{ID: id})
return err
}
func FindRepoSecrets(ctx context.Context,repoID int64) ([]*auth_model.Secret, error) {
var res []*auth_model.Secret
return res, db.FindObjects(ctx, builder.Eq{"repo_id": repoID}, nil,&res)
}
func FindUserSecrets(ctx context.Context, userID int64) ([]*auth_model.Secret, error) {
var res []*auth_model.Secret
return res, db.FindObjects(ctx, builder.Eq{"user_id": userID}, nil,&res)
}

View File

@ -75,6 +75,8 @@
{{end}}
</div>
</div>
{{template "settings/tokens" .}}
</div>
<div class="ui small basic delete modal">

View File

@ -0,0 +1,73 @@
<div class="ui container">
{{template "base/alert" .}}
<h4 class="ui top attached header">
{{.locale.Tr "repo.settings.deploy_keys"}}
<div class="ui right">
{{if not .DisableSSH}}
<div class="ui primary tiny show-panel button" data-panel="#add-deploy-key-panel">{{.locale.Tr "repo.settings.add_deploy_key"}}</div>
{{else}}
<div class="ui primary tiny button disabled">{{.locale.Tr "settings.ssh_disabled"}}</div>
{{end}}
</div>
</h4>
<div class="ui attached segment">
<div class="{{if not .HasError}}hide{{end}} mb-4" id="add-deploy-key-panel">
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="field">
{{.locale.Tr "repo.settings.deploy_key_desc"}}
</div>
<div class="field {{if .Err_Title}}error{{end}}">
<label for="title">{{.locale.Tr "repo.settings.title"}}</label>
<input id="ssh-key-title" name="title" value="{{.title}}" autofocus required>
</div>
<div class="field {{if .Err_Content}}error{{end}}">
<label for="content">{{.locale.Tr "repo.settings.deploy_key_content"}}</label>
<textarea id="ssh-key-content" name="content" placeholder="{{.locale.Tr "settings.key_content_ssh_placeholder"}}" required>{{.content}}</textarea>
</div>
<div class="field">
<div class="ui checkbox {{if .Err_IsWritable}}error{{end}}">
<input id="ssh-key-is-writable" name="is_writable" class="hidden" type="checkbox" value="1">
<label for="is_writable">
{{.locale.Tr "repo.settings.is_writable"}}
</label>
<small style="padding-left: 26px;">{{$.locale.Tr "repo.settings.is_writable_info" | Str2html}}</small>
</div>
</div>
<button class="ui green button">
{{.locale.Tr "repo.settings.add_deploy_key"}}
</button>
<button class="ui hide-panel button" data-panel="#add-deploy-key-panel">
{{.locale.Tr "cancel"}}
</button>
</form>
</div>
{{if .Deploykeys}}
<div class="ui key list">
{{range .Deploykeys}}
<div class="item">
<div class="right floated content">
<button class="ui red tiny button delete-button" data-url="{{$.Link}}/delete" data-id="{{.ID}}">
{{$.locale.Tr "settings.delete_key"}}
</button>
</div>
<div class="left floated content">
<i class="tooltip{{if .HasRecentActivity}} green{{end}}" {{if .HasRecentActivity}}data-content="{{$.locale.Tr "settings.key_state_desc"}}"{{end}}>{{svg "octicon-key" 32}}</i>
</div>
<div class="content">
<strong>{{.Name}}</strong>
<div class="print meta">
{{.Fingerprint}}
</div>
<div class="activity meta">
<i>{{$.locale.Tr "settings.add_on"}} <span>{{.CreatedUnix.FormatShort}}</span> — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{.UpdatedUnix.FormatShort}}</span>{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}} - <span>{{$.locale.Tr "settings.can_read_info"}}{{if not .IsReadOnly}} / {{$.locale.Tr "settings.can_write_info"}} {{end}}</span></i>
</div>
</div>
</div>
{{end}}
</div>
{{else}}
{{.locale.Tr "repo.settings.no_deploy_keys"}}
{{end}}
</div>
</div>