Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions pkg/backend/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,39 @@ func (b *Backend) SetAnonAccess(ctx context.Context, level access.AccessLevel) e
return b.store.SetAnonAccess(ctx, tx, level)
})
}

// IsDefaultRepoPrivate returns whether new repositories are created as private
// by default.
func (b *Backend) IsDefaultRepoPrivate(ctx context.Context) bool {
var visibility string
if err := b.db.TransactionContext(ctx, func(tx *db.Tx) error {
var err error
visibility, err = b.store.GetDefaultRepoVisibility(ctx, tx)
return err
}); err != nil {
return false
}

return visibility == "private"
}

// DefaultRepoVisibility returns the default repo visibility setting.
func (b *Backend) DefaultRepoVisibility(ctx context.Context) string {
var visibility string
if err := b.db.TransactionContext(ctx, func(tx *db.Tx) error {
var err error
visibility, err = b.store.GetDefaultRepoVisibility(ctx, tx)
return err
}); err != nil {
return "public"
}

return visibility
}

// SetDefaultRepoVisibility sets the default repo visibility.
func (b *Backend) SetDefaultRepoVisibility(ctx context.Context, visibility string) error {
return b.db.TransactionContext(ctx, func(tx *db.Tx) error {
return b.store.SetDefaultRepoVisibility(ctx, tx, visibility)
})
}
23 changes: 23 additions & 0 deletions pkg/db/migrate/0004_default_repo_visibility.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package migrate

import (
"context"

"github.com/charmbracelet/soft-serve/pkg/db"
)

const (
defaultRepoVisibilityName = "default_repo_visibility"
defaultRepoVisibilityVersion = 4
)

var defaultRepoVisibility = Migration{
Name: defaultRepoVisibilityName,
Version: defaultRepoVisibilityVersion,
Migrate: func(ctx context.Context, tx *db.Tx) error {
return migrateUp(ctx, tx, defaultRepoVisibilityVersion, defaultRepoVisibilityName)
},
Rollback: func(ctx context.Context, tx *db.Tx) error {
return migrateDown(ctx, tx, defaultRepoVisibilityVersion, defaultRepoVisibilityName)
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM settings WHERE "key" = 'default_repo_visibility';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INSERT INTO settings ("key", value, updated_at) VALUES ('default_repo_visibility', 'public', CURRENT_TIMESTAMP);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM settings WHERE "key" = 'default_repo_visibility';
1 change: 1 addition & 0 deletions pkg/db/migrate/0004_default_repo_visibility_sqlite.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INSERT INTO settings ("key", value, updated_at) VALUES ('default_repo_visibility', 'public', CURRENT_TIMESTAMP);
1 change: 1 addition & 0 deletions pkg/db/migrate/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var migrations = []Migration{
createTables,
webhooks,
migrateLfsObjects,
defaultRepoVisibility,
}

func execMigration(ctx context.Context, tx *db.Tx, version int, name string, down bool) error {
Expand Down
3 changes: 3 additions & 0 deletions pkg/ssh/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ func createCommand() *cobra.Command {
be := backend.FromContext(ctx)
user := proto.UserFromContext(ctx)
name := args[0]
if !cmd.Flags().Changed("private") {
private = be.IsDefaultRepoPrivate(ctx)
}
r, err := be.CreateRepository(ctx, name, user, proto.RepositoryOptions{
Private: private,
Description: description,
Expand Down
2 changes: 1 addition & 1 deletion pkg/ssh/cmd/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func gitRunE(cmd *cobra.Command, args []string) error {
return git.ErrNotAuthed
}
if repo == nil {
if _, err := be.CreateRepository(ctx, name, user, proto.RepositoryOptions{Private: false}); err != nil {
if _, err := be.CreateRepository(ctx, name, user, proto.RepositoryOptions{Private: be.IsDefaultRepoPrivate(ctx)}); err != nil {
log.Errorf("failed to create repo: %s", err)
return err
}
Expand Down
29 changes: 29 additions & 0 deletions pkg/ssh/cmd/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,34 @@ func SettingsCommand() *cobra.Command {
},
)

vls := []string{"public", "private"}
cmd.AddCommand(
&cobra.Command{
Use: "default-repo-visibility [public|private]",
Short: "Set or get the default visibility for new repositories",
Args: cobra.RangeArgs(0, 1),
ValidArgs: vls,
PersistentPreRunE: checkIfAdmin,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
be := backend.FromContext(ctx)
switch len(args) {
case 0:
cmd.Println(be.DefaultRepoVisibility(ctx))
case 1:
v := args[0]
if v != "public" && v != "private" {
return fmt.Errorf("invalid visibility: %s. Please choose one of the following: %s", v, vls)
}
if err := be.SetDefaultRepoVisibility(ctx, v); err != nil {
return err
}
}

return nil
},
},
)

return cmd
}
17 changes: 17 additions & 0 deletions pkg/store/database/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,20 @@ func (*settingsStore) SetAnonAccess(ctx context.Context, tx db.Handler, level ac
_, err := tx.ExecContext(ctx, query, level.String())
return db.WrapError(err)
}

// GetDefaultRepoVisibility implements store.SettingStore.
func (*settingsStore) GetDefaultRepoVisibility(ctx context.Context, tx db.Handler) (string, error) {
var visibility string
query := tx.Rebind(`SELECT value FROM settings WHERE "key" = 'default_repo_visibility'`)
if err := tx.GetContext(ctx, &visibility, query); err != nil {
return "public", db.WrapError(err)
}
return visibility, nil
}

// SetDefaultRepoVisibility implements store.SettingStore.
func (*settingsStore) SetDefaultRepoVisibility(ctx context.Context, tx db.Handler, visibility string) error {
query := tx.Rebind(`UPDATE settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE "key" = 'default_repo_visibility'`)
_, err := tx.ExecContext(ctx, query, visibility)
return db.WrapError(err)
}
2 changes: 2 additions & 0 deletions pkg/store/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ type SettingStore interface {
SetAnonAccess(ctx context.Context, h db.Handler, level access.AccessLevel) error
GetAllowKeylessAccess(ctx context.Context, h db.Handler) (bool, error)
SetAllowKeylessAccess(ctx context.Context, h db.Handler, allow bool) error
GetDefaultRepoVisibility(ctx context.Context, h db.Handler) (string, error)
SetDefaultRepoVisibility(ctx context.Context, h db.Handler, visibility string) error
}
2 changes: 1 addition & 1 deletion pkg/web/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func withAccess(next http.Handler) http.HandlerFunc {

// Create the repo if it doesn't exist.
if repo == nil {
repo, err = be.CreateRepository(ctx, repoName, user, proto.RepositoryOptions{})
repo, err = be.CreateRepository(ctx, repoName, user, proto.RepositoryOptions{Private: be.IsDefaultRepoPrivate(ctx)})
if err != nil {
logger.Error("failed to create repository", "repo", repoName, "err", err)
renderInternalServerError(w, r)
Expand Down
18 changes: 18 additions & 0 deletions testscript/testdata/settings.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ stdout 'admin-access.*'
! stdout .
stderr .

# check default repo visibility
soft settings default-repo-visibility
stdout 'public.*'

# change default-repo-visibility and check
soft settings default-repo-visibility private
soft settings default-repo-visibility
stdout 'private.*'

soft settings default-repo-visibility public
soft settings default-repo-visibility
stdout 'public.*'

# try to set a bad visibility
! soft settings default-repo-visibility nope
! stdout .
stderr .

# stop the server
[windows] stopserver