{"id":16776330,"url":"https://github.com/splendiddata/login_hook","last_synced_at":"2025-07-13T14:36:36.107Z","repository":{"id":53717190,"uuid":"116937909","full_name":"splendiddata/login_hook","owner":"splendiddata","description":"Postgres database extension to mimic a logon trigger","archived":false,"fork":false,"pushed_at":"2025-05-09T15:31:40.000Z","size":153,"stargazers_count":32,"open_issues_count":0,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-08T14:44:26.936Z","etag":null,"topics":["logon-trigger","postgres","postgresql","postgresql-extension"],"latest_commit_sha":null,"homepage":null,"language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/splendiddata.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-01-10T09:34:47.000Z","updated_at":"2025-05-09T15:31:43.000Z","dependencies_parsed_at":"2022-09-10T13:40:18.547Z","dependency_job_id":"dd91c30e-df6f-4c99-a5aa-ebb15f9a26d8","html_url":"https://github.com/splendiddata/login_hook","commit_stats":{"total_commits":40,"total_committers":5,"mean_commits":8.0,"dds":"0.17500000000000004","last_synced_commit":"e51444322e2a0a0fadb58333d34cda115b4c20e0"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/splendiddata/login_hook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/splendiddata%2Flogin_hook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/splendiddata%2Flogin_hook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/splendiddata%2Flogin_hook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/splendiddata%2Flogin_hook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/splendiddata","download_url":"https://codeload.github.com/splendiddata/login_hook/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/splendiddata%2Flogin_hook/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265156440,"owners_count":23719718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["logon-trigger","postgres","postgresql","postgresql-extension"],"created_at":"2024-10-13T07:09:35.413Z","updated_at":"2025-07-13T14:36:36.096Z","avatar_url":"https://github.com/splendiddata.png","language":"PLpgSQL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# login_hook\nPostgres database extension to execute some code on user login, comparable to\nOracle's after logon trigger.\n\n## Postgres versions\nThe login_hook database extension works well in Postgres versions 13, 14, 15 and 16.\n\nPostgres version 17 works as well **BUT** please start using\nthe login event trigger instead. For an example see\n[https://www.postgresql.org/docs/17/event-trigger-database-login-example.html](https://www.postgresql.org/docs/17/event-trigger-database-login-example.html).\nTo allow for a smooth migration to the Postgres native login even trigger: As soon as a login event trigger is defined in the database, the login_hook.login() function will no longer be executed. Later you can drop the login_hook extension and remove the login_hook.login() function.\n\nMaintenance of the login_hook will be discontinued in Postgres version 18.\n\n## Installation\nFirst you'll need to compile the database extension (Check the\n[Postgres manual](https://www.postgresql.org/docs/current/static/extend-pgxs.html)\nfor more information):\u003cbr\u003e\n - Make sure pg_config points to the right places\u003cbr\u003e\n - execute: make\u003cbr\u003e\n - execute: sudo make install\u003cbr\u003e\n\nAfter compilation, the login_hook.so library must be set to load at session\nstart. So please alter the postgresql.conf file and add the login\\_hook.so\nlibrary to the session\\_preload\\_libraries setting. For example:\n\n```\n      .\n      .\n      .\n\n#------------------------------------------------------------------------------\n# CUSTOMIZED OPTIONS\n#------------------------------------------------------------------------------\n\n# Add settings for extensions here\n#\nsession_preload_libraries = 'login_hook'\n```\n\nRestart the database to activate the setting.\n\nThen logon to the database and execute:\n\n```SQL\ncreate extension login_hook;\n```\n\nAnd create function login_hook.login() that is to be executed when a client\nlogs in. For example:\n\n```PLpgSQL\nCREATE OR REPLACE FUNCTION login_hook.login() RETURNS VOID LANGUAGE PLPGSQL AS $$\nDECLARE\n    ex_state   TEXT;\n    ex_message TEXT;\n    ex_detail  TEXT;\n    ex_hint    TEXT;\n    ex_context TEXT;\nBEGIN\n\tIF NOT login_hook.is_executing_login_hook()\n\tTHEN\n\t    RAISE EXCEPTION 'The login_hook.login() function should only be invoked by the login_hook code';\n\tEND IF;\n\n\tBEGIN\n\t   --\n\t   -- Do whatever you need to do at login here.\n\t   -- For example:\n\t   RAISE NOTICE 'Hello %', current_user;\n\tEXCEPTION\n\t   WHEN OTHERS THEN\n\t       GET STACKED DIAGNOSTICS ex_state   = RETURNED_SQLSTATE\n\t                             , ex_message = MESSAGE_TEXT\n\t                             , ex_detail  = PG_EXCEPTION_DETAIL\n\t                             , ex_hint    = PG_EXCEPTION_HINT\n\t                             , ex_context = PG_EXCEPTION_CONTEXT;\n\t       RAISE LOG e'Error in login_hook.login()\\nsqlstate: %\\nmessage : %\\ndetail  : %\\nhint    : %\\ncontext : %'\n\t               , ex_state\n\t               , ex_message\n\t               , ex_detail\n\t               , ex_hint\n\t               , ex_context;\n    END\t;\nEND\n$$;\nGRANT EXECUTE ON FUNCTION login_hook.login() TO PUBLIC;\n```\n#### Remarks:\nthe public execute permission is absolutely necessary because the function will\nbe invoked for every body/thing that logs in to the database. In fact the function\nwill be executed every time that a new process starts on behalf of a user session,\nso also if you are for example logged in with psql and use \\c to reconnect. And\nalso sessions started by dblink or fdw will trigger execution of the login()\nfunction.\n\nHaving public access granted to everybody might tempt people to execute the\nlogin_hook.login() function at any time. But of course it is intended to run\nonly at login. The login\\_hook.is\\_executing\\_login\\_hook() function can be used\nto check if the function is invoked under the control of the login_hook code.\n\nMake sure that all exceptions that occur in the login\\_hook.login() function\nare properly dealt with because otherwise logging in to the database might\nprove challenging. Superusers will get a warning, but are still allowed to\nlog in to be able to correct the function. Normal users will be logged out\nimmediately when the login() function fails.\n\nThe login\\_hook.login() function will not be invoked:\n* in a background processes\n* when the database is in recovery mode (replication backup server)\n\nThe \"make installcheck\" will only pass if \"session_preload_libraries = 'login_hook'\"\nis added to the postgresql.conf file\n\nBEWARE! there appears to be a problem with EDB databases. See issue \u003ca href=\"https://github.com/splendiddata/login_hook/issues/5\"\u003e#5\u003c/a\u003e.\n## Functions\n**login_hook.is_executing_login_hook() returns boolean**\n\n    returns true when the login_hook.login() function is invoked under\n    control of the login_hook code. When invoked during a normal\n    session, it will always return false.\n\n**login_hook.get_login_hook_version() returns text**\n\n    returns the compiled version of the login_hook software.\n\n**login_hook.login() returns void**\n\n    To be provided by you!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsplendiddata%2Flogin_hook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsplendiddata%2Flogin_hook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsplendiddata%2Flogin_hook/lists"}