{"id":21765530,"url":"https://github.com/prasoonsoni/fortisafe","last_synced_at":"2025-10-20T08:04:28.599Z","repository":{"id":183645693,"uuid":"670471088","full_name":"prasoonsoni/FortiSafe","owner":"prasoonsoni","description":"FortiSafe is a secure and efficient resource management platform. The system offers role and group based access control for resources. It features robust user registration and authentication, allowing seamless account deactivation and deletion while adhering to data retention policies. It guards against vulnerabilities like SQL injection attacks.","archived":false,"fork":false,"pushed_at":"2023-07-29T05:12:42.000Z","size":67,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-13T15:08:02.437Z","etag":null,"topics":["aws-rds","docker","docker-compose","gofiber","golang","gorm","jwt","nginx","postgresql","reverse-proxy"],"latest_commit_sha":null,"homepage":"https://documenter.getpostman.com/view/28558819/2s946mZ9Ld","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prasoonsoni.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-07-25T06:09:51.000Z","updated_at":"2024-10-09T10:31:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"3c8918e4-cb3b-4fbc-9c21-5a918c08c8ea","html_url":"https://github.com/prasoonsoni/FortiSafe","commit_stats":null,"previous_names":["prasoonsoni/fortisafe"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasoonsoni%2FFortiSafe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasoonsoni%2FFortiSafe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasoonsoni%2FFortiSafe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prasoonsoni%2FFortiSafe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prasoonsoni","download_url":"https://codeload.github.com/prasoonsoni/FortiSafe/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248732486,"owners_count":21152852,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-rds","docker","docker-compose","gofiber","golang","gorm","jwt","nginx","postgresql","reverse-proxy"],"created_at":"2024-11-26T13:12:53.384Z","updated_at":"2025-10-20T08:04:28.524Z","avatar_url":"https://github.com/prasoonsoni.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n# FortiSafe\n\n## ℹ️ Problem Statement\nBuild a robust containerized task management system to handle user authentication, authorization and access management.\n\n## 📍 Key Features\n- Secure user registration and authentication\n- Account Deactivation and Deletion: Allow users to deactivate or delete their accounts, if applicable. Implement a mechanism to handle account deletion securely while considering data retention policies.\n- Role-based and Group-based access management on resources(Tasks) with ability to create custom roles and groups (Need to make sure endpoints are secure)\n- Protection against vulnerabilities like SQL injection attacks\n- Support for bulk upload using CSV(Both users and tasks) making sure all the relationships are preserved accurately\n\n## ⚙️ Tech Stack \n- **GoLang** - Used for developing efficient and fast server-side applications due to its compiled nature and strong concurrency support.\n- **AWS RDS (PostgreSQL Instance)** - Utilized as a managed database service to provide scalable, reliable, and performant storage for the application.\n- **Docker** - Employed for containerizing the application, ensuring consistency across different environments and facilitating easy deployment and scaling.\n- **Nginx** - Used as a reverse proxy to efficiently handle client requests, load balance, and improve security by serving as a barrier between clients and the application server.\n\n## ⚒️ Go Packages Used\n- **uuid** -  Generates unique identifiers for entities.\n- **jwt** - Creates secure JSON Web Tokens for authentication.\n- **bcrypt** - Hashes and encrypts passwords securely.\n- **gorm** - Simplifies database interactions with an ORM in Go. It also protects from **SQL Injection**.\n- **gofiber** - Fast and efficient web framework for building APIs in Go.\n- **godotenv** - Loads environment variables from a .env file.\n- **postgres** - Robust and scalable relational database management system.\n\n## 🔧 Getting Started\nTo get a local copy up and running follow these simple steps.\n\n### 👉🏻 Prerequisites\nIn order to get a copy of the project and run it locally, you'll need to have Go (v1.15 or later) and Docker installed on your machine.\n\nIf you don't have Go installed, you can download it from the [official Go website](https://go.dev/doc/install). After installation, you can verify it by typing `go version` in your terminal. It should display the installed version of Go.\n\nFor Docker, you can download it from the [official Docker website](https://www.docker.com/products/docker-desktop/). After installation, you can verify it by typing `docker --version` in your terminal. It should display the installed version of Docker.\n\nMake sure you also have a working Docker Compose. Docker Desktop installs Docker Compose by default on Mac and Windows, but you might need to add it separately in some Linux distributions. You can check its availability by typing `docker-compose --version` in your terminal.\n\n### 👉🏻 Get Local Copy\n1. Clone the Repository\n```bash\ngit clone https://github.com/prasoonsoni/FortiSafe\n```\n2. Change the directory\n```bash\ncd FortiSafe\n```\n### 👉🏻 Create Environment Variables\n1. Change the name of `.env.example` to `.env`\n2. Add the following variables to `.env` file\n```env\nDB_HOST = \u003cyour-db-host\u003e\nDB_NAME = \u003cyour-db-name\u003e\nDB_USER = \u003cyour-db-user\u003e\nDB_PASSWORD = \u003cyour-db-password\u003e\nDB_PORT= \u003cyour-db-port\u003e\nJWT_SECRET = \u003cyour-jwt-secret\u003e\nADMIN_EMAIL = \u003cyour-admin-email\u003e\nADMIN_PASSWORD = \u003cyour-admin-password\u003e\n```\n\n\n### 👉🏻 Running the Project\n#### 1. Using Docker\nIn order to test our service we first need to build and run docker-compose. Docker-compose will automate the build and the run of our two Dockerfile.\nTo run this commands you must be in the repository’s root.\n1. Build the Image\n```bash\ndocker-compose build\n```\n2. Start the service\n```bash\ndocker-compose up -d\n```\nNow we have and built the image and service is started for both **go** and **nginx** (used for reverse-proxy).\nThe Nginx reverse proxy will send all request from `localhost/fortisafe/` to Golang service on port `3000`.\n\nBackend is accessible at `http://localhost/fortisafe/`\n\n#### 2. Without Docker\n1. Download the required packages\n```bash\ngo mod download\n```\n2. Run the `main.go`\n```bash\ngo run main.go\n```\n\u003e Note - When running without Docker we don't have access to reverse proxy (nginx) service.\n\nBackend is accessible at `http://localhost:3000/`\n\n\n## 📂 Complete Project Folder Structure\n```\n├── .env\n├── .env.example\n├── .gitignore\n├── docker-compose.yaml\n├── Dockerfile\n├── go.mod\n├── go.sum\n├── main.go\n├── README.md\n│\n├── controllers\n│   ├── groupController.go\n│   ├── permissionController.go\n│   ├── resourceController.go\n│   ├── roleController.go\n│   └── userController.go\n│\n├── db\n│    ├── db.go\n│    └── migrate.go\n│\n├── middlewares\n│   ├── authenticateAdmin.go\n│   └── authenticateUser.go\n│\n├── models\n│   ├── account_status_logs.go\n│   ├── body.go\n│   ├── group.go\n│   ├── permission.go\n│   ├── resource.go\n│   ├── response.go\n│   ├── role.go\n│   ├── role_permission.go\n│   └── user.go\n│\n├── nginx\n│   ├── Dockerfile\n│   └── nginx.conf\n│\n└── routes\n    ├── groupRoutes.go\n    ├── permissionRoutes.go\n    ├── resourceRoutes.go\n    ├── roleRoutes.go\n    └── userRoutes.go\n```\n## 🔐 Pre Configured Permissions\n\u003e Note - These are the basic permissions considered while creating this project.\n1. **create**: This permission allows a user to create new resources or data in the system. \n2. **read**: This permission gives a user the ability to read and retrieve existing resources or data.\n3. **update**: This permission grants a user the ability to modify or update existing resources or data.\n4. **delete**: This permission enables a user to remove existing resources or data from the system.\n\n## 🔦 Basic Workflow\n![architecture](https://github.com/prasoonsoni/FortiSafe/assets/75159757/5a0a1730-8e7a-4b94-a6ea-f2347a2c4b12)\n\n\n## 📖 API References\n[![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/28558819-fbc27156-acd1-40fb-911f-053538bf7dda?action=collection%2Ffork\u0026source=rip_markdown\u0026collection-url=entityId%3D28558819-fbc27156-acd1-40fb-911f-053538bf7dda%26entityType%3Dcollection%26workspaceId%3D7daa153e-aea8-4ce7-a519-f33bbddc43eb)\n[![Postman API Docs](https://img.shields.io/badge/Postman%20API%20Docs-FF6C37?style=for-the-badge\u0026logo=Postman\u0026logoColor=white)](https://documenter.getpostman.com/view/28558819/2s946mZ9Ld)\n\n### User\n\n#### 1. Create User\n\n```http\n  POST /api/user/create\n```\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `name` | `string` |\n| `email` | `string` |\n| `password` | `string` |\n| `role_id` | `string` |\n| `group_id` | `string` |\n\n#### 2. Login User\n\n```http\n  POST /api/user/login\n```\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `email` | `string` |\n| `password` | `string` |\n\n#### 3. Get User\n\n```http\n  GET /api/user/get\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cuser-auth-token\u003e` |\n\n#### 4. Deactivate User\n\n```http\n  PUT /api/user/deactivate\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cuser-auth-token\u003e` |\n\n#### 5. Activate User\n\n```http\n  PUT /api/user/activate\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cyour-auth-token\u003e` |\n\n#### 6. Delete User\n\n```http\n  DELETE /api/user/delete\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cyour-auth-token\u003e` |\n\n#### 7. Bulk Create User\n\n```http\n  POST /api/user/create/bulk\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nForm Data\n| Key | Value     |\n| :-------- | :------- |\n| `users` | `.csv file` |\n\n#### 8. Login Admin\n\n```http\n  POST /api/admin/login\n```\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `email` | `string` |\n| `password` | `string` |\n\n### Permission\n\n#### 1. Create Permission\n\n```http\n  POST /api/permission/create\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `name` | `string` |\n| `description` | `string` |\n\n#### 2. Get All Permissions\n\n```http\n  GET /api/permission/all\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\n### Role\n\n#### 1. Create Role\n\n```http\n  POST /api/role/create\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `name` | `string` |\n| `description` | `string` |\n| `permissions` | `[\u003cpermission-id\u003e, \u003cpermission-id\u003e...]` |\n\n#### 2. Add Permission\n\n```http\n  PUT /api/role/permission/add\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `role_id` | `string` |\n| `permissions` | `[\u003cpermission-id\u003e, \u003cpermission-id\u003e...]` |\n\n#### 3. Get All Roles\n\n```http\n  GET /api/role/get/all\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\n#### 4. Remove Permission\n\n```http\n  DELETE /api/role/permission/remove\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `role_id` | `string` |\n| `permission_id` | `string` |\n\n#### 5. Assign Role\n\n```http\n  PUT /api/role/assign\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `user_id` | `string` |\n| `role_id` | `string` |\n\n#### 6. Unassign Role\n\n```http\n  PUT /api/role/unassign?user_id=\u003cuser-id\u003e\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nQuery Params\n| Parameter | Type     |\n| :-------- | :------- |\n| `user_id` | `string` |\n\n### Resource\n\n#### 1. Create Resource\n\n```http\n  POST /api/resource/create\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cuser-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `name` | `string` |\n| `description` | `string` |\n\n#### 2. Get Resource\n\n```http\n  GET /api/resource/get/:resource_id\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cuser-auth-token\u003e` |\n\nPath Variables\n| Parameter | Type     |\n| :-------- | :------- |\n| `resource_id` | `string` |\n\n#### 3. Update Resource\n\n```http\n  PUT /api/resource/update/:resource_id\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cuser-auth-token\u003e` |\n\nPath Variables\n| Parameter | Type     |\n| :-------- | :------- |\n| `resource_id` | `string` |\n\n#### 4. Delete Resource\n\n```http\n  DELETE /api/resource/delete/:resource_id\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cuser-auth-token\u003e` |\n\nPath Variables\n| Parameter | Type     |\n| :-------- | :------- |\n| `resource_id` | `string` |\n\n#### 5. Add Associated Role\n\n```http\n  PUT /api/resource/role/add\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `resource_id` | `string` |\n| `roles` | `[\u003crole-id\u003e, \u003crole-id\u003e...]` |\n\n#### 6. Remove Associated Role\n\n```http\n  DELETE /api/resource/role/remove\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `resource_id` | `string` |\n| `role_id` | `string` |\n\n#### 7. Bulk Create Resource\n\n```http\n  POST /api/user/create/bulk\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cuser-auth-token\u003e` |\n\nForm Data\n| Key | Value     |\n| :-------- | :------- |\n| `resources` | `.csv file` |\n\n#### 8. Add Associated Group\n\n```http\n  PUT /api/resource/group/add\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `resource_id` | `string` |\n| `groups` | `[\u003cgroup-id\u003e, \u003cgroup-id\u003e...]` |\n\n#### 9. Remove Associated Group\n\n```http\n  DELETE /api/resource/group/remove\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `resource_id` | `string` |\n| `group_id` | `string` |\n\n### Group\n\n#### 1. Create Group\n\n```http\n  POST /api/group/create\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `name` | `string` |\n| `description` | `string` |\n| `permissions` | `[\u003cpermission-id\u003e, \u003cpermission-id\u003e...]` |\n\n#### 2. Add Permission\n\n```http\n  PUT /api/group/permission/add\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `group_id` | `string` |\n| `permissions` | `[\u003cpermission-id\u003e, \u003cpermission-id\u003e...]` |\n\n#### 3. Remove Permission\n\n```http\n  DELETE /api/group/permission/remove\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `group_id` | `string` |\n| `permission_id` | `string` |\n\n#### 4. Assign Group\n\n```http\n  PUT /api/group/assign\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nBody\n| Parameter | Type     |\n| :-------- | :------- |\n| `user_id` | `string` |\n| `group_id` | `string` |\n\n#### 5. Unassign Group\n\n```http\n  PUT /api/group/unassign?user_id=\u003cuser-id\u003e\n```\n\nHeader\n| Key | Value     |\n| :-------- | :------- |\n| `Authorization` | `Bearer \u003cadmin-auth-token\u003e` |\n\nQuery Params\n| Parameter | Type     |\n| :-------- | :------- |\n| `user_id` | `string` |\n\n## 📷 Screenshots\n1. Building Docker Image\n![Building Image](https://github.com/prasoonsoni/FortiSafe/assets/75159757/35d2a7d7-925a-43d8-b806-d36b72432a2b)\n\n2. Running Docker Image\n![Running Docker Image](https://github.com/prasoonsoni/FortiSafe/assets/75159757/cf7bfa58-6e1c-479c-839f-10584317396f)\n\n3. Accessing host using reverse proxy\n![Accessing host using reverse proxy](https://github.com/prasoonsoni/FortiSafe/assets/75159757/5b3368c3-98ac-4201-8fff-0b6a346f2d36)\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprasoonsoni%2Ffortisafe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprasoonsoni%2Ffortisafe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprasoonsoni%2Ffortisafe/lists"}