From c64aa69970e2807e37c4f5ab245e31da618133f9 Mon Sep 17 00:00:00 2001 From: Milan Pavlik Date: Mon, 12 Dec 2022 13:07:17 +0000 Subject: [PATCH] [oidc] Setup db --- .../gitpod-db/go/dbtest/oidc_client_config.go | 64 +++++++++++++++++ components/gitpod-db/go/oidc_client_config.go | 72 +++++++++++++++++++ .../gitpod-db/go/oidc_client_config_test.go | 22 ++++++ ...70850042413-CreateOIDCClientConfigTable.ts | 24 +++++++ 4 files changed, 182 insertions(+) create mode 100644 components/gitpod-db/go/dbtest/oidc_client_config.go create mode 100644 components/gitpod-db/go/oidc_client_config.go create mode 100644 components/gitpod-db/go/oidc_client_config_test.go create mode 100644 components/gitpod-db/src/typeorm/migration/1670850042413-CreateOIDCClientConfigTable.ts diff --git a/components/gitpod-db/go/dbtest/oidc_client_config.go b/components/gitpod-db/go/dbtest/oidc_client_config.go new file mode 100644 index 00000000000000..2f131f0a58365b --- /dev/null +++ b/components/gitpod-db/go/dbtest/oidc_client_config.go @@ -0,0 +1,64 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License.AGPL.txt in the project root for license information. + +package dbtest + +import ( + "context" + db "github.com/gitpod-io/gitpod/components/gitpod-db/go" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "gorm.io/gorm" + "testing" + "time" +) + +func NewOIDCClientConfig(t *testing.T, record db.OIDCClientConfig) db.OIDCClientConfig { + t.Helper() + + now := time.Now().UTC().Truncate(time.Millisecond) + result := db.OIDCClientConfig{ + ID: uuid.New(), + Issuer: "issuer", + Data: []byte("{}"), + LastModified: now, + } + + if record.ID != uuid.Nil { + result.ID = record.ID + } + + if record.Issuer != "" { + result.Issuer = record.Issuer + } + + if record.Data != nil { + result.Data = record.Data + } + + return result +} + +func CreateOIDCClientConfigs(t *testing.T, conn *gorm.DB, entries ...db.OIDCClientConfig) []db.OIDCClientConfig { + t.Helper() + + var records []db.OIDCClientConfig + var ids []string + for _, entry := range entries { + record := NewOIDCClientConfig(t, entry) + records = append(records, record) + ids = append(ids, record.ID.String()) + + _, err := db.CreateOIDCCLientConfig(context.Background(), conn, record) + require.NoError(t, err) + } + + t.Cleanup(func() { + if len(ids) > 0 { + require.NoError(t, conn.Where(ids).Delete(&db.OIDCClientConfig{}).Error) + } + }) + + return records +} diff --git a/components/gitpod-db/go/oidc_client_config.go b/components/gitpod-db/go/oidc_client_config.go new file mode 100644 index 00000000000000..7d1696fc7af0c6 --- /dev/null +++ b/components/gitpod-db/go/oidc_client_config.go @@ -0,0 +1,72 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License.AGPL.txt in the project root for license information. + +package db + +import ( + "context" + "errors" + "fmt" + "github.com/google/uuid" + "gorm.io/datatypes" + "gorm.io/gorm" + "time" +) + +type OIDCClientConfig struct { + ID uuid.UUID `gorm:"primary_key;column:id;type:char;size:36;" json:"id"` + + Issuer string `gorm:"column:issuer;type:char;size:255;" json:"issuer"` + + Data datatypes.JSON `gorm:"column:data;type:text;size:65535" json:"data"` + + LastModified time.Time `gorm:"column:_lastModified;type:timestamp;default:CURRENT_TIMESTAMP(6);" json:"_lastModified"` + // deleted is reserved for use by db-sync. + _ bool `gorm:"column:deleted;type:tinyint;default:0;" json:"deleted"` +} + +func (c *OIDCClientConfig) TableName() string { + return "d_b_oidc_client_config" +} + +func CreateOIDCCLientConfig(ctx context.Context, conn *gorm.DB, cfg OIDCClientConfig) (OIDCClientConfig, error) { + if cfg.ID == uuid.Nil { + return OIDCClientConfig{}, errors.New("OIDC Client Config ID must be set") + } + + if cfg.Issuer == "" { + return OIDCClientConfig{}, errors.New("OIDC Client Config issuer must be set") + } + + tx := conn. + WithContext(ctx). + Create(&cfg) + if tx.Error != nil { + return OIDCClientConfig{}, fmt.Errorf("failed to create oidc client config: %w", tx.Error) + } + + return cfg, nil +} + +func GetOIDCClientConfig(ctx context.Context, conn *gorm.DB, id uuid.UUID) (OIDCClientConfig, error) { + var config OIDCClientConfig + + if id == uuid.Nil { + return OIDCClientConfig{}, fmt.Errorf("OIDC Client Config ID is a required argument") + } + + tx := conn. + WithContext(ctx). + Where("id = ?", id). + Where("deleted = ?", 0). + First(&config) + if tx.Error != nil { + if errors.Is(tx.Error, gorm.ErrRecordNotFound) { + return OIDCClientConfig{}, fmt.Errorf("OIDC Client Config with ID %s does not exist: %w", id, ErrorNotFound) + } + return OIDCClientConfig{}, fmt.Errorf("Failed to retrieve OIDC client config: %v", tx.Error) + } + + return config, nil +} diff --git a/components/gitpod-db/go/oidc_client_config_test.go b/components/gitpod-db/go/oidc_client_config_test.go new file mode 100644 index 00000000000000..89c37e34934a0a --- /dev/null +++ b/components/gitpod-db/go/oidc_client_config_test.go @@ -0,0 +1,22 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License.AGPL.txt in the project root for license information. + +package db_test + +import ( + "context" + db "github.com/gitpod-io/gitpod/components/gitpod-db/go" + "github.com/gitpod-io/gitpod/components/gitpod-db/go/dbtest" + "github.com/stretchr/testify/require" + "testing" +) + +func TestCreateOIDCClientConfig_Create(t *testing.T) { + conn := dbtest.ConnectForTests(t) + created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{})[0] + + retrieved, err := db.GetOIDCClientConfig(context.Background(), conn, created.ID) + require.NoError(t, err) + require.Equal(t, created, retrieved) +} diff --git a/components/gitpod-db/src/typeorm/migration/1670850042413-CreateOIDCClientConfigTable.ts b/components/gitpod-db/src/typeorm/migration/1670850042413-CreateOIDCClientConfigTable.ts new file mode 100644 index 00000000000000..1ddb90a180c5dd --- /dev/null +++ b/components/gitpod-db/src/typeorm/migration/1670850042413-CreateOIDCClientConfigTable.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2022 Gitpod GmbH. All rights reserved. + * Licensed under the GNU Affero General Public License (AGPL). + * See License.AGPL.txt in the project root for license information. + */ + +import { MigrationInterface, QueryRunner } from "typeorm"; +import { tableExists } from "./helper/helper"; + +export class CreateOIDCClientConfigTable1670850042413 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + if (!(await tableExists(queryRunner, "d_b_oidc_client_config"))) { + await queryRunner.query( + "CREATE TABLE IF NOT EXISTS `d_b_oidc_client_config` (`id` varchar(255) NOT NULL, `issuer` varchar(255) NOT NULL, `data` text(65535) NOT NULL, `_lastModified` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), `deleted` tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (id))", + ); + } + } + + public async down(queryRunner: QueryRunner): Promise { + if (await tableExists(queryRunner, "d_b_oidc_client_config")) { + await queryRunner.query("DROP TABLE `d_b_oidc_client_config`"); + } + } +}