diff --git a/java/yb-pgsql/src/test/java/org/yb/pgsql/TestYbRoleProfile.java b/java/yb-pgsql/src/test/java/org/yb/pgsql/TestYbRoleProfile.java index 83318bee0144..e28180335dee 100644 --- a/java/yb-pgsql/src/test/java/org/yb/pgsql/TestYbRoleProfile.java +++ b/java/yb-pgsql/src/test/java/org/yb/pgsql/TestYbRoleProfile.java @@ -28,6 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yb.YBTestRunner; +import org.yb.minicluster.YsqlSnapshotVersion; import com.yugabyte.util.PSQLException; @RunWith(value=YBTestRunner.class) @@ -135,10 +136,15 @@ private void attachUserProfile(String username, String profilename) throws Excep @After public void cleanup() throws Exception { try (Statement stmt = connection.createStatement()) { - stmt.execute(String.format("ALTER USER %s PROFILE DETACH", USERNAME)); - stmt.execute(String.format("DROP PROFILE %s", PROFILE_1_NAME)); - stmt.execute(String.format("DROP PROFILE %s", PROFILE_2_NAME)); - stmt.execute(String.format("DROP USER %s", USERNAME)); + /* Cleanup fails if the tables don't exist. */ + boolean profile_exists = stmt.executeQuery("SELECT 1 FROM pg_class WHERE relname = 'pg_yb_profile'").next(); + + if (profile_exists) { + stmt.execute(String.format("ALTER USER %s PROFILE DETACH", USERNAME)); + stmt.execute(String.format("DROP PROFILE IF EXISTS %s", PROFILE_1_NAME)); + stmt.execute(String.format("DROP PROFILE IF EXISTS %s", PROFILE_2_NAME)); + stmt.execute(String.format("DROP USER IF EXISTS %s", USERNAME)); + } } } @@ -155,6 +161,31 @@ public void setup() throws Exception { } } + @Test + public void testProfilesOnOldDbVersion() throws Exception { + /* + * There are two operations that might result in an error if the profile catalogs don't exist: + * 1. logging in, because auth.c tries to get the user's profile if it exists + * 2. running profile commands. + * We can simply test this by logging in (which should behave as normal) and running a command. + */ + recreateWithYsqlVersion(YsqlSnapshotVersion.EARLIEST); + + try (Connection conn = getConnectionBuilder() + .withDatabase("template1") + .withTServer(0) + .withUser(DEFAULT_PG_USER) + .withPassword(DEFAULT_PG_PASS) + .connect(); + Statement stmt = conn.createStatement()) { + /* Validate that the connection is good. This is also useful for the cleanup */ + // stmt.execute(String.format("CREATE USER %s PASSWORD '%s'", USERNAME, PASSWORD)); + + runInvalidQuery(stmt, "CREATE PROFILE p LIMIT FAILED_LOGIN_ATTEMPTS 3", + "Login profile system catalogs do not exist"); + } + } + @Test public void testAdminCanChangeUserProfile() throws Exception { assertEquals(PROFILE_1_NAME, getProfileName(USERNAME)); diff --git a/java/yb-pgsql/src/test/java/org/yb/pgsql/TestYsqlUpgrade.java b/java/yb-pgsql/src/test/java/org/yb/pgsql/TestYsqlUpgrade.java index 940d9323a517..5050219aa8f6 100644 --- a/java/yb-pgsql/src/test/java/org/yb/pgsql/TestYsqlUpgrade.java +++ b/java/yb-pgsql/src/test/java/org/yb/pgsql/TestYsqlUpgrade.java @@ -117,6 +117,13 @@ public class TestYsqlUpgrade extends BasePgSQLTest { /** Since shared relations aren't cleared between tests, we can't reuse names. */ private String sharedRelName; + @Override + protected Map getTServerFlags() { + Map flagMap = super.getTServerFlags(); + flagMap.put("ysql_enable_profile", "true"); + return flagMap; + } + @Rule public TestName name = new TestName(); diff --git a/src/postgres/src/include/catalog/indexing.h b/src/postgres/src/include/catalog/indexing.h index 62a0017f891e..8afe3431a547 100644 --- a/src/postgres/src/include/catalog/indexing.h +++ b/src/postgres/src/include/catalog/indexing.h @@ -371,7 +371,7 @@ DECLARE_UNIQUE_INDEX(pg_yb_catalog_version_db_oid_index, 8012, on pg_yb_catalog_ DECLARE_UNIQUE_INDEX(pg_yb_profile_oid_index, 8052, on pg_yb_profile using btree(oid oid_ops)); #define YbProfileOidIndexId 8052 -DECLARE_UNIQUE_INDEX(pg_yb_role_profile_oid_index, 8055, on pg_yb_role_profile using btree(rolid oid_ops)); +DECLARE_UNIQUE_INDEX(pg_yb_role_profile_oid_index, 8055, on pg_yb_role_profile using btree(oid oid_ops)); #define YbRoleProfileOidIndexId 8055 #endif /* INDEXING_H */ diff --git a/src/postgres/src/include/catalog/pg_yb_role_profile.h b/src/postgres/src/include/catalog/pg_yb_role_profile.h index 2eaa6fff009c..0ebe783ed3b5 100644 --- a/src/postgres/src/include/catalog/pg_yb_role_profile.h +++ b/src/postgres/src/include/catalog/pg_yb_role_profile.h @@ -27,11 +27,11 @@ */ CATALOG(pg_yb_role_profile,8054,YbRoleProfileRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(8056,YbRoleProfileRelation_Rowtype_Id) BKI_SCHEMA_MACRO { - bool rolisenabled; /* Is the Role enabled? */ Oid rolid; /* OID of the role */ Oid prfid; /* OID of the profile */ + bool rolisenabled; /* Is the Role enabled? */ int32 rolfailedloginattempts; /* Number of failed attempts */ - int64 rollockedat; /* Timestamp at which role was locked */ + int32 rollockedat; /* Timestamp at which role was locked */ } FormData_pg_yb_role_profile; /* ---------------- diff --git a/src/yb/yql/pgwrapper/ysql_migrations/V30__14939__yb_profiles.sql b/src/yb/yql/pgwrapper/ysql_migrations/V30__14939__yb_profiles.sql index 791eeb0041a0..ca25652ebaa0 100644 --- a/src/yb/yql/pgwrapper/ysql_migrations/V30__14939__yb_profiles.sql +++ b/src/yb/yql/pgwrapper/ysql_migrations/V30__14939__yb_profiles.sql @@ -1,7 +1,7 @@ BEGIN; CREATE TABLE IF NOT EXISTS pg_catalog.pg_yb_profile ( prfname NAME NOT NULL, - prffailedloginattempts SMALLINT NOT NULL, + prffailedloginattempts INTEGER NOT NULL, prfpasswordlocktime INTEGER NOT NULL, CONSTRAINT pg_yb_profile_oid_index PRIMARY KEY(oid ASC) WITH (table_oid = 8052) @@ -10,15 +10,13 @@ BEGIN; table_oid = 8051, row_type_oid = 8053 ) TABLESPACE pg_global; -COMMIT; -BEGIN; CREATE TABLE IF NOT EXISTS pg_catalog.pg_yb_role_profile ( rolid OID NOT NULL, prfid OID NOT NULL, rolisenabled BOOL NOT NULL, - rolfailedloginattempts SMALLINT NOT NULL, - rollockts TIMESTAMPTZ NOT NULL, + rolfailedloginattempts INTEGER NOT NULL, + rollockedat INTEGER NOT NULL, CONSTRAINT pg_yb_role_profile_oid_index PRIMARY KEY(oid ASC) WITH (table_oid = 8055) ) WITH ( @@ -27,3 +25,11 @@ BEGIN; row_type_oid = 8056 ) TABLESPACE pg_global; COMMIT; + +BEGIN; + SET LOCAL yb_non_ddl_txn_for_sys_tables_allowed TO true; + + INSERT INTO pg_yb_profile (oid, prfname, prffailedloginattempts, prfpasswordlocktime) + VALUES (8057, 'default', 0, 0) + ON CONFLICT DO NOTHING; +COMMIT;