mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-03-26 16:13:05 -04:00
The forgejo admin command line allows to deal with all the propose auth mecanism but pam, this PR adds full support for adding and updating pam auth mecanism via the command line without limitation. Co-authored-by: Gusted <postmaster@gusted.xyz> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10388 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Baptiste Daroussin <bapt@FreeBSD.org> Co-committed-by: Baptiste Daroussin <bapt@FreeBSD.org>
293 lines
6.3 KiB
Go
293 lines
6.3 KiB
Go
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"forgejo.org/models/auth"
|
|
"forgejo.org/modules/test"
|
|
"forgejo.org/services/auth/source/pam"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/urfave/cli/v3"
|
|
)
|
|
|
|
func TestPamService(t *testing.T) {
|
|
// Mock cli functions to do not exit on error
|
|
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
|
|
|
|
// Test cases
|
|
cases := []struct {
|
|
args []string
|
|
source *auth.Source
|
|
errMsg string
|
|
}{
|
|
// case 0
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--name", "Pam Service",
|
|
"--service-name", "myservice",
|
|
},
|
|
source: &auth.Source{
|
|
Type: auth.PAM,
|
|
Name: "Pam Service",
|
|
IsActive: true,
|
|
Cfg: &pam.Source{
|
|
ServiceName: "myservice",
|
|
EmailDomain: "",
|
|
SkipLocalTwoFA: true,
|
|
},
|
|
},
|
|
},
|
|
// case 1
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--name", "Pam Service",
|
|
"--service-name", "myservice",
|
|
"--email-domain", "testdomain.org",
|
|
"--skip-local-2fa",
|
|
},
|
|
source: &auth.Source{
|
|
Type: auth.PAM,
|
|
Name: "Pam Service",
|
|
IsActive: true,
|
|
Cfg: &pam.Source{
|
|
ServiceName: "myservice",
|
|
EmailDomain: "testdomain.org",
|
|
SkipLocalTwoFA: true,
|
|
},
|
|
},
|
|
},
|
|
// case 2
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--service-name", "myservice",
|
|
"--email-domain", "testdomain.org",
|
|
"--skip-local-2fa", "false",
|
|
"--active", "true",
|
|
},
|
|
errMsg: "name must be set",
|
|
},
|
|
// case 3
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--name", "Pam Service",
|
|
"--email-domain", "testdomain.org",
|
|
"--skip-local-2fa", "false",
|
|
"--active", "true",
|
|
},
|
|
errMsg: "service-name must be set",
|
|
},
|
|
}
|
|
|
|
for n, c := range cases {
|
|
// Mock functions.
|
|
var createdAuthSource *auth.Source
|
|
service := &authService{
|
|
initDB: func(context.Context) error {
|
|
return nil
|
|
},
|
|
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
|
createdAuthSource = authSource
|
|
return nil
|
|
},
|
|
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
|
assert.FailNow(t, "should not call updateAuthSource", "case: %d", n)
|
|
return nil
|
|
},
|
|
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
|
|
assert.FailNow(t, "should not call getAuthSourceByID", "case: %d", n)
|
|
return nil, nil
|
|
},
|
|
}
|
|
|
|
// Create a copy of command to test
|
|
app := cli.Command{}
|
|
app.Flags = microcmdAuthAddPAM().Flags
|
|
app.Action = service.addPAM
|
|
|
|
// Run it
|
|
err := app.Run(t.Context(), c.args)
|
|
if c.errMsg != "" {
|
|
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
|
|
} else {
|
|
require.NoError(t, err, "case %d: should have no errors", n)
|
|
assert.Equal(t, c.source, createdAuthSource, "case %d: wrong authSource", n)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUpdatePAM(t *testing.T) {
|
|
// Mock cli functions to do not exit on error
|
|
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
|
|
|
|
// Test cases
|
|
cases := []struct {
|
|
args []string
|
|
id int64
|
|
existingAuthSource *auth.Source
|
|
authSource *auth.Source
|
|
errMsg string
|
|
}{
|
|
// case 0
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--id", "23",
|
|
"--name", "PAM Service",
|
|
"--service-name", "myservice",
|
|
},
|
|
id: 23,
|
|
existingAuthSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
IsActive: true,
|
|
Cfg: &pam.Source{},
|
|
},
|
|
authSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
Name: "PAM Service",
|
|
IsActive: true,
|
|
Cfg: &pam.Source{
|
|
ServiceName: "myservice",
|
|
},
|
|
},
|
|
},
|
|
// case 1
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--id", "1",
|
|
},
|
|
authSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
Cfg: &pam.Source{},
|
|
},
|
|
},
|
|
// case 2
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--id", "1",
|
|
"--name", "pam service",
|
|
},
|
|
authSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
Name: "pam service",
|
|
Cfg: &pam.Source{},
|
|
},
|
|
},
|
|
// case 3
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--id", "1",
|
|
"--active=false",
|
|
},
|
|
existingAuthSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
IsActive: true,
|
|
Cfg: &pam.Source{},
|
|
},
|
|
authSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
IsActive: false,
|
|
Cfg: &pam.Source{},
|
|
},
|
|
},
|
|
// case 4
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--id", "1",
|
|
"--service-name", "myservice",
|
|
},
|
|
authSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
Cfg: &pam.Source{
|
|
ServiceName: "myservice",
|
|
},
|
|
},
|
|
},
|
|
// case 5
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--id", "1",
|
|
"--skip-local-2fa=false",
|
|
},
|
|
authSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
Cfg: &pam.Source{
|
|
SkipLocalTwoFA: false,
|
|
},
|
|
},
|
|
},
|
|
// case 6
|
|
{
|
|
args: []string{
|
|
"pam-test",
|
|
"--id", "1",
|
|
"--email-domain", "testdomain.org",
|
|
},
|
|
authSource: &auth.Source{
|
|
Type: auth.PAM,
|
|
Cfg: &pam.Source{
|
|
EmailDomain: "testdomain.org",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for n, c := range cases {
|
|
// Mock functions.
|
|
var updatedAuthSource *auth.Source
|
|
service := &authService{
|
|
initDB: func(context.Context) error {
|
|
return nil
|
|
},
|
|
createAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
|
assert.FailNow(t, "should not call createAuthSource", "case: %d", n)
|
|
return nil
|
|
},
|
|
updateAuthSource: func(ctx context.Context, authSource *auth.Source) error {
|
|
updatedAuthSource = authSource
|
|
return nil
|
|
},
|
|
getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) {
|
|
if c.id != 0 {
|
|
assert.Equal(t, c.id, id, "case %d: wrong id", n)
|
|
}
|
|
if c.existingAuthSource != nil {
|
|
return c.existingAuthSource, nil
|
|
}
|
|
return &auth.Source{
|
|
Type: auth.PAM,
|
|
Cfg: &pam.Source{},
|
|
}, nil
|
|
},
|
|
}
|
|
|
|
// Create a copy of command to test
|
|
app := cli.Command{}
|
|
app.Flags = microcmdAuthUpdatePAM().Flags
|
|
app.Action = service.updatePAM
|
|
|
|
// Run it
|
|
err := app.Run(t.Context(), c.args)
|
|
if c.errMsg != "" {
|
|
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
|
|
} else {
|
|
require.NoError(t, err, "case %d: should have no errors", n)
|
|
assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n)
|
|
}
|
|
}
|
|
}
|