From 9ca4d2f257edbe084b9faac7cc3b75f11a8cb4f6 Mon Sep 17 00:00:00 2001 From: Bartosz Wieczorek Date: Thu, 8 Feb 2018 13:16:45 +0100 Subject: [PATCH] refactoring --- sql/schema.sql | 166 +++++++++++------------ src/eedb/auth/PgUserAuth.cpp | 12 +- src/eedb/data/AuthToken.hpp | 11 -- src/eedb/data/AuthTokenConst.hpp | 30 ++++ src/eedb/data/AuthTokens.hpp | 19 +++ src/eedb/data/Email.hpp | 9 +- src/eedb/data/Users.hpp | 8 +- src/eedb/db/data/PgAuthToken.hpp | 1 + src/eedb/db/data/PgUsers.cpp | 166 ++++++++++++++++------- src/eedb/db/data/PgUsers.hpp | 4 +- tests/unit/db/test_eedb_data_PgUsers.cpp | 8 ++ 11 files changed, 272 insertions(+), 162 deletions(-) create mode 100644 src/eedb/data/AuthTokenConst.hpp diff --git a/sql/schema.sql b/sql/schema.sql index 8c88aef..f3acdba 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -94,12 +94,12 @@ create table "auth_info" ( constraint "pk_auth_into_id" primary key("id"), constraint "ux_auth_info_email" unique ("email") ); -create trigger "update_auth_info_updated" before update on "auth_info" FOR EACH ROW EXECUTE PROCEDURE last_update_column(); +create trigger "update_auth_info_updated" before update on "auth_info" FOR EACH ROW EXECUTE PROCEDURE last_update_column(); comment on table "auth_info" is ''; comment on column "auth_info"."id" is ''; -comment on column "auth_info"."group" is ''; -comment on column "auth_info"."created" is ''; -comment on column "auth_info"."config" is ''; +comment on column "auth_info"."group" is 'default user group'; +comment on column "auth_info"."created" is 'time of created'; +comment on column "auth_info"."config" is 'user configuration'; create table "auth_identity" ( @@ -108,7 +108,7 @@ create table "auth_identity" ( "provider" varchar(64) not null, "identity" varchar(512) not null, constraint "pk_auth_identity_id" primary key("id"), - constraint "fk_auth_identity_auth_info" foreign key ("auth_info_id") references "auth_info" ("id") on delete cascade deferrable initially deferred + constraint "fk_auth_identity_auth_info_id" foreign key ("auth_info_id") references "auth_info" ("id") on delete cascade deferrable initially immediate ); comment on table "auth_identity" is ''; comment on column "auth_identity"."id" is ''; @@ -124,7 +124,7 @@ create table "auth_token" ( "expires" timestamp not null, "role" smallint not null, constraint "pk_auth_token_id" primary key("id"), - constraint "fk_auth_token_auth_info_id" foreign key ("auth_info_id") references "auth_info" ("id") on delete cascade deferrable initially deferred + constraint "fk_auth_token_auth_info_id" foreign key ("auth_info_id") references "auth_info" ("id") on delete cascade deferrable initially immediate ); create index "ix_auth_token_value" ON "auth_token" ("value"); comment on table "auth_token" is ''; @@ -153,8 +153,8 @@ create table "user_audit" ( "data" jsonb, "when_happened" timestamp DEFAULT(now()), constraint "pk_user_history_id" primary key ("id"), - constraint "fk_user_history_auth_info_id" foreign key ("auth_info_id") references "auth_info"("id") on delete cascade deferrable initially deferred, - constraint "fk_user_history_user_action" foreign key ("action_id") references "user_audit_action"("id") on delete cascade deferrable initially deferred + constraint "fk_user_history_auth_info_id" foreign key ("auth_info_id") references "auth_info"("id") on delete cascade deferrable initially immediate, + constraint "fk_user_history_user_action" foreign key ("action_id") references "user_audit_action"("id") on delete cascade deferrable initially immediate ); create index "ix_user_history_data" ON "user_audit" ((("data" ->> 'status')::text)) WHERE ("data" ->> 'status') IS not null; comment on table "user_audit" IS 'saves user actions like login/logout'; @@ -183,8 +183,8 @@ create table "stat"( "created" timestamp DEFAULT now() not null, "updated" timestamp, constraint "pk_stat" primary key ("id"), - constraint "fk_stat_user" foreign key ("owner") references "auth_info" ("id") on delete cascade deferrable initially deferred, - constraint "fk_stat_primary_group" foreign key ("group") references "group" ("gid") on delete cascade deferrable initially deferred + constraint "fk_stat_user" foreign key ("owner") references "auth_info" ("id") on delete cascade deferrable initially immediate, + constraint "fk_stat_primary_group" foreign key ("group") references "group" ("gid") on delete cascade deferrable initially immediate ); create trigger update_stat_last_update before update on stat FOR EACH ROW EXECUTE PROCEDURE last_update_column(); comment on table "stat" is ''; @@ -220,26 +220,26 @@ comment on column "implemented_action"."action" is ''; comment on column "implemented_action"."status" is ''; -create table "privilege" ( - "role" varchar(30) not null, -- TODO change to enum - "who" int not null default 0, - "action" text not null, - "type" varchar(30) not null, -- TODO change to enum - "related_table_name" varchar(100) not null, - "related_object_uid" int not null default 0, - constraint "pk_privilege" primary key("role", "who", "action", "type", "related_table_name", "related_object_uid") -); -create index "ix_privilege_action_type" on "privilege" ( "action", "type") with ( FILLFACTOR=100 ); -create index "ix_privilege_related_table" on "privilege" ( "related_table_name" ) with ( FILLFACTOR=100 ); -create index "ix_privilege_action" on "privilege" ( "action" ) with ( FILLFACTOR=100 ); -create index "ix_privilege_type" on "privilege" ( "type" ) with ( FILLFACTOR=100 ); -comment on table "privilege" is ''; -comment on column "privilege"."role" is 'specifies whether the privilege is granted to a user, a group, or in the case of an “object” privilege, the object’s owner or owner_group. A further special case, in my system, is “self.”'; -comment on column "privilege"."who" is 'is needed if role is user or group, and holds the user or group ID to which the privilege is granted.'; -comment on column "privilege"."action" is 'is the action the privilege grants. This is always required.'; -comment on column "privilege"."type" is 'specifies whether the privilege is “object”, “table”, or “global.”'; -comment on column "privilege"."related_table_name" is 'holds the name of the table to which the privilege applies. This is always required, though in the case of a “self” privilege it’s redundant because a “self” privilege always applies to the t_user table.'; -comment on column "privilege"."related_object_uid" is 'stores the ID of the object to which the privilege applies, if it’s an object privilege. This has no meaning for table and global privileges, of course. The one applies to a table, not an object, and the second applies to all rows in a table, so an ID is immaterial. This is also not used for self privileges, because by definition a self privilege has to apply to the user requesting permission to do something.'; +--create table "privilege" ( +-- "role" varchar(30) not null, -- TODO change to enum +-- "who" int not null default 0, +-- "action" text not null, +-- "type" varchar(30) not null, -- TODO change to enum +-- "related_table_name" varchar(100) not null, +-- "related_object_uid" int not null default 0, +-- constraint "pk_privilege" primary key("role", "who", "action", "type", "related_table_name", "related_object_uid") +--); +--create index "ix_privilege_action_type" on "privilege" ( "action", "type") with ( FILLFACTOR=100 ); +--create index "ix_privilege_related_table" on "privilege" ( "related_table_name" ) with ( FILLFACTOR=100 ); +--create index "ix_privilege_action" on "privilege" ( "action" ) with ( FILLFACTOR=100 ); +--create index "ix_privilege_type" on "privilege" ( "type" ) with ( FILLFACTOR=100 ); +--comment on table "privilege" is ''; +--comment on column "privilege"."role" is 'specifies whether the privilege is granted to a user, a group, or in the case of an “object” privilege, the object’s owner or owner_group. A further special case, in my system, is “self.”'; +--comment on column "privilege"."who" is 'is needed if role is user or group, and holds the user or group ID to which the privilege is granted.'; +--comment on column "privilege"."action" is 'is the action the privilege grants. This is always required.'; +--comment on column "privilege"."type" is 'specifies whether the privilege is “object”, “table”, or “global.”'; +--comment on column "privilege"."related_table_name" is 'holds the name of the table to which the privilege applies. This is always required, though in the case of a “self” privilege it’s redundant because a “self” privilege always applies to the t_user table.'; +--comment on column "privilege"."related_object_uid" is 'stores the ID of the object to which the privilege applies, if it’s an object privilege. This has no meaning for table and global privileges, of course. The one applies to a table, not an object, and the second applies to all rows in a table, so an ID is immaterial. This is also not used for self privileges, because by definition a self privilege has to apply to the user requesting permission to do something.'; create or replace function update_category_parent_path() returns trigger as $$ @@ -264,7 +264,7 @@ create table "category"( "description" text check(length(description) < 100000 ), "parent_path" ltree, constraint "pk_category_uid" primary key ("id"), - constraint "fk_category_parent_id" foreign key ("parent_id") references "category"("id") on delete cascade deferrable initially deferred, + constraint "fk_category_parent_id" foreign key ("parent_id") references "category"("id") on delete cascade deferrable initially immediate, constraint "fk_category_stat_owner" foreign key ("owner") references "auth_info"("id") deferrable initially immediate ) INHERITS (stat); create index "ix_category_parent_path" on "category" using GIST ("parent_path"); @@ -277,18 +277,18 @@ comment on column "category"."description" is ''; comment on column "category"."parent_path" is ''; -create table "measurands"( - "id" serial not null unique primary key, - "name" text not null unique, - "description" text, - "dimension_symbol" text -); +--create table "measurands"( +-- "id" serial not null unique primary key, +-- "name" text not null unique, +-- "description" text, +-- "dimension_symbol" text +--); -create table "metric_systems"( - "id" serial not null primary key, - "name" VARCHAR(32) not null unique, - "description" text -); +--create table "metric_systems"( +-- "id" serial not null primary key, +-- "name" VARCHAR(32) not null unique, +-- "description" text +--); --comment on table measurands IS 'Information about measured quantity length, time etc.'; @@ -314,8 +314,8 @@ create table "metric_systems"( -- equation TEXT not null, -- constraint unit_conversions_unique primary key (from_unit, to_unit) --); ---comment on table units_conversions IS 'This table contains a mathematical equation for converting one unitl to other, more info available at http://www.partow.net/programming/exprtk/index.html'; ---comment on column units_conversions.equation IS 'this equation should be a proper exprtk equation'; +--comment on table units_conversions IS 'This table contains a mathematical equation for converting one unitl to other'; +--comment on column units_conversions.equation IS 'this equation should be a proper script (mayby chaiscript?)'; --create table pointed_values( -- id serial primary key, @@ -341,45 +341,45 @@ create table "metric_systems"( --create table "item_namespaces"( --); -create table "item"( - "category_id" int not null, - "symbol" text not null, - "original_symbol" text, - "producer" text, - "visibility" VARCHAR(64) DEFAULT 'global' not null, - "attributes" jsonb not null DEFAULT('{}'), - "description" TEXT, - constraint "pk_items" primary key ("id"), - constraint "fk_item_category" foreign key ("category_id") references "category"("id") on delete cascade deferrable initially deferred, - constraint "fk_item_auth_info" foreign key ("owner") REFERENCES "auth_info"("id") deferrable initially IMMEDIATE -) INHERITS (stat); -create index "ix_item_attributes" on "item" USING GIN ("attributes"); -create unique index "ux_item" on "item"("name", "symbol"); -create trigger update_item_last_update before update on item FOR EACH ROW EXECUTE PROCEDURE last_update_column(); -comment on table "item" is ''; -comment on column "item"."category_id" is ''; -comment on column "item"."symbol" is ''; -comment on column "item"."original_symbol" is ''; -comment on column "item"."producer" is ''; -comment on column "item"."visibility" is ''; -comment on column "item"."attributes" is ''; -comment on column "item"."description" is ''; +--create table "item"( +-- "category_id" int not null, +-- "symbol" text not null, +-- "original_symbol" text, +-- "producer" text, +-- "visibility" VARCHAR(64) DEFAULT 'global' not null, +-- "attributes" jsonb not null DEFAULT('{}'), +-- "description" TEXT, +-- constraint "pk_items" primary key ("id"), +-- constraint "fk_item_category" foreign key ("category_id") references "category"("id") on delete cascade deferrable initially immediate, +-- constraint "fk_item_auth_info" foreign key ("owner") REFERENCES "auth_info"("id") deferrable initially immediate +--) INHERITS (stat); +--create index "ix_item_attributes" on "item" USING GIN ("attributes"); +--create unique index "ux_item" on "item"("name", "symbol"); +--create trigger update_item_last_update before update on item FOR EACH ROW EXECUTE PROCEDURE last_update_column(); +--comment on table "item" is ''; +--comment on column "item"."category_id" is ''; +--comment on column "item"."symbol" is ''; +--comment on column "item"."original_symbol" is ''; +--comment on column "item"."producer" is ''; +--comment on column "item"."visibility" is ''; +--comment on column "item"."attributes" is ''; +--comment on column "item"."description" is ''; -create table "inventory"( - "description" TEXT check(length(description)< 100000), - constraint "pk_inventory" primary key ("id"), - constraint "fk_inventory_owner" foreign key ("owner") REFERENCES "auth_info" ("id") deferrable initially IMMEDIATE, - constraint "chk_inventory_name_length" check (length(name) < 100) -) INHERITS (stat); -create trigger update_inventory_last_update before update on inventory FOR EACH ROW EXECUTE PROCEDURE last_update_column(); +--create table "inventory"( +-- "description" TEXT check(length(description)< 100000), +-- constraint "pk_inventory" primary key ("id"), +-- constraint "fk_inventory_owner" foreign key ("owner") REFERENCES "auth_info" ("id") deferrable initially immediate, +-- constraint "chk_inventory_name_length" check (length(name) < 100) +--) INHERITS (stat); +--create trigger update_inventory_last_update before update on inventory FOR EACH ROW EXECUTE PROCEDURE last_update_column(); -create table "user_inventory"( - "auth_info_id" INTEGER not null REFERENCES "auth_info" on DELETE CASCADE, - "inventory_id" INTEGER not null REFERENCES "inventory" on DELETE CASCADE, - constraint user_inventory_pk primary key ("inventory_id", "auth_info_id") -); +--create table "user_inventory"( +-- "auth_info_id" INTEGER not null REFERENCES "auth_info" on DELETE CASCADE, +-- "inventory_id" INTEGER not null REFERENCES "inventory" on DELETE CASCADE, +-- constraint user_inventory_pk primary key ("inventory_id", "auth_info_id") +--); --create table in_stock( @@ -419,11 +419,3 @@ create table "user_inventory"( -- create trigger update_items_last_update before update on items FOR EACH ROW EXECUTE PROCEDURE last_update_column(); -- create trigger update_shelfs_last_update before update on shelfs FOR EACH ROW EXECUTE PROCEDURE last_update_column(); -- create trigger update_inventory_operations_lats_update before update on inventory_operations FOR EACH ROW EXECUTE PROCEDURE last_update_column(); - -DO -$$ -DECLARE lastid int; - -BEGIN - -END $$; diff --git a/src/eedb/auth/PgUserAuth.cpp b/src/eedb/auth/PgUserAuth.cpp index 9a93c82..c38a97a 100644 --- a/src/eedb/auth/PgUserAuth.cpp +++ b/src/eedb/auth/PgUserAuth.cpp @@ -4,7 +4,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -306,10 +307,11 @@ void PgUserAuth::removeAuthToken(const Wt::Auth::User & user, const std::string } Wt::Auth::User PgUserAuth::findWithAuthToken(const std::string & hash) const { - // auto u = _userAuth.findWithAuthToken(hash); - // if(!u) - // return {}; - // return {u->id(), *this}; + spdlog::get("default")->debug("searching user by auth token: '{}'...", hash); + auto u = _priv->_users->findWith(eedb::AuthTokenConst(hash)); + if(!u) + return {}; + return {std::to_string(u->uid()), *this}; } int PgUserAuth::updateAuthToken(const Wt::Auth::User & user, const std::string & oldhash, const std::string & newhash) { diff --git a/src/eedb/data/AuthToken.hpp b/src/eedb/data/AuthToken.hpp index 5188dad..40dd818 100644 --- a/src/eedb/data/AuthToken.hpp +++ b/src/eedb/data/AuthToken.hpp @@ -2,7 +2,6 @@ #include #include -#include namespace eedb { @@ -27,14 +26,4 @@ class AuthToken { virtual void update(std::string newHash) = 0; }; -class AuthTokens { - public: - virtual ~AuthTokens() = default; - - virtual AuthToken * find(std::variant< std::string_view, AuthTokenRole > token) const = 0; - - virtual void removeToken(std::string_view token) = 0; - - virtual AuthToken * addToken(std::string token, AuthTokenRole role) = 0; -}; } // namespace eedb diff --git a/src/eedb/data/AuthTokenConst.hpp b/src/eedb/data/AuthTokenConst.hpp new file mode 100644 index 0000000..03b99a6 --- /dev/null +++ b/src/eedb/data/AuthTokenConst.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +namespace eedb { + +class AuthTokenConst final : public AuthToken { + public: + AuthTokenConst(std::string hash) : _hash{std::move(hash)} {} + + std::string_view token() const override { + return _hash; + } + + us_point expireTimepoint() const override { + throw; + } + + bool expired() const override { + throw; + } + void update(std::string newHash) override { + throw; + } + + private: + std::string _hash; +}; + +} // namespace eedb diff --git a/src/eedb/data/AuthTokens.hpp b/src/eedb/data/AuthTokens.hpp index e69de29..96e6b9c 100644 --- a/src/eedb/data/AuthTokens.hpp +++ b/src/eedb/data/AuthTokens.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include + +namespace eedb { + +class AuthTokens { + public: + virtual ~AuthTokens() = default; + + virtual AuthToken * find(std::variant< std::string_view, AuthTokenRole > token) const = 0; + + virtual void removeToken(std::string_view token) = 0; + + virtual AuthToken * addToken(std::string token, AuthTokenRole role) = 0; +}; +} // namespace eedb diff --git a/src/eedb/data/Email.hpp b/src/eedb/data/Email.hpp index 91d9dbb..a1cfc49 100644 --- a/src/eedb/data/Email.hpp +++ b/src/eedb/data/Email.hpp @@ -5,7 +5,14 @@ namespace eedb { class EmailToken { public: - explicit EmailToken(std::string) {} + explicit EmailToken(std::string token) : _token{std::move(token)} {} + + std::string_view token() const { + return _token; + } + + private: + std::string _token; }; class Email { diff --git a/src/eedb/data/Users.hpp b/src/eedb/data/Users.hpp index 6ba7a7d..8c46a73 100644 --- a/src/eedb/data/Users.hpp +++ b/src/eedb/data/Users.hpp @@ -21,7 +21,7 @@ class Users { template < typename T > using shared_ptr = std::shared_ptr< T >; - using string = std::string; + using string = std::string; public: virtual ~Users() = default; @@ -29,13 +29,13 @@ class Users { virtual unique_ptr< User > findWith(int64_t uid) const = 0; virtual unique_ptr< User > findWith(const AuthIdentity & name) const = 0; virtual unique_ptr< User > findWith(const Email & email) const = 0; - virtual unique_ptr< User > findWith(const EmailToken & token) const = 0; - // virtual unique_ptr< User > findWith(const AuthToken & token) const = 0; + virtual unique_ptr< User > findWith(const EmailToken & token) const = 0; + virtual unique_ptr< User > findWith(const AuthToken & token) const = 0; // adds new user into users virtual unique_ptr< User > addUser(unique_ptr< AuthInfo >, unique_ptr< AuthIdentity >) = 0; // remove user from database - virtual void removeUser(std::unique_ptr< AuthInfo > user) const = 0; + virtual void removeUser(std::unique_ptr< User > user) const = 0; }; } // namespace eedb diff --git a/src/eedb/db/data/PgAuthToken.hpp b/src/eedb/db/data/PgAuthToken.hpp index b76fcdf..1dd48c6 100644 --- a/src/eedb/db/data/PgAuthToken.hpp +++ b/src/eedb/db/data/PgAuthToken.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include diff --git a/src/eedb/db/data/PgUsers.cpp b/src/eedb/db/data/PgUsers.cpp index 3bf033b..8f7fc99 100644 --- a/src/eedb/db/data/PgUsers.cpp +++ b/src/eedb/db/data/PgUsers.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -28,70 +29,125 @@ struct PgUsers::PgUsersPriv { PgUsersPriv(eedb::db::PgConnection & db) : _db{db} {} eedb::db::PgConnection & _db; + + private: + // select + auto userData() const { + return t_auth_info.id; + } + + // where + auto tokenNotExpired() const { + return t_auth_token.expires < std::chrono::system_clock::now(); + } + + auto tokenRole(AuthTokenRole role) const { + return t_auth_token.role == static_cast< int >(role); + } + + template < typename TokenType > + auto tokenValueEq(TokenType && token) const { + return t_auth_token.value == std::string{token.token()}; + } + + auto statusIsValid() const { + return t_auth_info.status == 10; + } + + auto idEq(const int64_t id) const { + return t_auth_info.id == id; + } + + auto identityEq(const AuthIdentity & identity) const { + return t_auth_identity.provider == std::string{identity.identity()} and + t_auth_identity.identity == std::string{identity.identity()}; + } + + auto emailEq(const Email & email) const { + return t_auth_info.email == std::string{email.address()}; + } + + auto emailTokenEq(const EmailToken & token) const { + return tokenValueEq(token) and tokenNotExpired() and tokenRole(AuthTokenRole::EmailToken); + } + + auto authTokenEq(const AuthToken & token) const { + return tokenValueEq(token) and tokenNotExpired() and tokenRole(AuthTokenRole::Auth); + } + + // from + auto allAuthData() const { + return t_auth_info // + .inner_join(t_auth_identity) + .on(t_auth_info.id == t_auth_identity.auth_info_id) + .inner_join(t_auth_token) + .on(t_auth_info.id == t_auth_token.auth_info_id); + } + + public: + auto by(const int64_t id) const { + return select(userData()) // + .from(allAuthData()) + .where(idEq(id) and statusIsValid()); + } + + auto by(const AuthIdentity & identity) const { + return select(userData()) // + .from(allAuthData()) + .where(identityEq(identity) and statusIsValid()); + } + + auto by(const Email & email) const { + return select(t_auth_info.id) // + .from(allAuthData()) + .where(emailEq(email) and statusIsValid()); + } + + auto by(const EmailToken & token) const { + return select(userData()) // + .from(allAuthData()) + .where(emailTokenEq(token) and statusIsValid()); + } + + auto by(const AuthToken & authToken) const { + return select(userData()) // + .from(allAuthData()) + .where(authTokenEq(authToken) and statusIsValid()); + } + + template < typename Key > + auto find(Key && key) -> std::unique_ptr< PgUser > { + auto & db = _db; + auto result = db(by(key)); + + if(result.empty()) { + return {}; + } + return std::make_unique< PgUser >(_db, result.front().id); + } }; PgUsers::PgUsers(eedb::db::PgConnection & db) : _priv{spimpl::make_unique_impl< PgUsersPriv >(db)} {} unique_ptr< User > PgUsers::findWith(int64_t uid) const { - auto & db = *(_priv->_db.native()); - - auto result = db(select(t_auth_info.id) // - .from(t_auth_info) // - .where(t_auth_info.id == uid)); - -// const auto inner_select = select(t_auth_identity.id, t_auth_identity) // -// .from(t_auth_identity) // -// .where(t_auth_identity.auth_info_id == 6); - -// auto userdata = db(sqlpp::custom_query()); - -// select(t_auth_info.id, sub) // -// .from(auth_info -// .inner_join( // -// // -// ) -// .on(t_auth_identity.auth_info_id == t_auth_info.id))); - - if(result.empty()) { - return {}; - } - return std::make_unique< PgUser >(_priv->_db, result.front().id); + return _priv->find(uid); } unique_ptr< User > PgUsers::findWith(const AuthIdentity & identity) const { - const auto identity_eq = t_auth_identity.identity == std::string{identity.identity()}; - const auto provider_eq = t_auth_identity.provider == std::string{identity.provider()}; - - auto & db = *(_priv->_db.native()); - auto result = db(select(t_auth_info.id) // - .from(t_auth_info.inner_join(t_auth_identity).on(t_auth_info.id == t_auth_identity.auth_info_id)) // - .where(provider_eq and identity_eq)); - - if(result.empty()) { - return {}; - } - return std::make_unique< PgUser >(_priv->_db, result.front().id); + return _priv->find(identity); } unique_ptr< User > PgUsers::findWith(const Email & email) const { - auto & db = _priv->_db; - const auto & result = db(select(t_auth_info.id) // - .from(t_auth_info) // - .where(t_auth_info.email == std::string{email.address()})); - - if(result.empty()) { - return {}; - } - return std::make_unique< PgUser >(_priv->_db, result.front().id); + return _priv->find(email); } unique_ptr< User > PgUsers::findWith(const EmailToken & token) const { - assert(false); + return _priv->find(token); } -// unique_ptr< User > PgUsers::findWith(const Users::AuthToken & token) const { -// return {}; -//} +unique_ptr< User > PgUsers::findWith(const AuthToken & token) const { + return _priv->find(token); +} unique_ptr< User > PgUsers::addUser(unique_ptr< AuthInfo > authInfo, unique_ptr< AuthIdentity > authIdentity) { assert(authInfo); @@ -104,10 +160,10 @@ unique_ptr< User > PgUsers::addUser(unique_ptr< AuthInfo > authInfo, unique_ptr< auto auth_info_id = // db(sqlpp::postgresql::insert_into(t_auth_info) - .set( // - t_auth_info.password_hash = pass.value(), // - t_auth_info.password_method = pass.function(), // - t_auth_info.password_salt = pass.salt(), // + .set( // + t_auth_info.password_hash = pass.value(), + t_auth_info.password_method = pass.function(), + t_auth_info.password_salt = pass.salt(), t_auth_info.email = std::string{email.address()}, t_auth_info.status = 0) /// TODO status->UserWaitingForVerification .returning(t_auth_info.id)) @@ -123,4 +179,10 @@ unique_ptr< User > PgUsers::addUser(unique_ptr< AuthInfo > authInfo, unique_ptr< return std::make_unique< eedb::PgUser >(_priv->_db, auth_info_id); } +void PgUsers::removeUser(std::unique_ptr< User > user) const { + auto & db = _priv->_db; + + // db() +} + } // namespace eedb diff --git a/src/eedb/db/data/PgUsers.hpp b/src/eedb/db/data/PgUsers.hpp index e2b89f3..5e4dd7c 100644 --- a/src/eedb/db/data/PgUsers.hpp +++ b/src/eedb/db/data/PgUsers.hpp @@ -18,10 +18,10 @@ class PgUsers : public Users { unique_ptr< User > findWith(const AuthIdentity & name) const override; unique_ptr< User > findWith(const Email & email) const override; unique_ptr< User > findWith(const EmailToken & token) const override; - // unique_ptr< User > findWith(const AuthToken & token) const override; + unique_ptr< User > findWith(const AuthToken & token) const override; unique_ptr< User > addUser(unique_ptr< AuthInfo >, unique_ptr< AuthIdentity >) override; - void removeUser(std::unique_ptr< AuthInfo > user) const override{} + void removeUser(std::unique_ptr< User > user) const override; private: struct PgUsersPriv; diff --git a/tests/unit/db/test_eedb_data_PgUsers.cpp b/tests/unit/db/test_eedb_data_PgUsers.cpp index e141791..f00e930 100644 --- a/tests/unit/db/test_eedb_data_PgUsers.cpp +++ b/tests/unit/db/test_eedb_data_PgUsers.cpp @@ -128,3 +128,11 @@ TEST_F(PgUsersTest, findByEmail) { auto u = sut->findWith(eedb::Email{"test_user_5@eedb.pl"}); EXPECT_EQ(idMap().at("test_user_5"), u->uid()); } + +TEST_F(PgUsersTest, removeUser) { + createTestUsers(); + + auto u = sut->findWith(eedb::AuthIdentityConst{"test_user_1", "loginname"}); + sut->removeUser(std::move(u)); + EXPECT_FALSE(sut->findWith(eedb::AuthIdentityConst{"test_user_1", "loginname"})); +}