[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fopk9srsgt993":3},{"id":4,"title":5,"description":6,"category":7,"contentHtml":8,"date":9,"createdAt":10,"updatedAt":11},"f951adce-6292-48d4-b83e-cf4a299cc7be","Implement Authorization with Role-Based Access Control (RBAC) in Golang","A practical guide on implementing role-based authorization in Go. Learn how to design database-driven roles and permissions, build an RBAC middleware, and protect your API routes based on assigned roles.","backend development","\u003Cp>This is part 2 of our authentication and authorization series. In the previous part, we implemented an authentication system from scratch in Golang with Gin and PostgreSQL. Now in this part, we will go further and see how we can implement authorization in our system.\u003C\u002Fp>\n\u003Ch2>Prerequisites\u003C\u002Fh2>\n\u003Cp>The requirements to follow along are:\u003C\u002Fp>\n\u003Col>\n\u003Cli>A working laptop or PC with Golang installed.\u003C\u002Fli>\n\u003Cli>Some familiarity with Golang and SQL.\u003C\u002Fli>\n\u003Cli>Having read the first part of this series (\u003Ca href=\"https:\u002F\u002Fwww.umohsg.com\u002Fblog\u002Fbuild-a-secure-authentication-system-in-golang-with-gin-jwt-and-postgres-48f2e823-f2c3-46c7-a861-ec44e806c38b\">link here\u003C\u002Fa>).\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2>What is Authorization?\u003C\u002Fh2>\n\u003Cp>Authorization answers the second half of our dilemma. When we know who you are, surely, we should know what you're allowed to do in our system?\u003C\u002Fp>\n\u003Cp>Authorization determines what an authenticated identity (user, application, or service) can do and which resources it can access within a system. It ensures that every authenticated identity operates within defined boundaries. Without it, a user who logs in successfully could access all sensitive data and perform any action.\u003C\u002Fp>\n\u003Ch3>What Does Authorization Do in Our System?\u003C\u002Fh3>\n\u003Cp>Authorization connects three main components:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Users\u003C\u002Fstrong> (authenticated entities)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Permissions\u003C\u002Fstrong> (actions they can perform)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Resources\u003C\u002Fstrong> (the things we're protecting)\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch3>Common Authorization Models\u003C\u002Fh3>\n\u003Cp>There are mainly three ways to implement authorization in a system:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Role-Based Access Control (RBAC)\u003C\u002Fstrong>\nRBAC is the foundational authorization model. It simplifies permission management by assigning permissions to roles (e.g., Admin, Driver, User) and then assigning those roles to users.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>How it works\u003C\u002Fstrong>: The system checks the user's assigned role(s) and aggregates their permissions to determine if the requested action is allowed.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Attribute-Based Access Control (ABAC)\u003C\u002Fstrong>\nABAC uses dynamic policies that evaluate attributes of the user, the resource, and the environment to make an access decision.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>How it works\u003C\u002Fstrong>: Access is determined by policy expressions that evaluate in real time (e.g., \u003Ccode>user.department == resource.department\u003C\u002Fcode>, or checking if the current time falls within business hours).\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Relationship-Based Access Control (ReBAC) and Fine-Grained Authorization (FGA)\u003C\u002Fstrong>\nReBAC bases authorization on the relationships and ownership between a user and a specific resource.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>How it works\u003C\u002Fstrong>: The system checks for explicit relationships (e.g., \"owner of,\" \"shared with,\" \"member of group\") to grant or deny access. Current implementations use graph-based relationship modeling to navigate complex permission chains.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>In this guide, we will be focusing on implementing RBAC. It's the most common and straightforward to implement, making it a solid starting point.\u003C\u002Fp>\n\u003Ch2>Database Migrations for RBAC\u003C\u002Fh2>\n\u003Cp>Now, let's implement RBAC into our Golang authentication system.\u003C\u002Fp>\n\u003Cp>First, we need to add some database migrations. In these migrations, we will create:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>A \u003Cstrong>roles\u003C\u002Fstrong> table to define the available roles.\u003C\u002Fli>\n\u003Cli>A \u003Cstrong>permissions\u003C\u002Fstrong> table to define the available permissions.\u003C\u002Fli>\n\u003Cli>A \u003Cstrong>role_permissions\u003C\u002Fstrong> table to establish the many-to-many relationship between roles and permissions.\u003C\u002Fli>\n\u003Cli>A \u003Cstrong>user_roles\u003C\u002Fstrong> table to establish the many-to-many relationship between users and roles.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>So let's create a new database migration:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"bash\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"bash\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">goose\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> create\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> create_authorization_tables\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> sql\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>Paste this into the generated migration file:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"sql\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"sql\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- migrations\u002F..._create_authorization_tables.sql\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- +goose Up\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- role\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">CREATE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> TABLE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> roles\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  id SMALLSERIAL \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">PRIMARY KEY\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> VARCHAR\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">50\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">UNIQUE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> NOT NULL\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">INSERT INTO\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">VALUES\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'super-admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'user'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'guest'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">--permissions\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">CREATE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> TABLE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> permissions\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  id SMALLSERIAL \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">PRIMARY KEY\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> VARCHAR\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">50\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">UNIQUE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> NOT NULL\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">INSERT INTO\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> permissions\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">VALUES\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'create_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'read_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'update_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'delete_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- role permissions\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">CREATE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> TABLE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> role_permissions\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  role_id \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">SMALLINT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> NOT NULL\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  permission_id \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">SMALLINT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> NOT NULL\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">  PRIMARY KEY\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (role_id, permission_id),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">  FOREIGN KEY\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (role_id) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">REFERENCES\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles(id) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">ON DELETE CASCADE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">  FOREIGN KEY\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (permission_id) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">REFERENCES\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> permissions\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(id) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">ON DELETE CASCADE\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">INSERT INTO\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> role_permissions (role_id, permission_id)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">  p\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">    VALUES\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'super-admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'create_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'super-admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'read_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'super-admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'update_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'super-admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'delete_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'read_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'update_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'admin'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'delete_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'user'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'read_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'user'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'update_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">      (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'guest'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">'read_task'\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  ) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">AS\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> mappings(role_name, permission_name)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles r \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> mappings\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">role_name\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> permissions p \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> p\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> mappings\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">permission_name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- user roles\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">CREATE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> TABLE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> user_roles\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  user_id UUID \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">NOT NULL\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">  role_id \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">SMALLINT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> NOT NULL\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">  PRIMARY KEY\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (user_id, role_id),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">  FOREIGN KEY\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (user_id) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">REFERENCES\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> users(id) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">ON DELETE CASCADE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">  FOREIGN KEY\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (role_id) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">REFERENCES\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles(id) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">ON DELETE CASCADE\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">INSERT INTO\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles (user_id, role_id)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> u\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> users u\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> CROSS JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles r\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> 'user'\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> AND\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> NOT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> EXISTS\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> 1\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles ur\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> ur\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">user_id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> u\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">   AND\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> ur\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">role_id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> );\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">CREATE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> INDEX\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> idx_user_roles_user_id_role_id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles (user_id, role_id);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- +goose Down\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">DROP\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> TABLE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> IF\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> EXISTS\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">DROP\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> TABLE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> IF\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> EXISTS\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> permissions;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">DROP\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> TABLE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> IF\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> EXISTS\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> role_permissions;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">DROP\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> TABLE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> IF\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> EXISTS\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">DROP\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> INDEX\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> IF\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> EXISTS\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> idx_user_roles_user_id_role_id;\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>We also added an insert statement to set a default \"user\" role to any existing user who doesn't have a role (I mean, they shouldn't before this migration, right?). We then create an index for faster queries.\u003C\u002Fp>\n\u003Cp>Now apply the migration:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"bash\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"bash\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">goose\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> up\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch2>RBAC Queries\u003C\u002Fh2>\n\u003Cp>Next, let's write all our queries and let sqlc run its magic:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"sql\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"sql\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- queries\u002Fauthorization.sql\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: GetRoles :many\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: GetPermissions :many\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> permissions;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: GetEntityRoles :many\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">name\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles ur\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles r \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> ur\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">role_id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> ur\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">user_id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: GetRolePermissions :many\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> p\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">name\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> role_permissions rp\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> permissions p \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> p\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> rp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">permission_id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> rp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">role_id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: GetRolePermissionsByRoleName :many\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> p\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">name\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles r\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> role_permissions rp \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> rp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">role_id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> permissions p \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> p\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> rp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">permission_id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> r\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: GetEntityRolesPermissions :many\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT DISTINCT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> p\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">name\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles ur\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> role_permissions rp \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> rp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">role_id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> ur\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">role_id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> JOIN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> permissions p \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">ON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> p\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> rp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">permission_id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> ur\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">user_id\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: AssignRoleToEntity :exec\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">INSERT INTO\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles (user_id, role_id)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">2\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: RevokeRoleFromEntity :exec\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">DELETE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_id \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">1\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> AND\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> role_id \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  SELECT\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> id\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">  WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> name\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">2\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> );\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">-- name: RemoveAllEntityRoles :exec\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">DELETE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\"> FROM\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_roles\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#D73A49\">WHERE\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user_id \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> $\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>Then generate the Go code with:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"bash\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"bash\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">sqlc\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> generate\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>Great, we have covered most of what we need.\u003C\u002Fp>\n\u003Ch2>Adding Roles to JWT Claims\u003C\u002Fh2>\n\u003Cp>Next, we need to update our \u003Ccode>GenerateAccessToken\u003C\u002Fcode> function to accept roles so they can be added to the JWT claims. This way, we don't have to make a call to our database every time a user hits our RBAC middleware, as that would be very detrimental to performance.\u003C\u002Fp>\n\u003Ch3>A Note on Alternative Approaches\u003C\u002Fh3>\n\u003Cp>Another way we can do this is to store the user roles and permissions in Redis.\u003C\u002Fp>\n\u003Cp>That way, we will get them from Redis and proceed accordingly. This is actually the better approach because we can invalidate permissions and it will update in real time.\u003C\u002Fp>\n\u003Cp>Whereas with our JWT approach, if we invalidate an entity's permissions, those permissions still live until the JWT access token expires, in our case 10-15 minutes.\u003C\u002Fp>\n\u003Cp>Now you understand the tradeoff, but for simplicity of this guide, we will pass the roles to the JWT claims and then access them in our RBAC middleware. Everything else is the same, just the choice of where to store it.\u003C\u002Fp>\n\u003Ch3>Updating GenerateAccessToken\u003C\u002Fh3>\n\u003Cp>Let's update our \u003Ccode>GenerateAccessToken\u003C\u002Fcode> function to accept and add roles to the claims:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">\u002F\u002F pkg\u002Futil\u002Fauth.go\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> GenerateAccessToken\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">user\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> sqlc\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">User\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">roles\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">jwtSecret\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">byte\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">accessTokenTTL\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> time\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Duration\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">error\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\texpirationTime \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> time.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Now\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">UTC\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Add\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(accessTokenTTL)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tclaims \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> jwt\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">MapClaims\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\"sub\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:   user.ID.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">String\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\"email\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: user.Email,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\"roles\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: roles,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\"exp\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:   expirationTime.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Unix\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\"iat\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">:   time.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Now\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">UTC\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">().\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Unix\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\ttoken \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> jwt.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewWithClaims\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(jwt.SigningMethodHS256, claims)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\ttokenString, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> token.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">SignedString\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(jwtSecret)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\treturn\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \"\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, err\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\treturn\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> tokenString, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\">nil\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch2>Updating the Authentication Handlers\u003C\u002Fh2>\n\u003Ch3>Updating the SignUp Handler\u003C\u002Fh3>\n\u003Cp>We need to update our signup handler so that when any entity signs up, we assign them a default role. Just before we send the \"user created successfully\" response, let's add:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">\u002F\u002F internal\u002Fports\u002Fhttp\u002Fhandlers\u002Fuser\u002Fuser.go\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\terr \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> h.queries.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">AssignRoleToEntity\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">sqlc\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">AssignRoleToEntityParams\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tUserID: user.ID,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tName:   \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"user\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusInternalServerError, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\"message\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: err.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Error\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch3>Updating the SignIn Handler\u003C\u002Fh3>\n\u003Cp>Next, we'll have to update our signin handler to get the entity roles so we can pass them to the \u003Ccode>GenerateAccessToken\u003C\u002Fcode> function we just modified:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">\u002F\u002F internal\u002Fports\u002Fhttp\u002Fhandlers\u002Fuser\u002Fuser.go\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\troles, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> h.queries.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GetEntityRoles\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c, user.ID)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusInternalServerError, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\ttoken, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> util.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GenerateAccessToken\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">user, roles, []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">byte\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(h.environmentVariables.Authentication.JWT_SECRET), \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">30\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">time.Minute)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusInternalServerError, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\"message\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"failed to generate access token\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch3>Updating the RefreshAccessToken Handler\u003C\u002Fh3>\n\u003Cp>We must also do the same for the \u003Ccode>RefreshAccessToken\u003C\u002Fcode> handler, as it uses the \u003Ccode>GenerateAccessToken\u003C\u002Fcode> function as well:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">\u002F\u002F internal\u002Fports\u002Fhttp\u002Fhandlers\u002Fuser\u002Fuser.go\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\troles, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> h.queries.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GetEntityRoles\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(c, user.ID)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusInternalServerError, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\taccessToken, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> util.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GenerateAccessToken\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">user, roles, []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">byte\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(h.environmentVariables.Authentication.JWT_SECRET), \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">30\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">time.Minute)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusInternalServerError, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\"message\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"failed to generate access token\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch2>Updating the Auth Middleware\u003C\u002Fh2>\n\u003Cp>Now that our JWT tokens contain role claims, we need to update our \u003Ccode>AuthMiddleware\u003C\u002Fcode> to extract and set the roles from the token. We also need a new \u003Ccode>RoleMiddleware\u003C\u002Fcode> that will check if a user has the required roles before granting access to a route.\u003C\u002Fp>\n\u003Ch3>Updated AuthMiddleware\u003C\u002Fh3>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">\u002F\u002F internal\u002Fports\u002Fhttp\u002Fmiddleware\u002Fauth.go\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">package\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> middleware\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">net\u002Fhttp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">strings\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fgin-gonic\u002Fgin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fgoogle\u002Fuuid\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fumohsamuel\u002Fauthentication-authorization\u002Fpkg\u002Fenv\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fumohsamuel\u002Fauthentication-authorization\u002Fpkg\u002Futil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> AuthMiddleware\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">environmentVariables\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> env\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">EnvironmentVariables\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">HandlerFunc\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\treturn\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">c\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tauthHeader \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> c.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GetHeader\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> authHeader \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">==\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \"\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusUnauthorized, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\t\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Authorization header required\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Abort\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tparts \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> strings.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Split\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(authHeader, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\" \"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> len\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(parts) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> 2\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> ||\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> parts[\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">0\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">] \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \"Bearer\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusUnauthorized, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\t\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Invalid authorization format\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Abort\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\ttokenString \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> parts[\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">1\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tclaims, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> util.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">ValidateToken\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(tokenString, []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">byte\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(environmentVariables.Authentication.JWT_SECRET))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusUnauthorized, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\t\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Invalid or expired token\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Abort\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tuserIDStr, ok \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> claims[\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"sub\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">].(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> !\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">ok {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusUnauthorized, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\t\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Invalid token\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Abort\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tuserID, err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> uuid.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Parse\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(userIDStr)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> err \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">!=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#005CC5\"> nil\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusUnauthorized, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\t\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Invalid token\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Abort\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\trawRoles, ok \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> claims[\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"roles\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">].([]\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> !\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">ok {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusUnauthorized, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\t\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Invalid token\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Abort\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\troles \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> make\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">([]\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">len\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(rawRoles))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tfor\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> i, r \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> range\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> rawRoles {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\troles[i] \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> r.(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Set\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"userID\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, userID)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Set\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"roles\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, roles)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Next\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>So now, we also extract roles from the JWT claims (since we added them in our updated \u003Ccode>GenerateAccessToken\u003C\u002Fcode>) and we set them as well in the Gin context, easy.\u003C\u002Fp>\n\u003Ch3>RoleMiddleware\u003C\u002Fh3>\n\u003Cp>Since \u003Ccode>AuthMiddleware\u003C\u002Fcode> runs first and sets the user's roles in the Gin context, our \u003Ccode>RoleMiddleware\u003C\u002Fcode> can simply read them and check if the user has the required roles. Now, let's create it:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">\u002F\u002F internal\u002Fports\u002Fhttp\u002Fmiddleware\u002Fauth.go\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> RoleMiddleware\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">requiredRoles\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">HandlerFunc\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\treturn\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">c\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\trolesValue, exists \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> c.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Get\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"roles\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> !\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">exists {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">AbortWithStatus\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusUnauthorized)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\troles \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> rolesValue.([]\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\thasRole \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> false\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tfor\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> _, r \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> range\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> roles {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\tfor\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> _, rr \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> range\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> requiredRoles {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> r \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">==\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> rr {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t\t\thasRole \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> true\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\tif\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> !\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">hasRole {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusForbidden, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\t\"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Forbidden\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Abort\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\t\t\treturn\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Next\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>This middleware:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Retrieves the user's roles from the Gin context (remember we set them in the \u003Ccode>AuthMiddleware\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>Loops through the user's roles and checks if any match the required roles for the route.\u003C\u002Fli>\n\u003Cli>If the user has at least one of the required roles, the request proceeds. Otherwise, we return a \u003Ccode>403 Forbidden\u003C\u002Fcode> response.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2>Updating the API Routes\u003C\u002Fh2>\n\u003Cp>Finally, let's update our API routes to reflect our authorization updates:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"go\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"go\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">\u002F\u002F cmd\u002Fapi\u002Fapi.go\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">package\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> api\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">net\u002Fhttp\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">time\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fgin-contrib\u002Fcors\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fgin-gonic\u002Fgin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fumohsamuel\u002Fauthentication-authorization\u002Finternal\u002Fadapters\u002Fdatabase\u002Fsqlc\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fumohsamuel\u002Fauthentication-authorization\u002Finternal\u002Fports\u002Fhttp\u002Fhandlers\u002Fuser\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fumohsamuel\u002Fauthentication-authorization\u002Finternal\u002Fports\u002Fhttp\u002Fmiddleware\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">github.com\u002Fumohsamuel\u002Fauthentication-authorization\u002Fpkg\u002Fenv\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">type\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> Server\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> struct\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tEngine  \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Engine\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tEnv     \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">env\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">EnvironmentVariables\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tQueries \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">sqlc\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Queries\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\"> API\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">environmentVariables\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">env\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">EnvironmentVariables\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">queries\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">sqlc\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Queries\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Server\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\ts \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> &#x26;\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Server\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tEngine:  gin.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Default\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tEnv:     environmentVariables,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tQueries: queries,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tconfig \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> cors.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">DefaultConfig\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tconfig.AllowAllOrigins \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> true\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tconfig.AllowMethods \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"POST\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"GET\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"PUT\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"OPTIONS\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tconfig.AllowHeaders \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Origin\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Accept\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"User-Agent\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Cache-Control\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Pragma\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tconfig.ExposeHeaders \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Content-Length\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tconfig.AllowCredentials \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> true\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tconfig.MaxAge \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\"> 12\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> time.Hour\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\ts.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Use\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(cors.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">New\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(config))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\ts.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Static\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fdownloads\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"tmp\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tauth \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> s.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Group\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fauth\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\ts.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Auth\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(auth)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tv1 \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> s.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Group\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fapi\u002Fv1\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tprotected \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> v1.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Group\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tprotected.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Use\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(middleware.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">AuthMiddleware\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">s.Env))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\ts.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Health\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(protected)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t\ts.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">OnlyMinLevelAdmin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(protected)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\ts.Engine.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Run\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">\treturn\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> s\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">s \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Server\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Health\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">rg\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">RouterGroup\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\trg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GET\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fhealth\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">ctx\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tctx.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(http.StatusOK, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\"message\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Server Up!\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">s \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Server\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">OnlyMinLevelAdmin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">rg\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">RouterGroup\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tg \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> rg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Group\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fadmin\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\trequiredRoles \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> []\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">string\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"super-admin\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"admin\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Use\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(middleware.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">RoleMiddleware\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(requiredRoles))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">GET\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Ftest\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">c\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Context\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\tc.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">JSON\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">200\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\t\t\t\"success\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"you have successfully implemented RBAC\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\t})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">func\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> (\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">s \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Server\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">Auth\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#E36209\">rg\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\"> *\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">gin\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">RouterGroup\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\tuserHandler \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">:=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> user.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">NewUserHandler\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">s.Env, \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">*\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">s.Queries)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\trg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">POST\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fsignup\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, userHandler.SignUp)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\trg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">POST\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Fsignin\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, userHandler.SignIn)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\trg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">POST\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Frefresh\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, userHandler.RefreshAccessToken)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#8B8B8B94;--shiki-light:#6A737D\">\t\u002F\u002F admin in case of revoking access token\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">\trg.\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">POST\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">(\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u002Frevoke-refresh\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">, userHandler.RevokeRefreshAccessToken)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>I updated the route structure a little, so it's a bit different from Part 1:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Public routes\u003C\u002Fstrong> (\u003Ccode>\u002Fauth\u002F*\u003C\u002Fcode>) handle signup, signin, and token management.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Protected routes\u003C\u002Fstrong> (\u003Ccode>\u002Fapi\u002Fv1\u002F*\u003C\u002Fcode>) use the \u003Ccode>AuthMiddleware\u003C\u002Fcode>, so you must be authenticated to access them.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Admin routes\u003C\u002Fstrong> (\u003Ccode>\u002Fapi\u002Fv1\u002Fadmin\u002F*\u003C\u002Fcode>) add an extra layer with \u003Ccode>RoleMiddleware\u003C\u002Fcode>, so only users with the \u003Ccode>super-admin\u003C\u002Fcode> or \u003Ccode>admin\u003C\u002Fcode> role can access them.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Run the Application\u003C\u002Fh2>\n\u003Cp>Let's do some testing. You can run the application in your terminal with:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"bash\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"bash\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">go\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> run\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> cmd\u002Fmain.go\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch2>Testing with cURL\u003C\u002Fh2>\n\u003Cp>If we go to an admin-only route now as a regular user:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"bash\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"bash\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">export\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\"> ACCESS_TOKEN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#D73A49\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#6F42C1\">curl\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#005CC5\"> -X\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> GET\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> http:\u002F\u002Flocalhost:8080\u002Fapi\u002Fv1\u002Fadmin\u002Ftest\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#A0A0A0;--shiki-light:#005CC5\"> \\\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#005CC5\">  -H\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\"> \"Authorization: Bearer \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">$ACCESS_TOKEN\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\"> \u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>You should get the response 403:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"json\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"json\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">  \"error\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"Forbidden\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Cp>You can update your user role from your database using a query tool, or update your signup \u003Ccode>AssignRoleToEntity\u003C\u002Fcode> to create an admin entity. Then try the route again, and you should get the response:\u003C\u002Fp>\n\u003Cfigure data-rehype-pretty-code-figure=\"\">\u003Cpre tabindex=\"0\" data-language=\"json\" data-theme=\"vesper github-light\">\u003Ccode data-language=\"json\" data-theme=\"vesper github-light\" style=\"display: grid;\">\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFC799;--shiki-light:#005CC5\">  \"success\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">: \u003C\u002Fspan>\u003Cspan style=\"--shiki-dark:#99FFE4;--shiki-light:#032F62\">\"you have successfully implemented RBAC\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan data-line=\"\">\u003Cspan style=\"--shiki-dark:#FFF;--shiki-light:#24292E\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Ffigure>\n\u003Ch2>Conclusion\u003C\u002Fh2>\n\u003Cp>Congratulations, if you have made it this far, you have successfully implemented RBAC authorization. This system we built includes:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Database schema for roles, permissions, and their relationships.\u003C\u002Fli>\n\u003Cli>Many-to-many mappings between roles and permissions, and between users and roles.\u003C\u002Fli>\n\u003Cli>Default role assignment on user signup.\u003C\u002Fli>\n\u003Cli>Role-based middleware to protect routes based on required roles.\u003C\u002Fli>\n\u003Cli>A structured API with separated public routes and protected routes.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>As usual, you can checkout the source code on Github here: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fumohsamuel\u002Fauthentication-and-authorization\">umohsamuel\u002Fauthentication-and-authorization\u003C\u002Fa>, play around with it and lmk what you think.\u003C\u002Fp>","June 16, 2026","2026-06-16T01:46:36.303Z","2026-06-16T10:05:30.061Z"]