ronantakizawa/codereview-bench huggingface dataset:
Repository: goauthentik/authentik
File: authentik/providers/scim/api/providers.py (Python)

Code before:
            "name",
            "property_mappings",
            "property_mappings_group",
            "component",
            "assigned_backchannel_application_slug",
            "assigned_backchannel_application_name",
            "verbose_name",
            "verbose_name_plural",
            "meta_model_name",
            "url",
            "verify_certificates",
            "token",
            "compatibility_mode",
            "exclude_users_service_account",
            "group_filters",
            "dry_run",
        ]
        extra_kwargs = {}


class SCIMProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixin, ModelViewSet):
    """SCIMProvider Viewset"""

    queryset = SCIMProvider.objects.all()
    serializer_class = SCIMProviderSerializer
    filterset_fields = ["name", "exclude_users_service_account", "url"]
    search_fields = ["name", "url"]
    ordering = ["name", "url"]
    sync_single_task = scim_sync
    sync_objects_task = scim_sync_objects


Review comment (suggestion):
```suggestion
    filterset_fields = ["name", "exclude_users_service_account", "url", "group_filters"]
```
The attribute should remain in the filterset

Code after:
    class Meta:
        model = SCIMProvider
        fields = [
            "pk",
            "name",
            "property_mappings",
            "property_mappings_group",
            "component",
            "assigned_backchannel_application_slug",
            "assigned_backchannel_application_name",
            "verbose_name",
            "verbose_name_plural",
            "meta_model_name",
            "url",
            "verify_certificates",
            "token",
            "auth_mode",
            "auth_oauth",
            "auth_oauth_params",
            "compatibility_mode",
            "service_provider_config_cache_timeout",
            "exclude_users_service_account",
            "sync_page_size",
            "sync_page_timeout",
            "group_filters",
            "dry_run",
        ]
        extra_kwargs = {}


class SCIMProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixin, ModelViewSet):
    """SCIMProvider Viewset"""

    queryset = SCIMProvider.objects.all()
    serializer_class = SCIMProviderSerializer
    filterset_fields = ["name", "exclude_users_service_account", "url", "group_filters"]
    search_fields = ["name", "url"]
    ordering = ["name", "url"]
    sync_task = scim_sync
    sync_objects_task = scim_sync_objects
Repository: goauthentik/authentik
File: internal/outpost/proxyv2/application/session_postgres_test.go (Go)

Code before:
package application

import (
	"context"
	"encoding/json"
	"testing"
	"time"

	"github.com/google/uuid"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"

	"goauthentik.io/internal/config"
	"goauthentik.io/internal/outpost/proxyv2/constants"
	"goauthentik.io/internal/outpost/proxyv2/postgresstore"
	"goauthentik.io/internal/outpost/proxyv2/types"
)

func SetupTestDB(t *testing.T) (*gorm.DB, *postgresstore.RefreshableConnPool) {
	cfg := config.Get().PostgreSQL

	gormConfig := &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent),
		NowFunc: func() time.Time {
			return time.Now().UTC()
		},
	}

	// Use standardized setup
	db, pool, err := postgresstore.SetupGORMWithRefreshablePool(cfg, gormConfig, 10, 100, time.Hour)
	require.NoError(t, err)

	return db, pool
}

Review comment (suggestion):
```suggestion
	"github.com/stretchr/testify/require"
	_ "gorm.io/driver/postgres"
```

Code after:
package application

import (
	"context"
	"encoding/json"
	"testing"
	"time"

	"github.com/google/uuid"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	_ "gorm.io/driver/postgres"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"

	"goauthentik.io/internal/config"
	"goauthentik.io/internal/outpost/proxyv2/constants"
	"goauthentik.io/internal/outpost/proxyv2/postgresstore"
	"goauthentik.io/internal/outpost/proxyv2/types"
)

