forked from mystiq/dex
db: add DB migration code and scripts.
This commit is contained in:
parent
abaf76a047
commit
c16e3b5a10
12 changed files with 568 additions and 2 deletions
15
build
15
build
|
@ -3,6 +3,21 @@
|
|||
export GOPATH=${PWD}/Godeps/_workspace
|
||||
export GOBIN=${PWD}/bin
|
||||
|
||||
if command -v go-bindata &>/dev/null; then
|
||||
DEX_MIGRATE_FROM_DISK=${DEX_MIGRATE_FROM_DISK:=false}
|
||||
|
||||
echo "Turning migrations into ./db/migrations/assets.go"
|
||||
if [ "$DEX_MIGRATE_FROM_DISK" = true ]; then
|
||||
echo "Compiling migrations.go: will read migrations from disk."
|
||||
else
|
||||
echo "Compiling migrations into migrations.go"
|
||||
fi
|
||||
go-bindata -debug=$DEX_MIGRATE_FROM_DISK -modtime=1 -pkg migrations -o ./db/migrations/assets.go ./db/migrations
|
||||
gofmt -w ./db/migrations/assets.go
|
||||
else
|
||||
echo "Could not find go-bindata in path, will not generate migrations"
|
||||
fi
|
||||
|
||||
rm -rf $GOPATH/src/github.com/coreos/dex
|
||||
mkdir -p $GOPATH/src/github.com/coreos/
|
||||
ln -s ${PWD} $GOPATH/src/github.com/coreos/dex
|
||||
|
|
|
@ -66,7 +66,7 @@ type clientIdentityModel struct {
|
|||
ID string `db:"id"`
|
||||
Secret []byte `db:"secret"`
|
||||
Metadata string `db:"metadata"`
|
||||
DexAdmin bool `db:"dexAdmin"`
|
||||
DexAdmin bool `db:"dex_admin"`
|
||||
}
|
||||
|
||||
func newClientMetadataJSON(cm *oidc.ClientMetadata) *clientMetadataJSON {
|
||||
|
|
52
db/migrate.go
Normal file
52
db/migrate.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/coopernurse/gorp"
|
||||
"github.com/lib/pq"
|
||||
migrate "github.com/rubenv/sql-migrate"
|
||||
|
||||
"github.com/coreos/dex/db/migrations"
|
||||
)
|
||||
|
||||
const (
|
||||
migrationDialect = "postgres"
|
||||
migrationTable = "dex_migrations"
|
||||
migrationDir = "db/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
migrate.SetTable(migrationTable)
|
||||
}
|
||||
|
||||
func MigrateToLatest(dbMap *gorp.DbMap) (int, error) {
|
||||
source := getSource()
|
||||
|
||||
return migrate.Exec(dbMap.Db, migrationDialect, source, migrate.Up)
|
||||
}
|
||||
|
||||
func MigrateMaxMigrations(dbMap *gorp.DbMap, max int) (int, error) {
|
||||
source := getSource()
|
||||
|
||||
return migrate.ExecMax(dbMap.Db, migrationDialect, source, migrate.Up, max)
|
||||
}
|
||||
|
||||
func GetPlannedMigrations(dbMap *gorp.DbMap) ([]*migrate.PlannedMigration, error) {
|
||||
migrations, _, err := migrate.PlanMigration(dbMap.Db, migrationDialect, getSource(), migrate.Up, 0)
|
||||
return migrations, err
|
||||
}
|
||||
|
||||
func DropMigrationsTable(dbMap *gorp.DbMap) error {
|
||||
qt := pq.QuoteIdentifier(migrationTable)
|
||||
_, err := dbMap.Exec(fmt.Sprintf("drop table if exists %s ;", qt))
|
||||
return err
|
||||
}
|
||||
|
||||
func getSource() migrate.MigrationSource {
|
||||
return &migrate.AssetMigrationSource{
|
||||
Dir: migrationDir,
|
||||
Asset: migrations.Asset,
|
||||
AssetDir: migrations.AssetDir,
|
||||
}
|
||||
}
|
42
db/migrate_test.go
Normal file
42
db/migrate_test.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/coopernurse/gorp"
|
||||
)
|
||||
|
||||
func initDB(dsn string) *gorp.DbMap {
|
||||
c, err := NewConnection(Config{DSN: dsn})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error making db connection: %q", err))
|
||||
}
|
||||
if err = c.DropTablesIfExists(); err != nil {
|
||||
panic(fmt.Sprintf("Unable to drop database tables: %v", err))
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// TestGetPlannedMigrations is a sanity check, ensuring that at least one
|
||||
// migration can be found.
|
||||
func TestGetPlannedMigrations(t *testing.T) {
|
||||
dsn := os.Getenv("DEX_TEST_DSN")
|
||||
if dsn == "" {
|
||||
t.Logf("Test will not run without DEX_TEST_DSN environment variable.")
|
||||
return
|
||||
}
|
||||
dbMap := initDB(dsn)
|
||||
ms, err := GetPlannedMigrations(dbMap)
|
||||
if err != nil {
|
||||
pwd, err := os.Getwd()
|
||||
t.Logf("pwd: %v", pwd)
|
||||
t.Fatalf("unexpected err: %q", err)
|
||||
}
|
||||
|
||||
if len(ms) == 0 {
|
||||
t.Fatalf("expected non-empty migrations")
|
||||
}
|
||||
}
|
47
db/migrations/0001_initial_migration.sql
Normal file
47
db/migrations/0001_initial_migration.sql
Normal file
|
@ -0,0 +1,47 @@
|
|||
-- +migrate Up
|
||||
CREATE TABLE IF NOT EXISTS "authd_user" (
|
||||
"id" text not null primary key,
|
||||
"email" text,
|
||||
"email_verified" boolean,
|
||||
"display_name" text,
|
||||
"admin" boolean) ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "client_identity" (
|
||||
"id" text not null primary key,
|
||||
"secret" bytea,
|
||||
"metadata" text);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "connector_config" (
|
||||
"id" text not null primary key,
|
||||
"type" text, "config" text) ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "key" (
|
||||
"value" bytea not null primary key) ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "password_info" (
|
||||
"user_id" text not null primary key,
|
||||
"password" text,
|
||||
"password_expires" bigint) ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "session" (
|
||||
"id" text not null primary key,
|
||||
"state" text,
|
||||
"created_at" bigint,
|
||||
"expires_at" bigint,
|
||||
"client_id" text,
|
||||
"client_state" text,
|
||||
"redirect_url" text, "identity" text,
|
||||
"connector_id" text,
|
||||
"user_id" text, "register" boolean) ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "session_key" (
|
||||
"key" text not null primary key,
|
||||
"session_id" text,
|
||||
"expires_at" bigint,
|
||||
"stale" boolean) ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "remote_identity_mapping" (
|
||||
"connector_id" text not null,
|
||||
"user_id" text,
|
||||
"remote_id" text not null,
|
||||
primary key ("connector_id", "remote_id")) ;
|
2
db/migrations/0002_dex_admin.sql
Normal file
2
db/migrations/0002_dex_admin.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
-- +migrate Up
|
||||
ALTER TABLE client_identity ADD COLUMN "dex_admin" boolean;
|
2
db/migrations/0003_user_created_at.sql
Normal file
2
db/migrations/0003_user_created_at.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
-- +migrate Up
|
||||
ALTER TABLE authd_user ADD COLUMN "created_at" bigint;
|
2
db/migrations/0004_session_nonce.sql
Normal file
2
db/migrations/0004_session_nonce.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
-- +migrate Up
|
||||
ALTER TABLE session ADD COLUMN "nonce" text;
|
21
db/migrations/0005_refresh_token_create.sql
Normal file
21
db/migrations/0005_refresh_token_create.sql
Normal file
|
@ -0,0 +1,21 @@
|
|||
-- +migrate Up
|
||||
CREATE TABLE refresh_token (
|
||||
id bigint NOT NULL,
|
||||
payload_hash text,
|
||||
user_id text,
|
||||
client_id text
|
||||
);
|
||||
|
||||
CREATE SEQUENCE refresh_token_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE refresh_token_id_seq OWNED BY refresh_token.id;
|
||||
|
||||
ALTER TABLE ONLY refresh_token ALTER COLUMN id SET DEFAULT nextval('refresh_token_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY refresh_token
|
||||
ADD CONSTRAINT refresh_token_pkey PRIMARY KEY (id);
|
3
db/migrations/0006_user_email_unique.sql
Normal file
3
db/migrations/0006_user_email_unique.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
-- +migrate Up
|
||||
ALTER TABLE ONLY authd_user
|
||||
ADD CONSTRAINT authd_user_email_key UNIQUE (email);
|
377
db/migrations/assets.go
Normal file
377
db/migrations/assets.go
Normal file
File diff suppressed because one or more lines are too long
|
@ -14,7 +14,10 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
userTableName = "dex_user"
|
||||
// This table is named authd_user for historical reasons; namely, that the
|
||||
// original name of the project was authd, and there are existing tables out
|
||||
// there that we don't want to have to rename in production.
|
||||
userTableName = "authd_user"
|
||||
remoteIdentityMappingTableName = "remote_identity_mapping"
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue