mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 13:11:49 +00:00
authtest: add tests for site admin endpoints (#20266)
This commit is contained in:
parent
e665321d03
commit
16a7bb1cb4
3
dev/authtest/CODENOTIFY
Normal file
3
dev/authtest/CODENOTIFY
Normal file
@ -0,0 +1,3 @@
|
||||
# See https://github.com/sourcegraph/codenotify for documentation.
|
||||
|
||||
**/* @unknwon
|
||||
@ -24,6 +24,8 @@ var (
|
||||
password = flag.String("password", "supersecurepassword", "The password of the admin user")
|
||||
|
||||
githubToken = flag.String("github-token", os.Getenv("GITHUB_TOKEN"), "The GitHub personal access token that will be used to authenticate a GitHub external service")
|
||||
|
||||
dotcom = flag.Bool("dotcom", false, "Whether to test dotcom specific constraints")
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
||||
@ -1,29 +1,442 @@
|
||||
package authtest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/internal/gqltestutil"
|
||||
)
|
||||
|
||||
func TestSiteAdminEndpoints(t *testing.T) {
|
||||
// Create a test user (authtest-user-1) which is not a site admin, the user
|
||||
// should receive access denied for site admin endpoints.
|
||||
const testUsername = "authtest-user-1"
|
||||
testUserID, err := client.CreateUser(testUsername, testUsername+"@sourcegraph.com")
|
||||
userClient, err := gqltestutil.SignUp(*baseURL, testUsername+"@sourcegraph.com", testUsername, "mysecurepassword")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
err := client.DeleteUser(testUserID, true)
|
||||
err := client.DeleteUser(userClient.AuthenticatedUserID(), true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
t.Run("HTTP endpoints", func(t *testing.T) {
|
||||
// TODO(jchen): Add HTTP endpoints that are site-admin-only
|
||||
t.Run("debug endpoints", func(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
}{
|
||||
{
|
||||
name: "debug",
|
||||
path: "/-/debug/",
|
||||
}, {
|
||||
name: "jaeger",
|
||||
path: "/-/debug/jaeger/",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
resp, err := userClient.Get(*baseURL + test.path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if resp.StatusCode != http.StatusUnauthorized {
|
||||
t.Fatalf(`Want status code %d error but got %d`, http.StatusUnauthorized, resp.StatusCode)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("latest ping", func(t *testing.T) {
|
||||
resp, err := userClient.Get(*baseURL + "/site-admin/pings/latest")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if want, got := http.StatusUnauthorized, resp.StatusCode; want != got {
|
||||
t.Fatalf("Want %d but got %d", want, got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("usage stats archive", func(t *testing.T) {
|
||||
resp, err := userClient.Get(*baseURL + "/site-admin/usage-statistics/archive")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if want, got := http.StatusUnauthorized, resp.StatusCode; want != got {
|
||||
t.Fatalf("Want %d but got %d", want, got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("GraphQL queries", func(t *testing.T) {
|
||||
// TODO(jchen): Add GraphQL queries that are site-admin-only
|
||||
type gqlTest struct {
|
||||
name string
|
||||
query string
|
||||
variables map[string]interface{}
|
||||
}
|
||||
tests := []gqlTest{
|
||||
{
|
||||
name: "resetTriggerQueryTimestamps",
|
||||
query: `
|
||||
mutation {
|
||||
resetTriggerQueryTimestamps(id: "SUQ6MTIz") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "dotcom.productLicenses",
|
||||
query: `
|
||||
{
|
||||
dotcom {
|
||||
productLicenses {
|
||||
__typename
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "dotcom.createProductSubscription",
|
||||
query: `
|
||||
mutation {
|
||||
dotcom {
|
||||
createProductSubscription(accountID: "VXNlcjox") {
|
||||
id
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "dotcom.setProductSubscriptionBilling",
|
||||
query: `
|
||||
mutation {
|
||||
dotcom {
|
||||
setProductSubscriptionBilling(id: "VXNlcjox") {
|
||||
alwaysNil
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "dotcom.archiveProductSubscription",
|
||||
query: `
|
||||
mutation {
|
||||
dotcom {
|
||||
archiveProductSubscription(id: "VXNlcjox") {
|
||||
alwaysNil
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "dotcom.generateProductLicenseForSubscription",
|
||||
query: `
|
||||
mutation {
|
||||
dotcom {
|
||||
generateProductLicenseForSubscription(
|
||||
productSubscriptionID: "UHJvZHVjdFN1YnNjcmlwdGlvbjox"
|
||||
license: {tags: [], userCount: 1, expiresAt: 1}
|
||||
) {
|
||||
id
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "dotcom.setUserBilling",
|
||||
query: `
|
||||
mutation {
|
||||
dotcom {
|
||||
setUserBilling(user: "VXNlcjox", billingCustomerID: "404") {
|
||||
alwaysNil
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "updateMirrorRepository",
|
||||
query: `
|
||||
mutation {
|
||||
updateMirrorRepository(repository: "UmVwb3NpdG9yeTox") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "addUserToOrganization",
|
||||
query: `
|
||||
mutation {
|
||||
addUserToOrganization(organization: "T3JnYW5pemF0aW9uOjE=", username: "alice") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "site.configuration",
|
||||
query: `
|
||||
{
|
||||
site {
|
||||
configuration {
|
||||
id
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "site.accessTokens",
|
||||
query: `
|
||||
{
|
||||
site {
|
||||
accessTokens {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "site.externalAccounts",
|
||||
query: `
|
||||
{
|
||||
site {
|
||||
externalAccounts {
|
||||
nodes {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "updateSiteConfiguration",
|
||||
query: `
|
||||
mutation {
|
||||
updateSiteConfiguration(input: "", lastID: 0)
|
||||
}`,
|
||||
}, {
|
||||
name: "deleteLSIFUpload",
|
||||
query: `
|
||||
mutation {
|
||||
deleteLSIFUpload(id: "TFNJRjox") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "outOfBandMigrations",
|
||||
query: `
|
||||
{
|
||||
outOfBandMigrations {
|
||||
id
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "SetMigrationDirection",
|
||||
query: `
|
||||
mutation {
|
||||
SetMigrationDirection(id: "TWlncmF0aW9uOjE=", applyReverse: false) {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "sendSavedSearchTestNotification",
|
||||
query: `
|
||||
mutation {
|
||||
sendSavedSearchTestNotification(id: "U2F2ZWRTZWFyY2g6MQ==") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "createAccessToken.ScopeSiteAdminSudo",
|
||||
query: `
|
||||
mutation CreateAccessToken($userID: ID!) {
|
||||
createAccessToken(user: $userID, scopes: ["site-admin:sudo"], note: "") {
|
||||
id
|
||||
}
|
||||
}`,
|
||||
variables: map[string]interface{}{
|
||||
"userID": userClient.AuthenticatedUserID(),
|
||||
},
|
||||
}, {
|
||||
name: "setRepositoryPermissionsForUsers",
|
||||
query: `
|
||||
mutation {
|
||||
setRepositoryPermissionsForUsers(
|
||||
repository: "UmVwb3NpdG9yeTox"
|
||||
userPermissions: [{bindID: "alice@example.com"}]
|
||||
) {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "scheduleRepositoryPermissionsSync",
|
||||
query: `
|
||||
mutation {
|
||||
scheduleRepositoryPermissionsSync(repository: "UmVwb3NpdG9yeTox") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "scheduleUserPermissionsSync",
|
||||
query: `
|
||||
mutation {
|
||||
scheduleUserPermissionsSync(user: "VXNlcjox") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "authorizedUserRepositories",
|
||||
query: `
|
||||
{
|
||||
authorizedUserRepositories(username: "alice", first: 1) {
|
||||
totalCount
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "usersWithPendingPermissions",
|
||||
query: `
|
||||
{
|
||||
usersWithPendingPermissions
|
||||
}`,
|
||||
}, {
|
||||
name: "authorizedUserRepositories",
|
||||
query: `
|
||||
{
|
||||
authorizedUserRepositories(username: "alice", first: 1) {
|
||||
totalCount
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "setUserEmailVerified",
|
||||
query: `
|
||||
mutation {
|
||||
setUserEmailVerified(
|
||||
user: "VXNlcjox"
|
||||
email: "alice@exmaple.com"
|
||||
verified: true
|
||||
) {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "setUserIsSiteAdmin",
|
||||
query: `
|
||||
mutation {
|
||||
setUserIsSiteAdmin(userID: "VXNlcjox", siteAdmin: true) {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "invalidateSessionsByID",
|
||||
query: `
|
||||
mutation {
|
||||
invalidateSessionsByID(userID: "VXNlcjox") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "triggerObservabilityTestAlert",
|
||||
query: `
|
||||
mutation {
|
||||
triggerObservabilityTestAlert(level: "critical") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "reloadSite",
|
||||
query: `
|
||||
mutation {
|
||||
reloadSite {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "organizations",
|
||||
query: `
|
||||
{
|
||||
organizations {
|
||||
nodes {
|
||||
id
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "surveyResponses",
|
||||
query: `
|
||||
{
|
||||
surveyResponses {
|
||||
nodes {
|
||||
id
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "repositoryStats",
|
||||
query: `
|
||||
{
|
||||
repositoryStats {
|
||||
gitDirBytes
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "createUser",
|
||||
query: `
|
||||
mutation {
|
||||
createUser(username: "alice") {
|
||||
resetPasswordURL
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "deleteUser",
|
||||
query: `
|
||||
mutation {
|
||||
deleteUser(user: "VXNlcjox") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "deleteOrganization",
|
||||
query: `
|
||||
mutation {
|
||||
deleteOrganization(organization: "T3JnYW5pemF0aW9uOjE=") {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "randomizeUserPassword",
|
||||
query: `
|
||||
mutation {
|
||||
randomizeUserPassword(user: "VXNlcjox") {
|
||||
resetPasswordURL
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
name: "setTag",
|
||||
query: `
|
||||
mutation {
|
||||
setTag(node: "VXNlcjox", tag: "tag", present: true) {
|
||||
alwaysNil
|
||||
}
|
||||
}`,
|
||||
},
|
||||
}
|
||||
|
||||
if *dotcom {
|
||||
tests = append(tests,
|
||||
gqlTest{
|
||||
name: "look up user by email",
|
||||
query: `
|
||||
{
|
||||
user(email: "alice@example.com") {
|
||||
id
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
)
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := userClient.GraphQL("", test.query, test.variables, nil)
|
||||
got := fmt.Sprintf("%v", err)
|
||||
if !strings.Contains(got, "must be site admin") {
|
||||
t.Fatalf(`Want "must be site admin"" error but got %q`, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ mutation CreateUser($username: String!, $email: String) {
|
||||
func (c *Client) DeleteUser(id string, hard bool) error {
|
||||
const query = `
|
||||
mutation DeleteUser($user: ID!, $hard: Boolean) {
|
||||
deleteUser(user: $user, hard: $hard) {
|
||||
deleteUser(user: $user, hard: $hard) {
|
||||
alwaysNil
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user