func SetupTestDB(t *testing.T) (*gorm.DB, *postgresstore.RefreshableConnPool) {
	cfg := config.Get().PostgreSQL

	gormConfig := &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent),
		NowFunc: func() time.Time {
			return time.Now().UTC()
		},
	}

	// Use standardized setup
	db, pool, err := postgresstore.SetupGORMWithRefreshablePool(cfg, gormConfig, 10, 100, time.Hour)
	require.NoError(t, err)

	return db, pool
Repository: goauthentik/authentik
File: internal/outpost/proxyv2/refresh.go (Go)

Code before:
	}
	apps := make(map[string]*application.Application)
	for _, provider := range providers {
		rsp := sentry.StartSpan(context.Background(), "authentik.outposts.proxy.application_ss")
		ua := fmt.Sprintf(" (provider=%s)", provider.Name)
		hc := &http.Client{
			Transport: web.NewUserAgentTransport(
				constants.UserAgentOutpost()+ua,
				web.NewTracingTransport(
					rsp.Context(),
					ak.GetTLSTransport(),
				),
			),
		}
		externalHost, err := url.Parse(provider.ExternalHost)
		if err != nil {
			ps.log.WithError(err).Warning("failed to parse URL, skipping provider")
			continue
		}
		existing, ok := ps.apps[externalHost.Host]
		a, err := application.NewApplication(provider, hc, ps, existing)
		if ok {
			existing.Stop()
		}
		if err != nil {
			ps.log.WithError(err).Fatal("failed to setup application")
			continue
		}
		apps[externalHost.Host] = a
	}
	ps.apps = apps
	ps.log.Debug("Swapped maps")
	return nil
}

func (ps *ProxyServer) API() *ak.APIController {
	return ps.akAPI
}

func (ps *ProxyServer) CryptoStore() *ak.CryptoStore {
	return ps.cryptoStore
}

func (ps *ProxyServer) Apps() []*application.Application {
	return maps.Values(ps.apps)
}


Review comment (bug):
```suggestion
			ps.log.WithError(err).Warning("failed to setup application")
```

I dont think we'd want the outpost to crash in this case, since other applications might be running fine

Code after:
	}
	apps := make(map[string]*application.Application)
	for _, provider := range providers {
		rsp := sentry.StartSpan(context.Background(), "authentik.outposts.proxy.application_ss")
		ua := fmt.Sprintf(" (provider=%s)", provider.Name)
		hc := &http.Client{
			Transport: web.NewUserAgentTransport(
				constants.UserAgentOutpost()+ua,
				web.NewTracingTransport(
					rsp.Context(),
					ak.GetTLSTransport(),
				),
			),
		}
		externalHost, err := url.Parse(provider.ExternalHost)
		if err != nil {
			ps.log.WithError(err).Warning("failed to parse URL, skipping provider")
			continue
		}
		existing, ok := ps.apps[externalHost.Host]
		a, err := application.NewApplication(provider, hc, ps, existing)
		if ok {
			existing.Stop()
		}
		if err != nil {
			ps.log.WithError(err).Warning("failed to setup application")
			continue
		}
		apps[externalHost.Host] = a
	}
	ps.apps = apps
	ps.log.Debug("Swapped maps")
	return nil
}

func (ps *ProxyServer) API() *ak.APIController {
	return ps.akAPI
}

func (ps *ProxyServer) CryptoStore() *ak.CryptoStore {
	return ps.cryptoStore
}

func (ps *ProxyServer) Apps() []*application.Application {
	return maps.Values(ps.apps)
}
Repository: goauthentik/authentik
File: authentik/core/api/authenticated_sessions.py (Python)

Code before:
    family: str
    major: str
    minor: str
    patch: str
    patch_minor: str


class UserAgentBrowserDict(TypedDict):
    """User agent browser"""

    family: str
    major: str
    minor: str
    patch: str


class UserAgentDict(TypedDict):
    """User agent details"""

    device: UserAgentDeviceDict
    os: UserAgentOSDict
    user_agent: UserAgentBrowserDict
    string: str


class BulkDeleteSessionSerializer(serializers.Serializer):
    """Serializer for bulk deleting authenticated sessions by user"""

    user_ids = ListField(child=serializers.IntegerField(), help_text="List of user IDs to revoke all sessions for")


class AuthenticatedSessionSerializer(ModelSerializer):
    """AuthenticatedSession Serializer"""

    expires = DateTimeField(source="session.expires", read_only=True)
    last_ip = IPAddressField(source="session.last_ip", read_only=True)
    last_user_agent = CharField(source="session.last_user_agent", read_only=True)
    last_used = DateTimeField(source="session.last_used", read_only=True)

    current = SerializerMethodField()
    user_agent = SerializerMethodField()
    geo_ip = SerializerMethodField()
    asn = SerializerMethodField()

    def get_current(self, instance: AuthenticatedSession) -> bool:
        """Check if session is currently active session"""
        request: Request = self.context["request"]
        return request._request.session.session_key == instance.session.session_key

    def get_user_agent(self, instance: AuthenticatedSession) -> UserAgentDict:
        """Get parsed user agent"""

Review comment (suggestion):
```suggestion
class BulkDeleteSessionSerializer(PassiveSerializer):
```

Code after:
class UserAgentDeviceDict(TypedDict):
    """User agent device"""

    brand: str
    family: str
    model: str


class UserAgentOSDict(TypedDict):
    """User agent os"""

    family: str
    major: str
    minor: str
    patch: str
    patch_minor: str


class UserAgentBrowserDict(TypedDict):
    """User agent browser"""

    family: str
    major: str
    minor: str
    patch: str


class UserAgentDict(TypedDict):
    """User agent details"""

    device: UserAgentDeviceDict
    os: UserAgentOSDict
    user_agent: UserAgentBrowserDict
    string: str


class BulkDeleteSessionSerializer(PassiveSerializer):
    """Serializer for bulk deleting authenticated sessions by user"""

    user_pks = ListField(
        child=serializers.IntegerField(), help_text="List of user IDs to revoke all sessions for"
    )


class AuthenticatedSessionSerializer(ModelSerializer):
    """AuthenticatedSession Serializer"""

    expires = DateTimeField(source="session.expires", read_only=True)
    last_ip = IPAddressField(source="session.last_ip", read_only=True)
    last_user_agent = CharField(source="session.last_user_agent", read_only=True)
    last_used = DateTimeField(source="session.last_used", read_only=True)
Repository: goauthentik/authentik
File: web/src/components/ak-switch-input.ts (TypeScript)

Code before:
    // visual clutter and legibility issues of ak-form-elemental-horizontal and patternfly in
    // general.
    protected createRenderRoot() {
        return this;
    }

    @property({ type: String })
    name!: string;

    @property({ type: String })
    label = "";

    @property({ type: Boolean })
    checked: boolean = false;

    @property({ type: Boolean })
    required = false;

    @property({ type: String })
    help = "";

    /**
     * For more complex help instructions, provide a template result.
     */
    @property({ type: Object })
    bighelp!: TemplateResult | TemplateResult[];

    @query("input.pf-c-switch__input[type=checkbox]")
    checkbox!: HTMLInputElement;

    #fieldID: string = IDGenerator.randomID();

    renderHelp() {
        const helpText = this.help.trim();

        return [
            helpText
                ? html`<p id="${this.#fieldID}-help" class="pf-c-form__helper-text">${helpText}</p>`
                : nothing,
            this.bighelp ? this.bighelp : nothing,
        ];
    }

    render() {
        const doCheck = this.checked ? this.checked : undefined;

        return html` <ak-form-element-horizontal name=${this.name} ?required=${this.required}>
            <div slot="label" class="pf-c-form__group-label"></div>

            <label class="pf-c-switch" for="${this.#fieldID}">
                <input

Review comment (suggestion):
```suggestion
   public bighelp!: TemplateResult | TemplateResult[];
```

Code after:
    // visual clutter and legibility issues of ak-form-elemental-horizontal and patternfly in
    // general.
    protected createRenderRoot() {
        return this;
    }

    @property({ type: String })
    name!: string;

    @property({ type: String })
    label = "";

    @property({ type: Boolean })
    checked: boolean = false;

    @property({ type: Boolean })
    required = false;

    @property({ type: String })
    help = "";

    /**
     * For more complex help instructions, provide a template result.
     */
    @property({ type: Object })
    public bighelp!: TemplateResult | TemplateResult[];

    @query("input.pf-c-switch__input[type=checkbox]")
    checkbox!: HTMLInputElement;

    #fieldID: string = IDGenerator.randomID();

    protected renderHelp() {
        const helpText = this.help.trim();

        return [
            helpText
                ? html`<p id="${this.#fieldID}-help" class="pf-c-form__helper-text">${helpText}</p>`
                : nothing,
            this.bighelp ? this.bighelp : nothing,
        ];
    }

    render() {
        const doCheck = this.checked ? this.checked : undefined;

        return html` <ak-form-element-horizontal name=${this.name} ?required=${this.required}>
            <div slot="label" class="pf-c-form__group-label"></div>

            <label class="pf-c-switch" for="${this.#fieldID}">
                <input
Repository: goauthentik/authentik
File: website/docusaurus-theme/releases/node.mjs (JavaScript)

Code before:
/**
 * @file Docusaurus release utils.
 *
 * @import { SidebarItemConfig } from "@docusaurus/plugin-content-docs/src/sidebars/types.js"
 * @import { AKReleaseFile, AKReleasesPluginEnvironment } from "./common.mjs"
 */

import { readFileSync } from "node:fs";
import { extname, join } from "node:path";

import { parseFileContentFrontMatter } from "@docusaurus/utils/lib/markdownUtils.js";
import FastGlob from "fast-glob";
import { coerce } from "semver";

/**
 * Collect all Markdown files from the releases directory.
 *
 * @param {string} releasesParentDirectory
 * @returns {AKReleaseFile[]}
 */
export function collectReleaseFiles(releasesParentDirectory) {
    /**
     * @type {Array<FastGlob.Entry & AKReleaseFile>}
     */
    const releaseFiles = FastGlob.sync("releases/**/v*.{md,mdx}", {
        cwd: releasesParentDirectory,
        onlyFiles: true,
        objectMode: true,
    })
        .map((fileEntry) => {
            return {
                ...fileEntry,
                path: fileEntry.path.replace(/\.mdx?$/, ""),
                name: fileEntry.name.replace(/^v/, "").replace(/\.mdx?$/, ""),
            };
        })
        .sort((a, b) => {
            const aSemVer = coerce(a.name);
            const bSemVer = coerce(b.name);

            if (aSemVer && bSemVer) {
                return bSemVer.compare(aSemVer);
            }

            return b.name.localeCompare(a.name);
        });

    const [latestRelease] = releaseFiles;

    if (latestRelease) {

Review comment (suggestion):
```suggestion
 * Reads and parses the front matter of recent release files (first N releases).
 * Returns the release unchanged for older releases.
```

Code after:
/**
 * @file Docusaurus release utils.
 *
 * @import { SidebarItemConfig } from "@docusaurus/plugin-content-docs/src/sidebars/types.js"
 * @import { AKReleaseFile, AKReleasesPluginEnvironment } from "./common.mjs"
 */

import { readFileSync } from "node:fs";
import { extname, join } from "node:path";

import { parseFileContentFrontMatter } from "@docusaurus/utils/lib/markdownUtils.js";
import FastGlob from "fast-glob";
import { coerce } from "semver";

/**
 * Number of supported releases to show in the sidebar.
 */
export const SUPPORTED_RELEASE_COUNT = 3;

/**
 * @typedef {FastGlob.Entry & AKReleaseFile} AKReleaseFileEntry
 */

/**
 * Reads and parses the front matter of recent release files.
 *
 * @param {string} releasesParentDirectory
 * @param {AKReleaseFileEntry} release
 * @param {number} index
 */
function parseRelease(releasesParentDirectory, release, index) {
    if (index > SUPPORTED_RELEASE_COUNT - 1) {
        return release;
    }

    const extension = extname(release.dirent.name);

    const fileContent = readFileSync(
        join(releasesParentDirectory, `${release.path}${extension}`),
        "utf-8",
    );

    const { frontMatter } = parseFileContentFrontMatter(fileContent);

    if (frontMatter.beta) {
        release.name += " (Release Candidate)";
    }

    return {
        ...release,
Repository: goauthentik/authentik
File: authentik/providers/oauth2/utils.py (Python)

Code before:

    As per https://openid.net/specs/openid-connect-backchannel-1_0.html
    """

    LOGGER.debug("Creating logout token", provider=provider, sub=sub)

    _now = now()
    # Create the logout token payload
    payload = {
        "iss": str(iss),
        "aud": provider.client_id,
        "iat": int(_now.timestamp()),
        "exp": int((_now + timedelta_from_string(provider.access_token_validity)).timestamp()),
        "jti": str(uuid.uuid4()),
        "events": {
            "http://schemas.openid.net/event/backchannel-logout": {},
        },
    }

    # Add either sub or sid (or both)
    if sub:
        payload["sub"] = sub
    if session_key:
        payload["sid"] = hash_session_key(session_key)
    # Encode the token
    return provider.encode(payload, "logout+jwt")


Review comment (suggestion):
```suggestion
    return provider.encode(payload, jwt_type="logout+jwt")
```

Code after:

    As per https://openid.net/specs/openid-connect-backchannel-1_0.html
    """

    LOGGER.debug("Creating logout token", provider=provider, sub=sub)

    _now = now()
    # Create the logout token payload
    payload = {
        "iss": str(iss),
        "aud": provider.client_id,
        "iat": int(_now.timestamp()),
        "exp": int((_now + timedelta_from_string(provider.access_token_validity)).timestamp()),
        "jti": str(uuid.uuid4()),
        "events": {
            "http://schemas.openid.net/event/backchannel-logout": {},
        },
    }

    # Add either sub or sid (or both)
    if sub:
        payload["sub"] = sub
    if session_key:
        payload["sid"] = hash_session_key(session_key)
    # Encode the token
    return provider.encode(payload, jwt_type="logout+jwt")
Repository: goauthentik/authentik
File: authentik/api/tests/test_schema.py (Python)

Code before:
from yaml import safe_load

from authentik.lib.config import CONFIG


class TestSchemaGeneration(APITestCase):
    """Generic admin tests"""

    def test_schema(self):
        """Test generation"""
        response = self.client.get(
            reverse("authentik_api:schema"),
        )
        self.assertTrue(safe_load(response.content.decode()))

    def test_browser(self):
        """Test API Browser"""
        response = self.client.get(
            reverse("authentik_api:schema-browser"),
        )
        self.assertEqual(response.status_code, 200)

    def test_build_schema(self):
        """Test schema build command"""
        blueprint_file_name = f"/tmp/{str(uuid4())}.json"
        api_file_name = f"/tmp/{str(uuid4())}.yml"
        with (
            CONFIG.patch("debug", True),
            CONFIG.patch("tenants.enabled", True),
            CONFIG.patch("outposts.disable_embedded_outpost", True),
        ):
            call_command("build_schema", blueprint_file=blueprint_file_name, api_file=api_file_name)
        self.assertTrue(Path(blueprint_file_name).exists())
        self.assertTrue(Path(api_file_name).exists())


Review comment (suggestion):
```suggestion
        tmp = Path(gettempdir())
        blueprint_file_name = tmp / f"str(uuid4()).json"
        api_file_name = tmp / f"str(uuid4()).yml"
```
with the proper imports as well
```
from pathlib import Path
from tempfile import gettempdir
```

Code after:
from rest_framework.test import APITestCase
from yaml import safe_load

from authentik.lib.config import CONFIG


class TestSchemaGeneration(APITestCase):
    """Generic admin tests"""

    def test_schema(self):
        """Test generation"""
        response = self.client.get(
            reverse("authentik_api:schema"),
        )
        self.assertTrue(safe_load(response.content.decode()))

    def test_browser(self):
        """Test API Browser"""
        response = self.client.get(
            reverse("authentik_api:schema-browser"),
        )
        self.assertEqual(response.status_code, 200)

    def test_build_schema(self):
        """Test schema build command"""
        tmp = Path(gettempdir())
        blueprint_file = tmp / f"{str(uuid4())}.json"
        api_file = tmp / f"{str(uuid4())}.yml"
        with (
            CONFIG.patch("debug", True),
            CONFIG.patch("tenants.enabled", True),
            CONFIG.patch("outposts.disable_embedded_outpost", True),
        ):
            call_command("build_schema", blueprint_file=blueprint_file, api_file=api_file)
        self.assertTrue(blueprint_file.exists())
        self.assertTrue(api_file.exists())
Repository: goauthentik/authentik
File: scripts/test_docker.sh (Shell)

Code before:
#!/usr/bin/env bash
set -e -x -o pipefail
hash="$(git rev-parse HEAD || openssl rand -base64 36 | sha256sum)"

AUTHENTIK_IMAGE="ghcr.io/goauthentik/server"
AUTHENTIK_TAG="$(echo "$hash" | cut -c1-15)"

if [ -f lifecycle/container/.env ]; then
    echo "Existing .env file, aborting"
    exit 1
fi

echo PG_PASS="$(openssl rand -base64 36 | tr -d '\n')" >lifecycle/container/.env
echo AUTHENTIK_SECRET_KEY="$(openssl rand -base64 60 | tr -d '\n')" >>lifecycle/container/.env
export COMPOSE_PROJECT_NAME="authentik-test-${AUTHENTIK_TAG}"

if [[ -v BUILD ]]; then
    echo AUTHENTIK_IMAGE="${AUTHENTIK_IMAGE}" >>lifecycle/container/.env
    echo AUTHENTIK_TAG="${AUTHENTIK_TAG}" >>lifecycle/container/.env

    # Ensure buildx is installed
    docker buildx install
    make gen-client-ts
    make gen-client-go
    touch lifecycle/container/.env

    docker build -t "${AUTHENTIK_IMAGE}:${AUTHENTIK_TAG}" -f lifecycle/container/Dockerfile .
fi

docker compose -f lifecycle/container/compose.yml up --no-start

Review comment (security):
```suggestion
AUTHENTIK_IMAGE="xghcr.io/goauthentik/server"
```

this shouldn't be changed. We are building the image here, and we *don't* want a valid name, to prevent accidental pushes.

Code after:
#!/usr/bin/env bash
set -e -x -o pipefail
hash="$(git rev-parse HEAD || openssl rand -base64 36 | sha256sum)"

AUTHENTIK_IMAGE="authentik.invalid/goauthentik/server"
AUTHENTIK_TAG="$(echo "$hash" | cut -c1-15)"

if [ -f lifecycle/container/.env ]; then
    echo "Existing .env file, aborting"
    exit 1
fi

echo PG_PASS="$(openssl rand -base64 36 | tr -d '\n')" >lifecycle/container/.env
echo AUTHENTIK_SECRET_KEY="$(openssl rand -base64 60 | tr -d '\n')" >>lifecycle/container/.env
export COMPOSE_PROJECT_NAME="authentik-test-${AUTHENTIK_TAG}"

if [[ -v BUILD ]]; then
    echo AUTHENTIK_IMAGE="${AUTHENTIK_IMAGE}" >>lifecycle/container/.env
    echo AUTHENTIK_TAG="${AUTHENTIK_TAG}" >>lifecycle/container/.env

    # Ensure buildx is installed
    docker buildx install
    make gen-client-ts
    make gen-client-go
    touch lifecycle/container/.env

    docker build -t "${AUTHENTIK_IMAGE}:${AUTHENTIK_TAG}" -f lifecycle/container/Dockerfile .
fi

docker compose -f lifecycle/container/compose.yml up --no-start