├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── PULL_REQUEST_TEMPLATE │ └── pull_request.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── branding ├── README.md ├── institute │ └── .gitignore ├── maintainers │ ├── favicon.ico │ ├── logo.png │ ├── logo.svg │ └── wordmark.svg └── site │ ├── favicon.ico │ ├── logo.svg │ ├── logo_192.png │ ├── logo_512.png │ ├── logo_apple.png │ └── wordmark.svg ├── certificates └── .gitignore ├── configuration ├── .gitignore ├── README.md ├── base_stencil.yml └── sites │ └── site_stencil.yml ├── history_dir └── .gitignore ├── media_files └── .gitignore ├── network_storage ├── .gitignore ├── protected │ └── .gitignore └── public │ └── .gitignore ├── omniport ├── .gitignore ├── README.md ├── apps │ └── README.md ├── core │ ├── README.md │ ├── base_auth │ │ ├── __init__.py │ │ ├── admin │ │ │ ├── __init__.py │ │ │ └── models │ │ │ │ ├── __init__.py │ │ │ │ └── user.py │ │ ├── apps.py │ │ ├── backends │ │ │ ├── __init__.py │ │ │ └── generalised.py │ │ ├── http_urls.py │ │ ├── managers │ │ │ ├── __init__.py │ │ │ ├── get_user.py │ │ │ └── user.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_user_institute_security_key.py │ │ │ └── __init__.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ └── user.py │ │ ├── serializers │ │ │ ├── __init__.py │ │ │ ├── reset_password.py │ │ │ ├── retrieve_user.py │ │ │ └── verify_secret_answer.py │ │ └── views │ │ │ ├── __init__.py │ │ │ ├── recover_passowrd.py │ │ │ ├── reset_password.py │ │ │ ├── retrieve_institute_security_key.py │ │ │ ├── verify_institute_security_key.py │ │ │ └── verify_secret_answer.py │ ├── bootstrap │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── http_urls.py │ │ └── views │ │ │ ├── __init__.py │ │ │ └── branding.py │ ├── configuration │ │ ├── __init__.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ ├── app │ │ │ │ ├── __init__.py │ │ │ │ ├── acceptables.py │ │ │ │ ├── app.py │ │ │ │ ├── assets.py │ │ │ │ ├── base_urls.py │ │ │ │ ├── categorisation.py │ │ │ │ └── nomenclature.py │ │ │ └── project │ │ │ │ ├── __init__.py │ │ │ │ ├── allowances.py │ │ │ │ ├── branding.py │ │ │ │ ├── emails.py │ │ │ │ ├── i18n.py │ │ │ │ ├── imagery.py │ │ │ │ ├── ip_address_ring.py │ │ │ │ ├── nomenclature.py │ │ │ │ ├── project.py │ │ │ │ ├── secrets.py │ │ │ │ ├── services.py │ │ │ │ ├── site.py │ │ │ │ └── text.py │ │ ├── serializers │ │ │ ├── __init__.py │ │ │ ├── app │ │ │ │ ├── __init__.py │ │ │ │ ├── app.py │ │ │ │ ├── assets.py │ │ │ │ ├── base_urls.py │ │ │ │ └── nomenclature.py │ │ │ └── project │ │ │ │ ├── __init__.py │ │ │ │ ├── branding.py │ │ │ │ ├── imagery.py │ │ │ │ ├── nomenclature.py │ │ │ │ ├── site.py │ │ │ │ └── text.py │ │ └── utils │ │ │ ├── __init__.py │ │ │ ├── app_config_class.py │ │ │ └── file_search.py │ ├── discovery │ │ ├── __init__.py │ │ ├── available.py │ │ └── discovery.py │ ├── guest_auth │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── http_urls.py │ │ ├── migrations │ │ │ └── __init__.py │ │ ├── utils │ │ │ └── create_guest.py │ │ └── views │ │ │ ├── login.py │ │ │ └── logout.py │ ├── kernel │ │ ├── __init__.py │ │ ├── admin │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ └── model_admins │ │ │ │ ├── __init__.py │ │ │ │ ├── branch.py │ │ │ │ ├── faculty_member.py │ │ │ │ ├── person.py │ │ │ │ └── student.py │ │ ├── apps.py │ │ ├── constants │ │ │ ├── __init__.py │ │ │ ├── biological_information.py │ │ │ └── graduations.py │ │ ├── http_urls.py │ │ ├── management │ │ │ └── commands │ │ │ │ └── collectdaemon.py │ │ ├── managers │ │ │ ├── __init__.py │ │ │ └── get_role.py │ │ ├── migrations │ │ │ ├── 0001_models.py │ │ │ ├── 0002_relationships.py │ │ │ ├── 0003_auto_20191104_0141.py │ │ │ ├── 0004_auto_20200110_1751.py │ │ │ ├── 0004_guest.py │ │ │ ├── 0005_auto_20200110_2246.py │ │ │ ├── 0006_merge_20200111_1752.py │ │ │ ├── 0007_jointfaculty_jointfacultymembership.py │ │ │ ├── 0008_auto_20220206_2015.py │ │ │ ├── 0009_branch_year_count_alter_person_spouses.py │ │ │ ├── 0010_nonteachingstaff.py │ │ │ └── __init__.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ ├── institute │ │ │ │ ├── __init__.py │ │ │ │ ├── branch.py │ │ │ │ ├── centre.py │ │ │ │ ├── course.py │ │ │ │ ├── degree.py │ │ │ │ ├── department.py │ │ │ │ └── residence.py │ │ │ ├── person.py │ │ │ ├── personal_information │ │ │ │ ├── __init__.py │ │ │ │ ├── base.py │ │ │ │ ├── biological_information.py │ │ │ │ ├── financial_information.py │ │ │ │ ├── political_information.py │ │ │ │ └── residential_information.py │ │ │ └── roles │ │ │ │ ├── __init__.py │ │ │ │ ├── base.py │ │ │ │ ├── faculty_member.py │ │ │ │ ├── guest_role.py │ │ │ │ ├── joint_faculty.py │ │ │ │ ├── maintainer.py │ │ │ │ ├── nonteaching_staff.py │ │ │ │ └── student.py │ │ ├── permissions │ │ │ ├── __init__.py │ │ │ ├── alohomora.py │ │ │ ├── has_role.py │ │ │ ├── helpcentre.py │ │ │ ├── omnipotence.py │ │ │ └── polyjuice.py │ │ ├── relations │ │ │ ├── __init__.py │ │ │ └── person.py │ │ ├── serializers │ │ │ ├── __init__.py │ │ │ ├── institute │ │ │ │ ├── branch.py │ │ │ │ ├── degree.py │ │ │ │ ├── department.py │ │ │ │ └── residence.py │ │ │ ├── person.py │ │ │ ├── personal_information │ │ │ │ ├── __init__.py │ │ │ │ ├── biological_information.py │ │ │ │ ├── financial_information.py │ │ │ │ ├── political_information.py │ │ │ │ └── residential_information.py │ │ │ ├── registration.py │ │ │ └── roles │ │ │ │ ├── __init__.py │ │ │ │ ├── base.py │ │ │ │ ├── faculty_member.py │ │ │ │ ├── guest.py │ │ │ │ ├── joint_faculty.py │ │ │ │ ├── maintainer.py │ │ │ │ └── student.py │ │ ├── supervisor.d │ │ │ ├── .gitignore │ │ │ └── celery.conf │ │ ├── utils │ │ │ ├── __init__.py │ │ │ ├── logs.py │ │ │ └── rights.py │ │ └── views │ │ │ ├── __init__.py │ │ │ ├── rights.py │ │ │ └── who_am_i.py │ ├── open_auth │ │ ├── __init__.py │ │ ├── apps.py │ │ ├── constants │ │ │ ├── __init__.py │ │ │ └── data_points.py │ │ ├── http_urls.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20211016_0005.py │ │ │ ├── 0003_alter_application_data_points.py │ │ │ └── __init__.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ └── application.py │ │ ├── serializers │ │ │ ├── __init__.py │ │ │ └── application.py │ │ ├── signals │ │ │ ├── __init__.py │ │ │ └── app_authorisation.py │ │ ├── utils.py │ │ └── views │ │ │ ├── __init__.py │ │ │ ├── application.py │ │ │ └── retrieve_data.py │ ├── session_auth │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── constants │ │ │ ├── __init__.py │ │ │ └── device_types.py │ │ ├── http_urls.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_alter_sessionmap_user_agent.py │ │ │ └── __init__.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ └── session_map.py │ │ ├── serializers │ │ │ ├── __init__.py │ │ │ └── login.py │ │ ├── utils │ │ │ ├── __init__.py │ │ │ ├── ip_address.py │ │ │ └── user_agent.py │ │ └── views │ │ │ ├── __init__.py │ │ │ ├── illustration_roulette.py │ │ │ ├── login.py │ │ │ └── logout.py │ ├── token_auth │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── authentication │ │ │ ├── __init__.py │ │ │ └── app_access_token_authentication.py │ │ ├── constants.py │ │ ├── http_urls.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ └── app_access_token.py │ │ ├── permission │ │ │ ├── __init__.py │ │ │ └── app_access_token.py │ │ └── views.py │ └── utils │ │ ├── __init__.py │ │ ├── logs.py │ │ └── slack.py ├── manage.py ├── omniport │ ├── __init__.py │ ├── admin │ │ ├── __init__.py │ │ └── site.py │ ├── asgi │ │ ├── __init__.py │ │ └── asgi.py │ ├── celery │ │ ├── __init__.py │ │ └── celery.py │ ├── context │ │ ├── __init__.py │ │ └── branding.py │ ├── middleware │ │ ├── __init__.py │ │ ├── drf_auth.py │ │ ├── ip_address_rings.py │ │ ├── last_seen.py │ │ ├── person_roles.py │ │ ├── routes_control.py │ │ └── routes_control_roles.py │ ├── routing │ │ ├── __init__.py │ │ └── routing.py │ ├── settings │ │ ├── __init__.py │ │ ├── base │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ ├── applications.py │ │ │ ├── authentication.py │ │ │ ├── directories.py │ │ │ ├── discovery.py │ │ │ ├── files.py │ │ │ ├── middleware.py │ │ │ ├── models.py │ │ │ ├── security.py │ │ │ ├── shell.py │ │ │ └── templates.py │ │ ├── configuration │ │ │ ├── __init__.py │ │ │ ├── allowances.py │ │ │ ├── base.py │ │ │ ├── branding.py │ │ │ ├── emails.py │ │ │ ├── i18n.py │ │ │ ├── integrations.py │ │ │ ├── logging.py │ │ │ ├── secrets.py │ │ │ ├── services.py │ │ │ └── site.py │ │ ├── settings.py │ │ └── third_party │ │ │ ├── __init__.py │ │ │ ├── celery.py │ │ │ ├── cors.py │ │ │ ├── drf.py │ │ │ ├── guardian.py │ │ │ ├── jwt.py │ │ │ ├── mptt.py │ │ │ └── tinymce.py │ ├── static │ │ ├── @fullcalendar │ │ │ ├── common.main.css │ │ │ ├── daygrid.main.css │ │ │ ├── list.main.css │ │ │ ├── semantic.fullCalendar.css │ │ │ └── timegrid.main.css │ │ ├── errors │ │ │ ├── confetti_green.svg │ │ │ ├── confetti_pink.svg │ │ │ ├── confetti_yellow.svg │ │ │ ├── dart.svg │ │ │ ├── dart_stuck.svg │ │ │ ├── dartboard.svg │ │ │ ├── person.svg │ │ │ ├── person_stressed.svg │ │ │ └── rabbit.svg │ │ ├── illustrations │ │ │ ├── 0.svg │ │ │ ├── 1.svg │ │ │ ├── 2.svg │ │ │ ├── 3.svg │ │ │ └── 4.svg │ │ ├── jquery │ │ │ └── jquery.min.js │ │ ├── omniport │ │ │ └── css │ │ │ │ ├── layout.css │ │ │ │ └── styling.css │ │ ├── pure-react-carousel │ │ │ ├── react-carousel.es.css │ │ │ └── react-carousel.es.css.map │ │ ├── react-semantic-toasts │ │ │ └── react-semantic-alert.css │ │ └── semantic-ui │ │ │ ├── semantic.fix.css │ │ │ ├── semantic.min.css │ │ │ ├── semantic.min.js │ │ │ └── themes │ │ │ └── default │ │ │ └── assets │ │ │ ├── fonts │ │ │ ├── brand-icons.eot │ │ │ ├── brand-icons.svg │ │ │ ├── brand-icons.ttf │ │ │ ├── brand-icons.woff │ │ │ ├── brand-icons.woff2 │ │ │ ├── icons.eot │ │ │ ├── icons.otf │ │ │ ├── icons.svg │ │ │ ├── icons.ttf │ │ │ ├── icons.woff │ │ │ ├── icons.woff2 │ │ │ ├── outline-icons.eot │ │ │ ├── outline-icons.svg │ │ │ ├── outline-icons.ttf │ │ │ ├── outline-icons.woff │ │ │ └── outline-icons.woff2 │ │ │ └── images │ │ │ └── flags.png │ ├── templates │ │ ├── 404.html │ │ ├── 500.html │ │ ├── base.html │ │ └── maintenance.html │ ├── urls │ │ ├── __init__.py │ │ ├── http_urls.py │ │ ├── urls.py │ │ └── ws_urls.py │ ├── utils │ │ ├── __init__.py │ │ └── switcher.py │ └── wsgi │ │ ├── __init__.py │ │ └── wsgi.py ├── services │ └── README.md └── templates │ ├── admin │ ├── base.html │ └── change_form.html │ └── rest_framework │ └── api.html ├── personal_files └── .gitignore ├── poetry.lock ├── pyproject.toml ├── readme-assets ├── maintainers │ └── wordmark.svg └── site │ └── wordmark.svg ├── scripts ├── clone │ ├── everything.sh │ ├── formula_one.sh │ ├── services.sh │ ├── shell.sh │ └── utils.sh ├── create │ └── app.sh └── start │ └── django.sh ├── static_files └── .gitignore ├── supervisor.d └── .gitignore └── web_server_logs ├── .gitignore └── server_logs └── .gitignore /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 13 | **Expected behavior** 14 | A clear and concise description of what you expected to happen. 15 | 16 | **Screenshots** 17 | If applicable, add screenshots to help explain your problem. 18 | 19 | **Operating System:** 20 | - OS: [e.g. iOS] 21 | - Browser [e.g. chrome, safari] 22 | - Version [e.g. 22] 23 | 24 | **Additional context** 25 | Add any other context about the problem here. 26 | 27 | **Want to take up?** 28 | Are you interested in and capable of tackling this issue? [yes|no] 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | 19 | **Want to take up?** 20 | Are you interested in and capable of tackling this issue? [yes|no] 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/pull_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Pull request 3 | about: Submit a patch to help us improve 4 | title: '' 5 | --- 6 | 7 | **Description** 8 | What does this PR achieve? [feature|hotfix|refactor] 9 | 10 | **Fixes** 11 | Issue # by @ 12 | 13 | **Technical** 14 | Notable details about the implementation. 15 | 16 | **Testing** 17 | Steps for the reviewer to verify that this PR fixes the problem: 18 | 19 | **Evidence** 20 | If applicable, add screenshots to show the problem and the solution. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ configuration 2 | .idea/ 3 | 4 | # VSCode configuration 5 | .vscode/ 6 | 7 | # macOS files 8 | .DS_Store 9 | 10 | # Collected static files 11 | static_files/ 12 | 13 | # User loaded media files 14 | media_files/ 15 | 16 | # Network storage files 17 | network_storage/ 18 | 19 | # Personal files of users 20 | personal_files/ 21 | 22 | # Web server logs 23 | web_server_logs/ 24 | 25 | # History directory 26 | history_dir/ 27 | 28 | # Certificates for remote services 29 | certificates/ 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | > The backend of the one true portal for any and every educational institute 4 | 5 | ## Backend 6 | 7 | This is the backend of Omniport. 8 | 9 | ## Technological stack 10 | 11 | - Language: `Python` 12 | - Framework: `Django` 13 | - API Framework: `Django REST framework` 14 | - Server: `Gunicorn + Daphne` 15 | - WS Routing: `Channels` 16 | - Other noteworthy packages: `Django OAuth Toolkit`, `Swapper` 17 | 18 | A Dockerised setup is the preferred mode of installation. One such is provided 19 | by us on our GitHub account. You can however set all the components up yourself, 20 | after suffering a reasonable amount of headbanging, cursing, and physical and 21 | mental pain. 22 | 23 | This can be found at `https://github.com/IMGIITRoorkee/omniport-docker`. 24 | 25 | ## Contribution guidelines 26 | 27 | - Fork the repository to your account. 28 | - Branch out to `a_meaningful_branch_name`. 29 | - Send in a `WIP: Pull request`. 30 | - Commit your changes. 31 | - Add your name to `CONTRIBUTORS.md`. 32 | - Get your pull request merged. 33 | 34 | It's that simple! 35 | 36 | ## Credits 37 | 38 | 39 | -------------------------------------------------------------------------------- /branding/institute/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all branding imagery for institute 2 | favicon.ico 3 | logo.* 4 | wordmark.* -------------------------------------------------------------------------------- /branding/maintainers/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/branding/maintainers/favicon.ico -------------------------------------------------------------------------------- /branding/maintainers/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/branding/maintainers/logo.png -------------------------------------------------------------------------------- /branding/maintainers/logo.svg: -------------------------------------------------------------------------------- 1 | img_logo -------------------------------------------------------------------------------- /branding/site/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/branding/site/favicon.ico -------------------------------------------------------------------------------- /branding/site/logo.svg: -------------------------------------------------------------------------------- 1 | op_logo -------------------------------------------------------------------------------- /branding/site/logo_192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/branding/site/logo_192.png -------------------------------------------------------------------------------- /branding/site/logo_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/branding/site/logo_512.png -------------------------------------------------------------------------------- /branding/site/logo_apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/branding/site/logo_apple.png -------------------------------------------------------------------------------- /certificates/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /configuration/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the base configuration YAML file 2 | base.yml 3 | 4 | # Ignore every site-specific configuration YAML file 5 | sites/site_[0-9].yml -------------------------------------------------------------------------------- /configuration/README.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | The Omniport project loads all settings from YAML configuration files. On a Dockerised distribution, the `docker-compose.yml` file takes care of loading the set of these configuration files into the Django container from this directory. 4 | 5 | ## Instructions 6 | 7 | - Use the YAML stencil `base_stencil.yml` to create `base.yml`. 8 | - Go to the `sites` folder. 9 | - For as many sites as you are deploying (plus the development site), use the YAML stencil `site_stencil.yml` to create `site_.yml`. 10 | - In this specific case the following site IDs are being followed. 11 | - **Site ID 0:** the development site launched by the run script 12 | - **Site ID 1:** the Intranet facing site 13 | - **Site ID 2:** the Internet facing site -------------------------------------------------------------------------------- /configuration/sites/site_stencil.yml: -------------------------------------------------------------------------------- 1 | site: 2 | id: # A unique numeric ID for the site 3 | nomenclature: 4 | name: # A code name for the site 5 | verboseName: # A verbose punctuated name for the site 6 | tagline: # A tagline for the site 7 | debug: # Boolean that decides whether the site is in production or development 8 | description: # String that describes the site 9 | allowances: 10 | hosts: 11 | # For as many hostnames that point to this site, repeat 12 | - # The domain name that this site should serve to 13 | - # Other domain name/+s to which this site can be accessed 14 | apps: 15 | # For all the apps that are allowed to be served on this site, repeat 16 | - # The code name of the app that should be allowed 17 | ipAddressRings: 18 | # For all the network rings that this site serves, repeat 19 | - # The name of the rings from base.yml that fall in the purview of this site 20 | -------------------------------------------------------------------------------- /history_dir/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/history_dir/.gitignore -------------------------------------------------------------------------------- /media_files/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/media_files/.gitignore -------------------------------------------------------------------------------- /network_storage/.gitignore: -------------------------------------------------------------------------------- 1 | i# Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /network_storage/protected/.gitignore: -------------------------------------------------------------------------------- 1 | i# Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /network_storage/public/.gitignore: -------------------------------------------------------------------------------- 1 | i# Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /omniport/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled .pyc files 2 | __pycache__/ 3 | 4 | # Ignore apps ... 5 | apps/* 6 | # ... but commit the README.md file so that the folder gets created 7 | !apps/README.md 8 | 9 | # Ignore services ... 10 | services/* 11 | # ... but commit the README.md file so that the folder gets created 12 | !services/README.md 13 | 14 | # Ignore Formula 1 15 | formula_one/ 16 | 17 | # Ignore shell 18 | shell/ -------------------------------------------------------------------------------- /omniport/README.md: -------------------------------------------------------------------------------- 1 | # Omniport 2 | 3 | ## Instructions 4 | -------------------------------------------------------------------------------- /omniport/apps/README.md: -------------------------------------------------------------------------------- 1 | # Apps 2 | 3 | > A collection of plug-and-play apps that can easily fit into Omniport 4 | 5 | Omniport is designed to simplify app installation to the point of simply adding 6 | said app to a designated folder. This is that folder, `apps/`. 7 | 8 | Drop your Omniport-compliant apps into this folder, sit back, relax and let 9 | Omniport take care of the rest. 10 | -------------------------------------------------------------------------------- /omniport/core/README.md: -------------------------------------------------------------------------------- 1 | # Core 2 | 3 | > A collection of the core functionality that makes Omniport what it is 4 | 5 | Omniport keeps various critically essential but typically disjoint functionality 6 | separated as separate packages. This is that collection, `core`. 7 | 8 | Note that the `core` is not to be altered in any way, unlike apps which 9 | and services which are discovered and configured based on your setup. -------------------------------------------------------------------------------- /omniport/core/base_auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/base_auth/__init__.py -------------------------------------------------------------------------------- /omniport/core/base_auth/admin/__init__.py: -------------------------------------------------------------------------------- 1 | from base_auth.admin.models.user import UserAdmin 2 | from base_auth.models import User 3 | from omniport.admin.site import omnipotence 4 | 5 | omnipotence.register(User, UserAdmin) 6 | -------------------------------------------------------------------------------- /omniport/core/base_auth/admin/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/base_auth/admin/models/__init__.py -------------------------------------------------------------------------------- /omniport/core/base_auth/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BaseAuthConfig(AppConfig): 5 | name = 'base_auth' 6 | verbose_name = 'Base authentication' 7 | -------------------------------------------------------------------------------- /omniport/core/base_auth/backends/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/base_auth/backends/__init__.py -------------------------------------------------------------------------------- /omniport/core/base_auth/http_urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from base_auth.views.reset_password import ResetPassword 4 | from base_auth.views.verify_secret_answer import VerifySecretAnswer 5 | from base_auth.views.recover_passowrd import RecoverPassword, VerifyRecoveryToken 6 | from base_auth.views.verify_institute_security_key import VerifyInstituteSecurityKey 7 | from base_auth.views.retrieve_institute_security_key import RetrieveInstituteSecurityKey 8 | app_name = 'base_auth' 9 | 10 | urlpatterns = [ 11 | path( 12 | 'verify_secret_answer/', 13 | VerifySecretAnswer.as_view(), 14 | name='verify_secret_answer' 15 | ), 16 | path( 17 | 'reset_password/', 18 | ResetPassword.as_view(), 19 | name='reset_password' 20 | ), 21 | path( 22 | 'recover_password/', 23 | RecoverPassword.as_view(), 24 | name='password recovery' 25 | ), 26 | path( 27 | 'verify/', 28 | VerifyRecoveryToken.as_view(), 29 | name='verify_recovery_token' 30 | ), 31 | path( 32 | 'verify_institute_security_key/', 33 | VerifyInstituteSecurityKey.as_view(), 34 | name='verify_institute_security_key' 35 | ), 36 | path( 37 | 'retrieve_institute_security_key/', 38 | RetrieveInstituteSecurityKey.as_view(), 39 | name='retrieve_institute_security_key' 40 | ), 41 | ] 42 | -------------------------------------------------------------------------------- /omniport/core/base_auth/managers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/base_auth/managers/__init__.py -------------------------------------------------------------------------------- /omniport/core/base_auth/managers/user.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import models as auth_models 2 | 3 | 4 | class UserManager(auth_models.BaseUserManager): 5 | """ 6 | This is the manager for objects of class AuthUser 7 | """ 8 | 9 | def _create_instance(self, username, password, is_superuser): 10 | """ 11 | Create a user with the given password 12 | Both standard and administrative users are identical at this level 13 | :param username: the username for the user 14 | :param password: the password for the user 15 | :return: the newly created user 16 | """ 17 | 18 | if not password: 19 | raise ValueError('Password is required') 20 | user = self.model( 21 | username=username, 22 | is_superuser=is_superuser, 23 | ) 24 | user.set_password(password) 25 | user.save() 26 | return user 27 | 28 | def create_user(self, username='', password=None): 29 | """ 30 | Create a standard user with the given password 31 | :param username: the username for the standard user 32 | :param password: the password for the standard user 33 | :return: the newly created standard user 34 | """ 35 | 36 | return self._create_instance( 37 | username=username, 38 | password=password, 39 | is_superuser=False 40 | ) 41 | 42 | def create_superuser(self, username='', password=None): 43 | """ 44 | Create an administrative user with the given password 45 | :param username: the username that will be ignored 46 | :param password: the password for the administrative user 47 | :return: the newly created administrative user 48 | """ 49 | 50 | return self._create_instance( 51 | username=username, 52 | password=password, 53 | is_superuser=True 54 | ) 55 | -------------------------------------------------------------------------------- /omniport/core/base_auth/migrations/0002_user_institute_security_key.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.3 on 2021-10-06 04:55 2 | 3 | from django.db import migrations, models 4 | import uuid 5 | 6 | from base_auth.models import User 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('base_auth', '0001_initial'), 12 | ] 13 | 14 | def generate_institute_security_key(apps, schema_editor): 15 | """ 16 | Helper function to generate unique institute security keys while 17 | migrations 18 | """ 19 | for user in User.objects.all(): 20 | user.institute_security_key = uuid.uuid4() 21 | user.save() 22 | 23 | operations = [ 24 | migrations.AddField( 25 | model_name='user', 26 | name='institute_security_key', 27 | field=models.CharField(default=uuid.uuid4, blank=False, max_length=255, null=False), 28 | preserve_default=True 29 | ), 30 | migrations.RunPython( 31 | code=generate_institute_security_key, 32 | reverse_code=migrations.RunPython.noop, 33 | ), 34 | migrations.AlterField( 35 | model_name='user', 36 | name='institute_security_key', 37 | field=models.CharField(default=uuid.uuid4, blank=False, max_length=255, null=False, unique=True), 38 | ), 39 | ] 40 | -------------------------------------------------------------------------------- /omniport/core/base_auth/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/base_auth/migrations/__init__.py -------------------------------------------------------------------------------- /omniport/core/base_auth/models/__init__.py: -------------------------------------------------------------------------------- 1 | from base_auth.models.user import User 2 | -------------------------------------------------------------------------------- /omniport/core/base_auth/serializers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/base_auth/serializers/__init__.py -------------------------------------------------------------------------------- /omniport/core/base_auth/serializers/reset_password.py: -------------------------------------------------------------------------------- 1 | 2 | from rest_framework import serializers 3 | 4 | from base_auth.serializers.retrieve_user import RetrieveUserSerializer 5 | from core.utils.logs import get_logging_function 6 | 7 | 8 | base_auth_log = get_logging_function('base_auth') 9 | 10 | 11 | class ResetPasswordSerializer(RetrieveUserSerializer): 12 | """ 13 | Stores the secret answer and the new password for changing it 14 | """ 15 | 16 | secret_answer = serializers.CharField() 17 | new_password = serializers.CharField() 18 | 19 | def validate_secret_answer(self, secret_answer): 20 | """ 21 | Validate the secret answer by comparing it with the stored answer 22 | :param secret_answer: the secret answer to check for correctness 23 | :return: the secret answer if it is correct 24 | :raise serializers.ValidationError: if the secret answer is wrong 25 | """ 26 | 27 | if self.user.failed_reset_attempts >= 3: 28 | base_auth_log( 29 | 'Password reset attempts exceeded limit', 30 | 'warning', 31 | self.user 32 | ) 33 | raise serializers.ValidationError('Reset attempts exceeded limit.') 34 | 35 | if not self.user.check_secret_answer(secret_answer): 36 | user = self.user 37 | user.failed_reset_attempts = user.failed_reset_attempts + 1 38 | user.save() 39 | raise serializers.ValidationError( 40 | 'Incorrect credentials. ' 41 | f'Attempts left: {3 - user.failed_reset_attempts}' 42 | ) 43 | 44 | return secret_answer 45 | -------------------------------------------------------------------------------- /omniport/core/base_auth/serializers/retrieve_user.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | from base_auth.managers.get_user import get_user 4 | from base_auth.models import User 5 | 6 | 7 | class RetrieveUserSerializer(serializers.Serializer): 8 | """ 9 | Stores an instance of User with the given username 10 | """ 11 | 12 | user = None 13 | username = serializers.CharField() 14 | 15 | def validate_username(self, username): 16 | """ 17 | Validates the username by seeing if any User object matches it 18 | :param username: the username whose existence is being checked 19 | :return: the username after validation 20 | :raise serializers.ValidationError: if no user has the given username 21 | """ 22 | 23 | try: 24 | user = get_user(username=username) 25 | self.user = user 26 | except User.DoesNotExist: 27 | raise serializers.ValidationError('Username does not exist.') 28 | 29 | return username 30 | -------------------------------------------------------------------------------- /omniport/core/base_auth/serializers/verify_secret_answer.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | from base_auth.serializers.retrieve_user import RetrieveUserSerializer 4 | 5 | 6 | class VerifySecretAnswerSerializer(RetrieveUserSerializer): 7 | """ 8 | Stores the secret answer and the new password for changing it 9 | """ 10 | 11 | secret_answer = serializers.CharField() 12 | 13 | def validate_secret_answer(self, secret_answer): 14 | """ 15 | Validate the secret answer by comparing it with the stored answer 16 | :param secret_answer: the secret answer to check for correctness 17 | :return: the secret answer if it is correct 18 | :raise serializers.ValidationError: if the secret answer is wrong 19 | """ 20 | 21 | if self.user.failed_reset_attempts >= 3: 22 | raise serializers.ValidationError('Reset attempts exceeded limit.') 23 | 24 | if not self.user.check_secret_answer(secret_answer): 25 | user = self.user 26 | user.failed_reset_attempts = user.failed_reset_attempts + 1 27 | user.save() 28 | raise serializers.ValidationError( 29 | 'Incorrect credentials. ' 30 | f'Attempts left: {3 - user.failed_reset_attempts}' 31 | ) 32 | 33 | return secret_answer 34 | -------------------------------------------------------------------------------- /omniport/core/base_auth/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/base_auth/views/__init__.py -------------------------------------------------------------------------------- /omniport/core/base_auth/views/reset_password.py: -------------------------------------------------------------------------------- 1 | from rest_framework import status, generics, response 2 | 3 | from base_auth.serializers.reset_password import ( 4 | ResetPasswordSerializer, 5 | ) 6 | from core.utils.logs import get_logging_function 7 | 8 | 9 | base_auth_log = get_logging_function('base_auth') 10 | 11 | 12 | class ResetPassword(generics.GenericAPIView): 13 | """ 14 | This view, when responding to a GET request, shows the secret question for 15 | the user in question and, when responding to a POST request, takes the 16 | username, the secret_answer and the new password to reset it 17 | """ 18 | 19 | serializer_class = ResetPasswordSerializer 20 | 21 | def post(self, request, *args, **kwargs): 22 | """ 23 | View to serve POST requests 24 | :param request: the request that is to be responded to 25 | :param args: arguments 26 | :param kwargs: keyword arguments 27 | :return: the response for request 28 | """ 29 | 30 | serializer = self.get_serializer(data=request.data) 31 | if serializer.is_valid(): 32 | user = serializer.user 33 | new_password = serializer.validated_data.get('new_password') 34 | user.set_password(new_password) 35 | user.failed_reset_attempts = 0 36 | user.save() 37 | response_data = { 38 | 'status': 'Successfully reset password.', 39 | } 40 | base_auth_log('Successfully reset password', 'info', user) 41 | return response.Response( 42 | data=response_data, 43 | status=status.HTTP_200_OK 44 | ) 45 | else: 46 | response_data = { 47 | 'errors': serializer.errors, 48 | } 49 | return response.Response( 50 | data=response_data, 51 | status=status.HTTP_400_BAD_REQUEST 52 | ) -------------------------------------------------------------------------------- /omniport/core/bootstrap/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/bootstrap/__init__.py -------------------------------------------------------------------------------- /omniport/core/bootstrap/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BootstrapConfig(AppConfig): 5 | name = 'bootstrap' 6 | -------------------------------------------------------------------------------- /omniport/core/bootstrap/http_urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from bootstrap.views.branding import ( 4 | SiteBrandingView, 5 | InstituteBrandingView, 6 | MaintainersBrandingView, 7 | ) 8 | 9 | app_name = 'bootstrap' 10 | 11 | urlpatterns = [ 12 | path('site_branding/', 13 | SiteBrandingView.as_view(), 14 | name='site_branding'), 15 | path('institute_branding/', 16 | InstituteBrandingView.as_view(), 17 | name='institute_branding'), 18 | path('maintainers_branding/', 19 | MaintainersBrandingView.as_view(), 20 | name='maintainers_branding'), 21 | ] 22 | -------------------------------------------------------------------------------- /omniport/core/bootstrap/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/bootstrap/views/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/configuration/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/configuration/models/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/models/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/configuration/models/app/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/models/app/acceptables.py: -------------------------------------------------------------------------------- 1 | from formula_one.enums.active_status import ActiveStatus 2 | 3 | 4 | class Role: 5 | """ 6 | This class stores information about the roles acceptable to an app, namely 7 | the role name and the active statuses of the said role 8 | """ 9 | 10 | def __init__(self, *args, **kwargs): 11 | """ 12 | Create a Role instance from a dictionary 13 | :param args: arguments 14 | :param kwargs: keyword arguments, including 'dictionary' 15 | """ 16 | 17 | super().__init__() 18 | 19 | dictionary = kwargs.get('dictionary') or dict() 20 | self.name = dictionary.get('name') 21 | 22 | active_statuses = dictionary.get('activeStatuses') 23 | if active_statuses is None: 24 | self.active_status = ActiveStatus.ANY 25 | else: 26 | self.active_status = ActiveStatus.NONE 27 | for active_status in active_statuses: 28 | self.active_status |= ActiveStatus[active_status] # Enum OR 29 | 30 | 31 | class Acceptables: 32 | """ 33 | This class stores information about an app's acceptables, namely the 34 | acceptable roles and the acceptable IP address rings 35 | """ 36 | 37 | def __init__(self, *args, **kwargs): 38 | """ 39 | Create an Acceptables instance from a dictionary 40 | :param args: arguments 41 | :param kwargs: keyword arguments, including 'dictionary' 42 | """ 43 | 44 | super().__init__() 45 | 46 | dictionary = kwargs.get('dictionary') or dict() 47 | self.roles = [ 48 | Role( 49 | dictionary=role 50 | ) 51 | for role in dictionary.get('roles') or [] 52 | ] 53 | self.ip_address_rings = dictionary.get('ipAddressRings') 54 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/app/app.py: -------------------------------------------------------------------------------- 1 | from configuration.models.app.acceptables import Acceptables 2 | from configuration.models.app.base_urls import BaseUrls 3 | from configuration.models.app.nomenclature import Nomenclature 4 | from configuration.models.app.categorisation import Categorisation 5 | 6 | 7 | class AppConfiguration: 8 | """ 9 | This class stores configuration for an app in the form of an object, 10 | encapsulating load-time checks 11 | """ 12 | 13 | def __init__(self, *args, **kwargs): 14 | """ 15 | Parse the dictionaries generated from YAML files into a class-object 16 | representation 17 | :param args: arguments 18 | :param kwargs: keyword arguments, includes 'dictionary' 19 | """ 20 | 21 | super().__init__() 22 | 23 | dictionary = kwargs.get('dictionary') or dict() 24 | 25 | self.nomenclature = Nomenclature( 26 | dictionary=dictionary.get('nomenclature') 27 | ) 28 | self.is_api = dictionary.get('isApi') or False 29 | self.description = dictionary.get('description') 30 | self.base_urls = BaseUrls( 31 | dictionary=dictionary.get('baseUrls') 32 | ) 33 | self.acceptables = Acceptables( 34 | dictionary=dictionary.get('acceptables') 35 | ) 36 | 37 | self.categorisation = Categorisation( 38 | list=dictionary.get('categorisation') 39 | ) 40 | self.guest_allowed = dictionary.get('guestAllowed') or False 41 | 42 | self.excluded_paths = [] 43 | excluded_paths = dictionary.get('excludedPaths') 44 | 45 | if excluded_paths is not None: 46 | for path in excluded_paths: 47 | self.excluded_paths.append(path) 48 | 49 | # Processed variables 50 | self.is_allowed = None 51 | self.has_static = None 52 | self.assets = None 53 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/app/assets.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from configuration.utils.file_search import file_search 4 | 5 | 6 | class Assets: 7 | """ 8 | This class stores information about an app's assets, namely the the path to 9 | various image files 10 | """ 11 | 12 | def __init__(self, *args, **kwargs): 13 | """ 14 | Create an instance of Assets from a directory 15 | :param args: arguments 16 | :param kwargs: keyword arguments, includes 'directory' 17 | """ 18 | 19 | super().__init__() 20 | 21 | directory = kwargs.get('directory') 22 | contents = os.listdir(directory) 23 | 24 | self.favicon = file_search(contents, 25 | 'favicon', ['.ico']) 26 | self.icon = file_search(contents, 27 | 'icon', ['.svg', '.png', '.jpg']) 28 | self.logo = file_search(contents, 29 | 'logo', ['.svg', '.png', '.jpg']) 30 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/app/base_urls.py: -------------------------------------------------------------------------------- 1 | class BaseUrls: 2 | """ 3 | This class stores information about an app's URL dispatcher configuration, 4 | namely the base URLs for http and ws protocols 5 | """ 6 | 7 | def __init__(self, *args, **kwargs): 8 | """ 9 | Create a BaseUrls instance from a dictionary 10 | :param args: arguments 11 | :param kwargs: keyword arguments, including 'dictionary' 12 | """ 13 | 14 | super().__init__() 15 | 16 | dictionary = kwargs.get('dictionary') or dict() 17 | self.http = dictionary.get('http') 18 | self.ws = dictionary.get('ws') 19 | self.static = dictionary.get('static') 20 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/app/categorisation.py: -------------------------------------------------------------------------------- 1 | class Categorisation: 2 | """ 3 | This class stores information about the category tree 4 | """ 5 | 6 | def __init__(self, *args, **kwargs): 7 | """ 8 | Parse the dictionaries generated from YAML files into a class-object 9 | representation 10 | :param args: arguments 11 | :param kwargs: keyword arguments, includes 'dictionary' 12 | """ 13 | 14 | category_list = kwargs.get('list') or list() 15 | self.categories = [ 16 | Category( 17 | dictionary=category 18 | ) 19 | for category in category_list 20 | ] 21 | 22 | 23 | class Category: 24 | """ 25 | This class stores information about a category, namely its name, slug 26 | and subcategories 27 | """ 28 | 29 | def __init__(self, *args, **kwargs): 30 | 31 | dictionary = kwargs.get('dictionary') or dict() 32 | self.name = dictionary.get('name') 33 | self.slug = dictionary.get('slug') 34 | self.categories = [ 35 | Category( 36 | dictionary=category 37 | ) 38 | for category in dictionary.get('categories') or [] 39 | ] 40 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/app/nomenclature.py: -------------------------------------------------------------------------------- 1 | class Nomenclature: 2 | """ 3 | This class stores information about an app's nomenclature, namely the code 4 | name and verbose name 5 | """ 6 | 7 | def __init__(self, *args, **kwargs): 8 | """ 9 | Create a Nomenclature instance, from a dictionary 10 | :param args: arguments 11 | :param kwargs: keyword arguments, including 'dictionary' 12 | """ 13 | 14 | super().__init__() 15 | 16 | dictionary = kwargs.get('dictionary') or dict() 17 | self.name = dictionary.get('name') 18 | self.verbose_name = dictionary.get('verboseName') 19 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/configuration/models/project/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/allowances.py: -------------------------------------------------------------------------------- 1 | class Allowances: 2 | """ 3 | This class stores information about a site's allowances, namely the hosts, 4 | apps and IP address rings 5 | """ 6 | 7 | def __init__(self, *args, **kwargs): 8 | """ 9 | Create an instance of Allowances from a dictionary 10 | :param args: arguments 11 | :param kwargs: keyword arguments, including 'dictionary' 12 | """ 13 | 14 | super().__init__() 15 | 16 | dictionary = kwargs.get('dictionary') or dict() 17 | self.hosts = dictionary.get('hosts') or ['*'] 18 | self.apps = dictionary.get('apps') or '__all__' 19 | self.ip_address_rings = dictionary.get('ipAddressRings') or '__all__' 20 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/emails.py: -------------------------------------------------------------------------------- 1 | class Emails: 2 | """ 3 | This class stores the configuration requirements for the email service to work 4 | """ 5 | 6 | def __init__(self, *args, **kwargs): 7 | """ 8 | Create an instance of Secrets from a dictionary 9 | :param args: arguments 10 | :param kwargs: keyword arguments, includes 'dictionary' 11 | """ 12 | 13 | super().__init__() 14 | 15 | dictionary = kwargs.get('dictionary') or dict() 16 | self.email_backend = dictionary.get('emailBackend') 17 | self.email_host = dictionary.get('emailHost') 18 | self.email_use_tls = dictionary.get('emailUseTls') 19 | self.email_port = dictionary.get('emailPort') 20 | self.email_host_user = dictionary.get('emailHostUser') 21 | self.email_host_password = dictionary.get('emailHostPassword') 22 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/i18n.py: -------------------------------------------------------------------------------- 1 | class I18n: 2 | """ 3 | This class stores the information about the internationalisation of the 4 | project, namely the language code and time zone 5 | """ 6 | 7 | def __init__(self, *args, **kwargs): 8 | """ 9 | Create an instance of I18n from a dictionary 10 | :param args: arguments 11 | :param kwargs: keyword arguments, includes 'dictionary' 12 | """ 13 | 14 | super().__init__() 15 | 16 | dictionary = kwargs.get('dictionary') or dict() 17 | self.language_code = dictionary.get('languageCode') or 'en-gb' 18 | self.time_zone = dictionary.get('timeZone') or 'Asia/Kolkata' 19 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/ip_address_ring.py: -------------------------------------------------------------------------------- 1 | class IpAddressRing: 2 | """ 3 | This class stores information about an IP address ring, namely the name and 4 | patterns 5 | """ 6 | 7 | def __init__(self, *args, **kwargs): 8 | """ 9 | Create an instance of IpAddressRing from a dictionary 10 | :param args: arguments 11 | :param kwargs: keyword arguments, including 'dictionary' 12 | """ 13 | 14 | super().__init__() 15 | 16 | dictionary = kwargs.get('dictionary') or dict() 17 | self.name = dictionary.get('name') 18 | self.patterns = dictionary.get('patterns') 19 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/nomenclature.py: -------------------------------------------------------------------------------- 1 | class Nomenclature: 2 | """ 3 | This class stores information about an app's nomenclature, namely the code 4 | name and verbose name 5 | """ 6 | 7 | def __init__(self, *args, **kwargs): 8 | """ 9 | Create a Nomenclature instance, from a dictionary 10 | :param args: arguments 11 | :param kwargs: keyword arguments, including 'dictionary' 12 | """ 13 | 14 | super().__init__() 15 | 16 | dictionary = kwargs.get('dictionary') or dict() 17 | self.name = dictionary.get('name') or 'omniport' 18 | self.verbose_name = dictionary.get('verboseName') or 'Omniport' 19 | self.tagline = dictionary.get('tagline', '') 20 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/secrets.py: -------------------------------------------------------------------------------- 1 | class Secrets: 2 | """ 3 | This class stores the secret information related to the project, namely 4 | the Django secret key 5 | """ 6 | 7 | def __init__(self, *args, **kwargs): 8 | """ 9 | Create an instance of Secrets from a dictionary 10 | :param args: arguments 11 | :param kwargs: keyword arguments, includes 'dictionary' 12 | """ 13 | 14 | super().__init__() 15 | 16 | dictionary = kwargs.get('dictionary') or dict() 17 | self.secret_key = dictionary.get('secretKey') 18 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/site.py: -------------------------------------------------------------------------------- 1 | from configuration.models.project.nomenclature import Nomenclature 2 | 3 | 4 | class Site: 5 | """ 6 | This class stores information about a site, namely the ID, code name and 7 | verbose name 8 | """ 9 | 10 | def __init__(self, *args, **kwargs): 11 | """ 12 | Create an instance of Site from a dictionary 13 | :param args: arguments 14 | :param kwargs: keyword arguments, including 'dictionary' 15 | """ 16 | 17 | super().__init__() 18 | 19 | dictionary = kwargs.get('dictionary') or dict() 20 | self.id = dictionary.get('id') or 0 21 | self.nomenclature = Nomenclature( 22 | dictionary=dictionary.get('nomenclature') 23 | ) 24 | self.debug = dictionary.get('debug') or False 25 | self.description = dictionary.get('description') 26 | 27 | # Processed variables 28 | self.imagery = None 29 | -------------------------------------------------------------------------------- /omniport/core/configuration/models/project/text.py: -------------------------------------------------------------------------------- 1 | class Text: 2 | """ 3 | This class stores information about a brand, namely the name, home page and 4 | acronym 5 | """ 6 | 7 | def __init__(self, *args, **kwargs): 8 | """ 9 | Create an instance of Text from a dictionary 10 | :param args: arguments 11 | :param kwargs: keyword arguments, includes 'dictionary' 12 | """ 13 | 14 | dictionary = kwargs.get('dictionary') or dict() 15 | self.name = dictionary.get('name') 16 | self.acronym = dictionary.get('acronym') 17 | self.home_page = dictionary.get('homePage') 18 | -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/configuration/serializers/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/configuration/serializers/app/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/app/app.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | from configuration.serializers.app.assets import AssetsSerializer 4 | from configuration.serializers.app.base_urls import BaseUrlsSerializer 5 | from configuration.serializers.app.nomenclature import NomenclatureSerializer 6 | 7 | 8 | class AppSerializer(serializers.Serializer): 9 | """ 10 | Serializer for AppConfiguration objects 11 | """ 12 | 13 | nomenclature = NomenclatureSerializer() 14 | base_urls = BaseUrlsSerializer() 15 | assets = AssetsSerializer() 16 | description = serializers.CharField() 17 | -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/app/assets.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from rest_framework import serializers 4 | 5 | 6 | class AssetsSerializer(serializers.Serializer): 7 | """ 8 | Serializer for Assets objects 9 | """ 10 | 11 | favicon = serializers.SerializerMethodField() 12 | icon = serializers.SerializerMethodField() 13 | logo = serializers.SerializerMethodField() 14 | 15 | def get_favicon(self, instance): 16 | """ 17 | Get the URL to the favicon of the imagery instance 18 | :param instance: the instance whose favicon is requested 19 | :return: the URL to the favicon 20 | """ 21 | 22 | if instance.favicon is not None: 23 | return os.path.join('assets', instance.favicon) 24 | 25 | def get_icon(self, instance): 26 | """ 27 | Get the URL to the icon of the imagery instance 28 | :param instance: the instance whose icon is requested 29 | :return: the URL to the icon 30 | """ 31 | 32 | if instance.icon is not None: 33 | return os.path.join('assets', instance.icon) 34 | 35 | def get_logo(self, instance): 36 | """ 37 | Get the URL to the logo of the imagery instance 38 | :param instance: the instance whose logo is requested 39 | :return: the URL to the logo 40 | """ 41 | 42 | if instance.logo is not None: 43 | return os.path.join('assets', instance.logo) 44 | -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/app/base_urls.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | 4 | class BaseUrlsSerializer(serializers.Serializer): 5 | """ 6 | Serializer for BaseUrls objects 7 | """ 8 | 9 | http = serializers.CharField() 10 | ws = serializers.CharField() 11 | static = serializers.CharField() 12 | -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/app/nomenclature.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | 4 | class NomenclatureSerializer(serializers.Serializer): 5 | """ 6 | Serializer for Nomenclature objects 7 | """ 8 | 9 | name = serializers.CharField() 10 | verbose_name = serializers.CharField() 11 | -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/configuration/serializers/project/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/project/branding.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | from configuration.serializers.project.imagery import ImagerySerializer 4 | from configuration.serializers.project.text import TextSerializer 5 | 6 | 7 | class BrandSerializer(serializers.Serializer): 8 | """ 9 | Serializer for Brand objects 10 | """ 11 | 12 | text = TextSerializer() 13 | imagery = ImagerySerializer() 14 | -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/project/nomenclature.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | 4 | class NomenclatureSerializer(serializers.Serializer): 5 | """ 6 | Serializer for Nomenclature objects 7 | """ 8 | 9 | name = serializers.CharField() 10 | verbose_name = serializers.CharField() 11 | tagline = serializers.CharField() 12 | -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/project/site.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | from configuration.serializers.project.imagery import ImagerySerializer 4 | from configuration.serializers.project.nomenclature import ( 5 | NomenclatureSerializer, 6 | ) 7 | 8 | 9 | class SiteSerializer(serializers.Serializer): 10 | """ 11 | Serializer for Site objects 12 | """ 13 | 14 | id = serializers.IntegerField() 15 | nomenclature = NomenclatureSerializer() 16 | imagery = ImagerySerializer() 17 | -------------------------------------------------------------------------------- /omniport/core/configuration/serializers/project/text.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | 4 | class TextSerializer(serializers.Serializer): 5 | """ 6 | Serializer for Text objects 7 | """ 8 | 9 | name = serializers.CharField() 10 | acronym = serializers.CharField() 11 | home_page = serializers.CharField() 12 | -------------------------------------------------------------------------------- /omniport/core/configuration/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/configuration/utils/__init__.py -------------------------------------------------------------------------------- /omniport/core/configuration/utils/app_config_class.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.apps import AppConfig 4 | from django.conf import settings 5 | 6 | 7 | def get_app_config_class(path): 8 | """ 9 | Return a subclass of AppConfig to configure the app 10 | :param path: the path to the apps.py file, can be accessed as __file__ 11 | :return: a subclass of AppConfig that configures the given app 12 | """ 13 | 14 | file_path = os.path.abspath(path) 15 | app_directory = os.path.dirname(file_path) 16 | app_directory_name = os.path.basename(app_directory) 17 | conf = settings.DISCOVERY.get_app_configuration(app_directory_name) 18 | 19 | class Config(AppConfig): 20 | name = app_directory_name 21 | label = conf.nomenclature.name 22 | verbose_name = conf.nomenclature.verbose_name 23 | configuration = conf 24 | 25 | return Config 26 | -------------------------------------------------------------------------------- /omniport/core/configuration/utils/file_search.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def file_search(files, name, extensions=None): 5 | """ 6 | Find a file with the given name from a list of files 7 | :param files: the list of files within which to search for the file 8 | :param name: the name of the file removing the extension to look for 9 | :param extensions: the allowed extensions, in order of preference 10 | :return: the full file name if found, None otherwise 11 | """ 12 | 13 | if extensions is None: 14 | for file in files: 15 | file_name, file_extension = os.path.splitext(file) 16 | if file_name == name: 17 | return file 18 | else: 19 | current_file = None 20 | current_pos = len(extensions) 21 | 22 | for file in files: 23 | file_name, file_extension = os.path.splitext(file) 24 | if ( 25 | file_name == name 26 | and file_extension in extensions 27 | and extensions.index(file_extension) < current_pos 28 | ): 29 | current_file = file 30 | current_pos = extensions.index(file_extension) 31 | 32 | return current_file 33 | -------------------------------------------------------------------------------- /omniport/core/discovery/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/discovery/__init__.py -------------------------------------------------------------------------------- /omniport/core/guest_auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/guest_auth/__init__.py -------------------------------------------------------------------------------- /omniport/core/guest_auth/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class GuestAuthConfig(AppConfig): 5 | name = 'guest_auth' 6 | verbose_name = 'Session-based guest authentication' 7 | -------------------------------------------------------------------------------- /omniport/core/guest_auth/http_urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from guest_auth.views.login import Login 4 | from guest_auth.views.logout import Logout 5 | 6 | app_name = 'guest_auth' 7 | 8 | urlpatterns = [ 9 | path('login/', Login.as_view(), name='login'), 10 | path('logout/', Logout.as_view(), name='logout'), 11 | ] 12 | -------------------------------------------------------------------------------- /omniport/core/guest_auth/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/guest_auth/migrations/__init__.py -------------------------------------------------------------------------------- /omniport/core/guest_auth/utils/create_guest.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | import random 3 | import string 4 | import datetime 5 | 6 | from django.conf import settings 7 | 8 | from base_auth.models import User 9 | 10 | 11 | def create_guest(): 12 | Person = swapper.load_model('kernel', 'person') 13 | password = ''.join(random.choice(string.ascii_letters) for i in range(10)) 14 | 15 | guest_user = User.objects.create_user( 16 | username=settings.GUEST_USERNAME, 17 | password=password 18 | ) 19 | guest_person, _ = Person.objects.get_or_create( 20 | user=guest_user, 21 | short_name=settings.GUEST_USERNAME, 22 | full_name=settings.GUEST_USERNAME 23 | ) 24 | 25 | Guest = swapper.load_model('kernel', 'Guest') 26 | Guest.objects.get_or_create(person=guest_person, start_date=datetime.date.today()) 27 | return guest_user 28 | -------------------------------------------------------------------------------- /omniport/core/guest_auth/views/login.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from rest_framework import status, generics, response 4 | from django.contrib.auth import login 5 | from django.conf import settings 6 | 7 | from omniport.utils import switcher 8 | from base_auth.models import User 9 | from base_auth.managers.get_user import get_user 10 | from session_auth.models import SessionMap 11 | from guest_auth.utils.create_guest import create_guest 12 | 13 | 14 | Person = swapper.load_model('kernel', 'Person') 15 | 16 | AvatarSerializer = switcher.load_serializer('kernel', 'Person', 'Avatar') 17 | 18 | 19 | class Login(generics.GenericAPIView): 20 | """ 21 | This view takes the username and password and if correct, logs the user in 22 | via cookie-based session authentication 23 | """ 24 | 25 | def get(self, request, *args, **kwargs): 26 | """ 27 | View to serve POST requests 28 | :param request: the request that is to be responded to 29 | :param args: arguments 30 | :param kwargs: keyword arguments 31 | :return: the response for request 32 | """ 33 | 34 | try: 35 | guest_user = get_user(settings.GUEST_USERNAME) 36 | except User.DoesNotExist: 37 | guest_user = create_guest() 38 | 39 | login( 40 | request=request, 41 | user=guest_user, 42 | backend='base_auth.backends.generalised.GeneralisedAuthBackend' 43 | ) 44 | 45 | SessionMap.create_session_map( 46 | request=request, 47 | user=guest_user, 48 | new=False 49 | ) 50 | 51 | try: 52 | user_data = AvatarSerializer(guest_user.person).data 53 | except Person.DoesNotExist: 54 | user_data = None 55 | response_data = { 56 | 'status': 'Successfully logged in.', 57 | 'user': user_data, 58 | } 59 | return response.Response( 60 | data=response_data, 61 | status=status.HTTP_200_OK 62 | ) 63 | -------------------------------------------------------------------------------- /omniport/core/guest_auth/views/logout.py: -------------------------------------------------------------------------------- 1 | from rest_framework import status, permissions, generics, response 2 | 3 | from session_auth.models import SessionMap 4 | 5 | 6 | class Logout(generics.GenericAPIView): 7 | """ 8 | This view deletes the cookie-based session authentication token from the 9 | database, thereby logging out the user 10 | 11 | Works only when authenticated 12 | """ 13 | 14 | permission_classes = [permissions.IsAuthenticated, ] 15 | 16 | def get(self, request, *args, **kwargs): 17 | """ 18 | View to serve GET requests 19 | :param request: the request that is to be responded to 20 | :param args: arguments 21 | :param kwargs: keyword arguments 22 | :return: the response for request 23 | """ 24 | 25 | # This is a direct replacement for django.contrib.auth.logout() 26 | SessionMap.delete_session_map(request=request) 27 | 28 | response_data = { 29 | 'status': 'Successfully logged out', 30 | } 31 | return response.Response( 32 | data=response_data, 33 | status=status.HTTP_200_OK 34 | ) 35 | -------------------------------------------------------------------------------- /omniport/core/kernel/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/admin/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | In these files the import order namely `model_admins` first, followed by `admin` 3 | is important. 4 | 5 | Do not refactor this file. 6 | """ 7 | 8 | from kernel.admin import model_admins 9 | from kernel.admin import admin 10 | -------------------------------------------------------------------------------- /omniport/core/kernel/admin/model_admins/__init__.py: -------------------------------------------------------------------------------- 1 | from kernel.admin.model_admins.faculty_member import FacultyMemberAdmin 2 | from kernel.admin.model_admins.branch import BranchAdmin 3 | from kernel.admin.model_admins.person import PersonAdmin 4 | from kernel.admin.model_admins.student import StudentAdmin 5 | -------------------------------------------------------------------------------- /omniport/core/kernel/admin/model_admins/branch.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.contrib import admin 3 | 4 | from formula_one.admin.model_admins.base import ModelAdmin 5 | from omniport.admin.site import omnipotence 6 | 7 | Branch = swapper.load_model('kernel', 'Branch') 8 | 9 | 10 | @admin.register(Branch, site=omnipotence) 11 | class BranchAdmin(ModelAdmin): 12 | """ 13 | This class controls the behaviour of Branch in Omnipotence 14 | """ 15 | 16 | search_fields = [ 17 | 'name' 18 | ] 19 | -------------------------------------------------------------------------------- /omniport/core/kernel/admin/model_admins/faculty_member.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.contrib import admin 3 | 4 | from formula_one.admin.model_admins.base import ModelAdmin 5 | from omniport.admin.site import omnipotence 6 | 7 | FacultyMember = swapper.load_model('kernel', 'FacultyMember') 8 | 9 | 10 | @admin.register(FacultyMember, site=omnipotence) 11 | class FacultyMemberAdmin(ModelAdmin): 12 | """ 13 | This class controls the behaviour of FacultyMember in Omnipotence 14 | """ 15 | 16 | search_fields = [ 17 | 'employee_id', 18 | 'person__full_name' 19 | ] 20 | -------------------------------------------------------------------------------- /omniport/core/kernel/admin/model_admins/student.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.contrib import admin 3 | 4 | from formula_one.admin.model_admins.base import ModelAdmin 5 | from omniport.admin.site import omnipotence 6 | 7 | Student = swapper.load_model('kernel', 'Student') 8 | 9 | 10 | @admin.register(Student, site=omnipotence) 11 | class StudentAdmin(ModelAdmin): 12 | """ 13 | This class controls the behaviour of Student in Omnipotence 14 | """ 15 | 16 | search_fields = [ 17 | 'enrolment_number', 18 | 'person__full_name' 19 | ] 20 | -------------------------------------------------------------------------------- /omniport/core/kernel/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class KernelConfig(AppConfig): 5 | name = 'kernel' 6 | -------------------------------------------------------------------------------- /omniport/core/kernel/constants/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/constants/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/constants/biological_information.py: -------------------------------------------------------------------------------- 1 | # Blood groups 2 | O_POSITIVE = 'O+' 3 | O_NEGATIVE = 'O-' 4 | A_POSITIVE = 'A+' 5 | A_NEGATIVE = 'A-' 6 | B_POSITIVE = 'B+' 7 | B_NEGATIVE = 'B-' 8 | AB_POSITIVE = 'AB+' 9 | AB_NEGATIVE = 'AB-' 10 | 11 | BLOOD_GROUPS = ( 12 | (O_POSITIVE, O_POSITIVE), 13 | (O_NEGATIVE, O_NEGATIVE), 14 | (A_POSITIVE, A_POSITIVE), 15 | (A_NEGATIVE, A_NEGATIVE), 16 | (B_POSITIVE, B_POSITIVE), 17 | (B_NEGATIVE, B_NEGATIVE), 18 | (AB_POSITIVE, AB_POSITIVE), 19 | (AB_NEGATIVE, AB_NEGATIVE), 20 | ) 21 | 22 | # Genders 23 | MAN = 'man' 24 | WOMAN = 'woman' 25 | NON_BINARY = 'n-bin' 26 | NON_DISCLOSURE = 'n-dis' 27 | 28 | GENDERS = ( 29 | (MAN, 'Man'), 30 | (WOMAN, 'Woman'), 31 | (NON_BINARY, 'Non-binary/Other'), 32 | (NON_DISCLOSURE, 'Prefer not to disclose'), 33 | ) 34 | 35 | # Sexes 36 | MALE = 'male' 37 | FEMALE = 'female' 38 | NON_BINARY = 'n-bin' 39 | NON_DISCLOSURE = 'n-dis' 40 | 41 | SEXES = ( 42 | (MALE, 'Male'), 43 | (FEMALE, 'Female'), 44 | (NON_BINARY, 'Non-binary/Other'), 45 | (NON_DISCLOSURE, 'Prefer not to disclose'), 46 | ) 47 | 48 | # Pronouns 49 | HE = 'h' 50 | SHE = 's' 51 | THEY = 't' 52 | 53 | PRONOUNS = ( 54 | (HE, 'He/him/his'), 55 | (SHE, 'She/her/her'), 56 | (THEY, 'They/them/their'), 57 | ) 58 | 59 | # Impairments 60 | ORTHOPAEDICALLY_IMPAIRED = 'o' 61 | VISUALLY_IMPAIRED = 'v' 62 | HEARING_IMPAIRED = 'h' 63 | SPEECH_IMPAIRED = 's' 64 | NO_IMPAIRMENT = 'n' 65 | 66 | IMPAIRMENTS = ( 67 | (ORTHOPAEDICALLY_IMPAIRED, 'Orthopaedically impaired'), 68 | (VISUALLY_IMPAIRED, 'Visually impaired'), 69 | (HEARING_IMPAIRED, 'Hearing impaired'), 70 | (SPEECH_IMPAIRED, 'Speech impaired'), 71 | (NO_IMPAIRMENT, 'No impairment'), 72 | ) 73 | -------------------------------------------------------------------------------- /omniport/core/kernel/constants/graduations.py: -------------------------------------------------------------------------------- 1 | """ 2 | Graduations in the Indian education system 3 | """ 4 | 5 | MATRICULATE = 'mat' 6 | INTERMEDIATE = 'int' 7 | ASSOCIATE = 'ass' 8 | GRADUATE = 'gra' 9 | POSTGRADUATE = 'pos' 10 | DOCTORATE = 'doc' 11 | POSTDOCTORATE = 'pdo' 12 | 13 | GRADUATIONS = ( 14 | (MATRICULATE, 'Matriculate'), 15 | (INTERMEDIATE, 'Intermediate'), 16 | (ASSOCIATE, 'Associate'), 17 | (GRADUATE, 'Graduate'), 18 | (POSTGRADUATE, 'Postgraduate'), 19 | (DOCTORATE, 'Doctorate'), 20 | (POSTDOCTORATE, 'Postdoctorate'), 21 | ) 22 | -------------------------------------------------------------------------------- /omniport/core/kernel/http_urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from kernel.views.rights import Rights 4 | from kernel.views.who_am_i import WhoAmI 5 | 6 | app_name = 'kernel' 7 | 8 | # URL patterns 9 | urlpatterns = [ 10 | path('who_am_i/', WhoAmI.as_view(), name='who_am_i'), # Primary URL 11 | path('whoami/', WhoAmI.as_view(), name='whoami'), # Alternate URL 12 | 13 | path('rights/', Rights.as_view(), name='rights'), 14 | ] 15 | -------------------------------------------------------------------------------- /omniport/core/kernel/managers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/managers/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/0003_auto_20191104_0141.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.3 on 2019-11-03 20:11 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('contenttypes', '0002_remove_content_type_name'), 11 | ('kernel', '0002_relationships'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='branch', 17 | name='department', 18 | ), 19 | migrations.AddField( 20 | model_name='branch', 21 | name='entity_content_type', 22 | field=models.ForeignKey(limit_choices_to=models.Q(models.Q(('app_label', 'shell'), ('model', 'department')), models.Q(('app_label', 'shell'), ('model', 'centre')), _connector='OR'), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'), 23 | preserve_default=False, 24 | ), 25 | migrations.AddField( 26 | model_name='branch', 27 | name='entity_object_id', 28 | field=models.BigIntegerField(), 29 | preserve_default=False, 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/0004_auto_20200110_1751.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.6 on 2020-01-10 12:21 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('contenttypes', '0002_remove_content_type_name'), 11 | ('kernel', '0003_auto_20191104_0141'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='course', 17 | name='department', 18 | ), 19 | migrations.RemoveField( 20 | model_name='facultymember', 21 | name='department', 22 | ), 23 | migrations.AddField( 24 | model_name='course', 25 | name='entity_content_type', 26 | field=models.ForeignKey(limit_choices_to=models.Q(models.Q(('app_label', 'shell'), ('model', 'department')), models.Q(('app_label', 'shell'), ('model', 'centre')), _connector='OR'), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'), 27 | preserve_default=False, 28 | ), 29 | migrations.AddField( 30 | model_name='course', 31 | name='entity_object_id', 32 | field=models.BigIntegerField(), 33 | preserve_default=False, 34 | ), 35 | migrations.AddField( 36 | model_name='facultymember', 37 | name='entity_content_type', 38 | field=models.ForeignKey(limit_choices_to=models.Q(models.Q(('app_label', 'shell'), ('model', 'department')), models.Q(('app_label', 'shell'), ('model', 'centre')), _connector='OR'), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'), 39 | preserve_default=False, 40 | ), 41 | migrations.AddField( 42 | model_name='facultymember', 43 | name='entity_object_id', 44 | field=models.BigIntegerField(), 45 | preserve_default=False, 46 | ), 47 | ] 48 | -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/0004_guest.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.3 on 2019-12-21 12:16 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('kernel', '0003_auto_20191104_0141'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Guest', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('datetime_created', models.DateTimeField(auto_now_add=True)), 20 | ('datetime_modified', models.DateTimeField(auto_now=True)), 21 | ('start_date', models.DateField()), 22 | ('end_date', models.DateField(blank=True, null=True)), 23 | ('person', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.KERNEL_PERSON_MODEL)), 24 | ], 25 | options={ 26 | 'swappable': 'KERNEL_GUEST_MODEL', 27 | }, 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/0005_auto_20200110_2246.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.6 on 2020-01-10 17:16 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('kernel', '0004_auto_20200110_1751'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='course', 15 | name='code', 16 | field=models.CharField(max_length=15, unique=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/0006_merge_20200111_1752.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.6 on 2020-01-11 12:22 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('kernel', '0004_guest'), 10 | ('kernel', '0005_auto_20200110_2246'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/0008_auto_20220206_2015.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.8 on 2022-02-06 14:45 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.KERNEL_JOINTFACULTYMEMBERSHIP_MODEL), 12 | ('kernel', '0007_jointfaculty_jointfacultymembership'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='jointfaculty', 18 | name='memberships', 19 | field=models.ManyToManyField(related_name='joint_faculty_members', to=settings.KERNEL_JOINTFACULTYMEMBERSHIP_MODEL), 20 | ), 21 | migrations.AddField( 22 | model_name='jointfaculty', 23 | name='person', 24 | field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.KERNEL_PERSON_MODEL), 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/0009_branch_year_count_alter_person_spouses.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.1.5 on 2023-09-27 17:59 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('kernel', '0008_auto_20220206_2015'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='branch', 16 | name='year_count', 17 | field=models.IntegerField(blank=True, null=True), 18 | ), 19 | migrations.AlterField( 20 | model_name='person', 21 | name='spouses', 22 | field=models.ManyToManyField(blank=True, to=settings.KERNEL_PERSON_MODEL), 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/0010_nonteachingstaff.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.1.5 on 2025-01-01 07:18 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('kernel', '0009_branch_year_count_alter_person_spouses'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='NonTeachingStaff', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('datetime_created', models.DateTimeField(auto_now_add=True)), 20 | ('datetime_modified', models.DateTimeField(auto_now=True)), 21 | ('start_date', models.DateField()), 22 | ('end_date', models.DateField(blank=True, null=True)), 23 | ('person', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.KERNEL_PERSON_MODEL)), 24 | ], 25 | options={ 26 | 'swappable': 'KERNEL_NONTEACHINGSTAFF_MODEL', 27 | }, 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /omniport/core/kernel/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/migrations/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/models/__init__.py: -------------------------------------------------------------------------------- 1 | from kernel.models.institute import ( 2 | # Abstract models for customised implementations 3 | AbstractDepartment, 4 | AbstractCentre, 5 | AbstractBranch, 6 | AbstractCourse, 7 | AbstractDegree, 8 | AbstractResidence, 9 | 10 | # Concrete models for default implementation 11 | Department, 12 | Centre, 13 | Branch, 14 | Course, 15 | Degree, 16 | Residence, 17 | ) 18 | from kernel.models.person import ( 19 | # Abstract models for customised implementations 20 | AbstractPerson, 21 | 22 | # Concrete models for default implementation 23 | Person, 24 | ) 25 | from kernel.models.personal_information import ( 26 | # Abstract models for customised implementations 27 | AbstractBiologicalInformation, 28 | AbstractPoliticalInformation, 29 | AbstractFinancialInformation, 30 | AbstractResidentialInformation, 31 | 32 | # Concrete models for default implementation 33 | BiologicalInformation, 34 | FinancialInformation, 35 | PoliticalInformation, 36 | ResidentialInformation, 37 | ) 38 | from kernel.models.roles import ( 39 | # Abstract models for customised implementations 40 | AbstractStudent, 41 | AbstractFacultyMember, 42 | AbstractJointFaculty, 43 | AbstractJointFacultyMembership, 44 | AbstractNonTeachingStaff, 45 | 46 | # Concrete models for default implementation 47 | Student, 48 | FacultyMember, 49 | Guest, 50 | JointFaculty, 51 | JointFacultyMembership, 52 | NonTeachingStaff, 53 | ) 54 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/institute/__init__.py: -------------------------------------------------------------------------------- 1 | from kernel.models.institute.branch import ( 2 | AbstractBranch, 3 | 4 | Branch, 5 | ) 6 | from kernel.models.institute.centre import ( 7 | AbstractCentre, 8 | 9 | Centre, 10 | ) 11 | from kernel.models.institute.course import ( 12 | AbstractCourse, 13 | 14 | Course, 15 | ) 16 | from kernel.models.institute.degree import ( 17 | AbstractDegree, 18 | 19 | Degree, 20 | ) 21 | from kernel.models.institute.department import ( 22 | AbstractDepartment, 23 | 24 | Department, 25 | ) 26 | from kernel.models.institute.residence import ( 27 | AbstractResidence, 28 | 29 | Residence, 30 | ) 31 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/institute/centre.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.contrib.contenttypes import fields as contenttypes_fields 3 | from django.db import models 4 | 5 | from formula_one.models.base import Model 6 | 7 | 8 | class AbstractCentre(Model): 9 | """ 10 | This class holds information about a centre in the college 11 | """ 12 | 13 | code = models.CharField( 14 | max_length=7, 15 | unique=True, 16 | ) 17 | name = models.CharField( 18 | max_length=127, 19 | ) 20 | 21 | location_information = contenttypes_fields.GenericRelation( 22 | to='formula_one.LocationInformation', 23 | related_query_name='centre', 24 | content_type_field='entity_content_type', 25 | object_id_field='entity_object_id', 26 | ) 27 | 28 | class Meta: 29 | """ 30 | Meta class for AbstractCentre 31 | """ 32 | 33 | abstract = True 34 | 35 | def __str__(self): 36 | """ 37 | Return a string representation of the model 38 | :return: a string representation of the model 39 | """ 40 | 41 | name = self.name 42 | return f'{name}' 43 | 44 | 45 | class Centre(AbstractCentre): 46 | """ 47 | This class implements AbstractCentre 48 | """ 49 | 50 | class Meta: 51 | """ 52 | Meta class for Centre 53 | """ 54 | 55 | swappable = swapper.swappable_setting('kernel', 'Centre') 56 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/institute/degree.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.db import models 3 | 4 | from formula_one.models.base import Model 5 | from kernel.constants import graduations 6 | 7 | 8 | class AbstractDegree(Model): 9 | """ 10 | This model holds information about a degree offered by the institute 11 | """ 12 | 13 | code = models.CharField( 14 | max_length=7, 15 | unique=True, 16 | ) 17 | name = models.CharField( 18 | max_length=127, 19 | ) 20 | 21 | graduation = models.CharField( 22 | max_length=3, 23 | choices=graduations.GRADUATIONS, 24 | ) 25 | 26 | class Meta: 27 | """ 28 | Meta class for AbstractDegree 29 | """ 30 | 31 | abstract = True 32 | 33 | def __str__(self): 34 | """ 35 | Return the string representation of the model 36 | :return: the string representation of the model 37 | """ 38 | 39 | name = self.name 40 | graduation = self.graduation 41 | return f'{name} ({graduation})' 42 | 43 | 44 | class Degree(AbstractDegree): 45 | """ 46 | This class implements AbstractDegree 47 | """ 48 | 49 | class Meta: 50 | """ 51 | Meta class for AbstractDegree 52 | """ 53 | 54 | swappable = swapper.swappable_setting('kernel', 'Degree') 55 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/institute/department.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.contrib.contenttypes import fields as contenttypes_fields 3 | from django.db import models 4 | 5 | from formula_one.models.base import Model 6 | 7 | 8 | class AbstractDepartment(Model): 9 | """ 10 | This class holds information about a department in the college 11 | """ 12 | 13 | code = models.CharField( 14 | max_length=7, 15 | unique=True, 16 | ) 17 | name = models.CharField( 18 | max_length=127, 19 | ) 20 | 21 | location_information = contenttypes_fields.GenericRelation( 22 | to='formula_one.LocationInformation', 23 | related_query_name='department', 24 | content_type_field='entity_content_type', 25 | object_id_field='entity_object_id', 26 | ) 27 | 28 | class Meta: 29 | """ 30 | Meta class for AbstractDepartment 31 | """ 32 | 33 | abstract = True 34 | 35 | def __str__(self): 36 | """ 37 | Return a string representation of the model 38 | :return: a string representation of the model 39 | """ 40 | 41 | name = self.name 42 | return f'{name}' 43 | 44 | 45 | class Department(AbstractDepartment): 46 | """ 47 | This class implements AbstractDepartment 48 | """ 49 | 50 | class Meta: 51 | """ 52 | Meta class for Department 53 | """ 54 | 55 | swappable = swapper.swappable_setting('kernel', 'Department') 56 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/institute/residence.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.contrib.contenttypes import fields as contenttypes_fields 3 | from django.db import models 4 | 5 | from formula_one.models.base import Model 6 | 7 | 8 | class AbstractResidence(Model): 9 | """ 10 | This class holds information about a residence in the college 11 | """ 12 | 13 | code = models.CharField( 14 | max_length=7, 15 | unique=True, 16 | ) 17 | name = models.CharField( 18 | max_length=127, 19 | ) 20 | 21 | location_information = contenttypes_fields.GenericRelation( 22 | to='formula_one.LocationInformation', 23 | related_query_name='residence', 24 | content_type_field='entity_content_type', 25 | object_id_field='entity_object_id', 26 | ) 27 | 28 | class Meta: 29 | """ 30 | Meta class for AbstractResidence 31 | """ 32 | 33 | abstract = True 34 | 35 | def __str__(self): 36 | """ 37 | Return the string representation of the model 38 | :return: the string representation of the model 39 | """ 40 | 41 | name = self.name 42 | return f'{name}' 43 | 44 | 45 | class Residence(AbstractResidence): 46 | """ 47 | This class implements AbstractResidence 48 | """ 49 | 50 | class Meta: 51 | """ 52 | Meta class for Residence 53 | """ 54 | 55 | swappable = swapper.swappable_setting('kernel', 'Residence') 56 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/personal_information/__init__.py: -------------------------------------------------------------------------------- 1 | from kernel.models.personal_information.biological_information import ( 2 | AbstractBiologicalInformation, 3 | 4 | BiologicalInformation, 5 | ) 6 | from kernel.models.personal_information.financial_information import ( 7 | AbstractFinancialInformation, 8 | 9 | FinancialInformation, 10 | ) 11 | from kernel.models.personal_information.political_information import ( 12 | AbstractPoliticalInformation, 13 | 14 | PoliticalInformation, 15 | ) 16 | from kernel.models.personal_information.residential_information import ( 17 | AbstractResidentialInformation, 18 | 19 | ResidentialInformation, 20 | ) 21 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/personal_information/base.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.db import models 3 | 4 | from formula_one.models.base import Model 5 | 6 | 7 | class AbstractPersonalInformation(Model): 8 | """ 9 | This model holds information about a person 10 | """ 11 | 12 | person = models.OneToOneField( 13 | to=swapper.get_model_name('kernel', 'Person'), 14 | on_delete=models.CASCADE, 15 | ) 16 | 17 | class Meta: 18 | """ 19 | Meta class for AbstractPersonalInformation 20 | """ 21 | 22 | abstract = True 23 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/personal_information/financial_information.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.core.validators import MinValueValidator 3 | from django.db import models 4 | 5 | from kernel.models.personal_information.base import AbstractPersonalInformation 6 | 7 | 8 | class AbstractFinancialInformation(AbstractPersonalInformation): 9 | """ 10 | This model holds financial information about a person 11 | """ 12 | 13 | local_bank = models.CharField( 14 | max_length=63, 15 | blank=True, 16 | ) 17 | local_bank_account_number = models.CharField( 18 | max_length=31, 19 | blank=True, 20 | ) 21 | annual_income = models.DecimalField( 22 | max_digits=31, 23 | decimal_places=2, 24 | validators=[ 25 | MinValueValidator(0), 26 | ], 27 | blank=True, 28 | null=True, 29 | ) 30 | 31 | class Meta: 32 | """ 33 | Meta class for AbstractFinancialInformation 34 | """ 35 | 36 | abstract = True 37 | 38 | def __str__(self): 39 | """ 40 | Return the string representation of the model 41 | :return: the string representation of the model 42 | """ 43 | 44 | person = self.person 45 | local_bank = self.local_bank 46 | local_bank_account_number = self.local_bank_account_number 47 | return f'{person} - {local_bank}, {local_bank_account_number}' 48 | 49 | 50 | class FinancialInformation(AbstractFinancialInformation): 51 | """ 52 | This class implements AbstractFinancialInformation 53 | """ 54 | 55 | class Meta: 56 | """ 57 | Meta class for FinancialInformation 58 | """ 59 | 60 | verbose_name_plural = 'financial information' 61 | swappable = swapper.swappable_setting('kernel', 62 | 'FinancialInformation') 63 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/personal_information/political_information.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.db import models 3 | from django_countries import fields as django_countries_fields 4 | 5 | from kernel.models.personal_information.base import AbstractPersonalInformation 6 | 7 | 8 | class AbstractPoliticalInformation(AbstractPersonalInformation): 9 | """ 10 | This model holds political information about a person 11 | """ 12 | 13 | nationality = django_countries_fields.CountryField( 14 | blank_label='Nationality', 15 | ) 16 | 17 | religion = models.CharField( 18 | max_length=63, 19 | blank=True, 20 | ) 21 | 22 | passport_number = models.CharField( 23 | max_length=15, 24 | blank=True, 25 | ) 26 | driving_license_number = models.CharField( 27 | max_length=31, 28 | blank=True, 29 | ) 30 | 31 | class Meta: 32 | """ 33 | Meta class for AbstractPoliticalInformation 34 | """ 35 | 36 | abstract = True 37 | 38 | def __str__(self): 39 | """ 40 | Return the string representation of the model 41 | :return: the string representation of the model 42 | """ 43 | 44 | person = self.person 45 | nationality = self.nationality 46 | return f'{person} - {nationality}' 47 | 48 | 49 | class PoliticalInformation(AbstractPoliticalInformation): 50 | """ 51 | This class implements AbstractPoliticalInformation 52 | """ 53 | 54 | class Meta: 55 | """ 56 | Meta class for PoliticalInformation 57 | """ 58 | 59 | verbose_name_plural = 'political information' 60 | swappable = swapper.swappable_setting('kernel', 61 | 'PoliticalInformation') 62 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/personal_information/residential_information.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.db import models 3 | 4 | from kernel.models.personal_information.base import AbstractPersonalInformation 5 | 6 | 7 | class AbstractResidentialInformation(AbstractPersonalInformation): 8 | """ 9 | This model holds residential information about a person 10 | """ 11 | 12 | residence = models.ForeignKey( 13 | to=swapper.get_model_name('kernel', 'Residence'), 14 | on_delete=models.CASCADE, 15 | ) 16 | 17 | room_number = models.CharField( 18 | max_length=15, 19 | ) 20 | 21 | class Meta: 22 | """ 23 | Meta class for AbstractResidentialInformation 24 | """ 25 | 26 | abstract = True 27 | 28 | def __str__(self): 29 | """ 30 | Return the string representation of the model 31 | :return: the string representation of the model 32 | """ 33 | 34 | person = self.person 35 | room_number = self.room_number 36 | residence = self.residence 37 | return f'{person} - {room_number}, {residence}' 38 | 39 | 40 | class ResidentialInformation(AbstractResidentialInformation): 41 | """ 42 | This class implements AbstractResidentialInformation 43 | """ 44 | 45 | class Meta: 46 | """ 47 | Meta class for ResidentialInformation 48 | """ 49 | 50 | verbose_name_plural = 'residential information' 51 | swappable = swapper.swappable_setting('kernel', 52 | 'ResidentialInformation') 53 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/roles/__init__.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | from kernel.models.roles.faculty_member import ( 4 | AbstractFacultyMember, 5 | 6 | FacultyMember, 7 | ) 8 | from kernel.models.roles.maintainer import ( 9 | AbstractMaintainer, 10 | 11 | Maintainer, 12 | ) 13 | from kernel.models.roles.student import ( 14 | AbstractStudent, 15 | 16 | Student, 17 | ) 18 | from kernel.models.roles.guest_role import ( 19 | Guest, 20 | ) 21 | from kernel.models.roles.joint_faculty import ( 22 | AbstractJointFacultyMembership, 23 | AbstractJointFaculty, 24 | 25 | JointFacultyMembership, 26 | JointFaculty, 27 | ) 28 | from kernel.models.roles.nonteaching_staff import ( 29 | AbstractNonTeachingStaff, 30 | 31 | NonTeachingStaff, 32 | ) 33 | 34 | # Add the names of roles to the list maintained in settings 35 | settings.ROLES.extend([ 36 | 'Student', 37 | 'FacultyMember', 38 | 'Maintainer', 39 | 'Guest', 40 | 'JointFaculty', 41 | 'NonTeachingStaff', 42 | ]) 43 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/roles/base.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.db import models 3 | 4 | from formula_one.mixins.period_mixin import PeriodMixin 5 | from formula_one.models.base import Model 6 | 7 | 8 | class AbstractRole(PeriodMixin, Model): 9 | """ 10 | This model holds information pertaining to a role held by a person 11 | """ 12 | 13 | person = models.OneToOneField( 14 | to=swapper.get_model_name('kernel', 'Person'), 15 | on_delete=models.CASCADE, 16 | ) 17 | 18 | class Meta: 19 | """ 20 | Meta class for AbstractRole 21 | """ 22 | 23 | abstract = True 24 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/roles/guest_role.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from kernel.models.roles.base import AbstractRole 4 | 5 | class Guest(AbstractRole): 6 | """ 7 | This class implements Guest Role 8 | """ 9 | 10 | class Meta: 11 | """ 12 | Meta class for Guest 13 | """ 14 | 15 | swappable = swapper.swappable_setting('kernel', 'Guest') 16 | -------------------------------------------------------------------------------- /omniport/core/kernel/models/roles/nonteaching_staff.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from kernel.models.roles.base import AbstractRole 3 | 4 | class AbstractNonTeachingStaff(AbstractRole): 5 | """ 6 | This model holds information pertaining to a non-teaching staff member 7 | """ 8 | 9 | class Meta: 10 | """ 11 | Meta class for AbstractNonTeachingStaff 12 | """ 13 | 14 | abstract = True 15 | 16 | def __str__(self): 17 | """ 18 | Return the string representation of the model 19 | :return: the string representation of the model 20 | """ 21 | 22 | person = self.person 23 | return f'{person}' 24 | 25 | class NonTeachingStaff(AbstractNonTeachingStaff): 26 | """ 27 | This class implements NonTeachingStaff Role 28 | """ 29 | 30 | class Meta: 31 | """ 32 | Meta class for NonTeachingStaff 33 | """ 34 | 35 | swappable = swapper.swappable_setting('kernel', 'NonTeachingStaff') 36 | -------------------------------------------------------------------------------- /omniport/core/kernel/permissions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/permissions/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/permissions/alohomora.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from rest_framework.permissions import BasePermission 3 | 4 | from kernel.utils.logs import log_permission 5 | 6 | 7 | def has_alohomora_rights(user): 8 | """ 9 | Check if the given user has enough privileges for Alohomora 10 | :param user: the user whose privileges are being tested 11 | :return: True if the user has privileges, False otherwise 12 | """ 13 | 14 | if settings.DEBUG: 15 | has_permission = user.is_superuser 16 | log_permission('alohomora', user, has_permission) 17 | return has_permission 18 | 19 | try: 20 | from shell.utils.rights import has_alohomora_rights as alohomora 21 | has_permission = alohomora(user) 22 | except ImportError: 23 | has_permission = user.is_superuser 24 | 25 | log_permission('alohomora', user, has_permission) 26 | return has_permission 27 | 28 | 29 | class HasAlohomoraRights(BasePermission): 30 | """ 31 | Allows access only to users who have Alohomora rights 32 | """ 33 | 34 | def has_permission(self, request, view): 35 | return ( 36 | request.user is not None 37 | and has_alohomora_rights(request.user) 38 | ) 39 | -------------------------------------------------------------------------------- /omniport/core/kernel/permissions/has_role.py: -------------------------------------------------------------------------------- 1 | from rest_framework.permissions import BasePermission 2 | 3 | from formula_one.enums.active_status import ActiveStatus 4 | from kernel.managers.get_role import get_role 5 | 6 | 7 | def get_has_role(role_name, active_status=ActiveStatus.IS_ACTIVE): 8 | """ 9 | Returns a permission class that checks if a person has a specific role 10 | :param role_name: the name of the role to check for 11 | :param active_status: the active status to look for 12 | :return: a permission class that can be used with DRF 13 | """ 14 | 15 | class HasRole(BasePermission): 16 | """ 17 | Allows access only to users having the given role 18 | """ 19 | 20 | def has_permission(self, request, view): 21 | return get_role( 22 | person=request.person, 23 | role_name=role_name, 24 | active_status=active_status, 25 | silent=True 26 | ) is not None 27 | 28 | return HasRole 29 | -------------------------------------------------------------------------------- /omniport/core/kernel/permissions/helpcentre.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from rest_framework.permissions import BasePermission 3 | 4 | from kernel.utils.logs import log_permission 5 | 6 | 7 | def has_helpcentre_rights(user): 8 | """ 9 | Check if the given user has enough privileges for Helpcentre 10 | :param user: the user whose privileges are being tested 11 | :return: True if the user has privileges, False otherwise 12 | """ 13 | 14 | if settings.DEBUG: 15 | has_permission = user.is_superuser 16 | log_permission('helpcentre', user, has_permission) 17 | return has_permission 18 | 19 | try: 20 | from shell.utils.rights import has_helpcentre_rights as helpcentre 21 | has_permission = helpcentre(user) 22 | except ImportError: 23 | has_permission = user.is_superuser 24 | 25 | log_permission('helpcentre', user, has_permission) 26 | return has_permission 27 | 28 | 29 | class HasHelpcentreRights(BasePermission): 30 | """ 31 | Allows access only to users who have Helpcentre rights 32 | """ 33 | 34 | def has_permission(self, request, view): 35 | return ( 36 | request.user is not None 37 | and has_helpcentre_rights(request.user) 38 | ) 39 | -------------------------------------------------------------------------------- /omniport/core/kernel/permissions/omnipotence.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from rest_framework.permissions import BasePermission 3 | 4 | from kernel.utils.logs import log_permission 5 | 6 | 7 | def has_omnipotence_rights(user): 8 | """ 9 | Check if the given user has enough privileges for Omnipotence 10 | :param user: the user whose privileges are being tested 11 | :return: True if the user has privileges, False otherwise 12 | """ 13 | 14 | if settings.DEBUG: 15 | has_permission = user.is_superuser 16 | log_permission('omnipotence', user, has_permission) 17 | return has_permission 18 | 19 | try: 20 | from shell.utils.rights import has_omnipotence_rights as omnipotence 21 | has_permission = omnipotence(user) 22 | except ImportError: 23 | has_permission = user.is_superuser 24 | 25 | log_permission('omnipotence', user, has_permission) 26 | return has_permission 27 | 28 | class HasOmnipotenceRights(BasePermission): 29 | """ 30 | Check if the given user has enough privileges for Omnipotence 31 | """ 32 | 33 | def has_permission(self, request, view): 34 | return ( 35 | request.user is not None 36 | and has_omnipotence_rights(request.user) 37 | ) 38 | -------------------------------------------------------------------------------- /omniport/core/kernel/permissions/polyjuice.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from rest_framework.permissions import BasePermission 3 | 4 | from kernel.utils.logs import log_permission 5 | 6 | 7 | def has_polyjuice_rights(user): 8 | """ 9 | Check if the given user has enough privileges for Polyjuice 10 | :param user: the user whose privileges are being tested 11 | :return: True if the user has privileges, False otherwise 12 | """ 13 | 14 | if settings.DEBUG: 15 | has_permission = user.is_superuser 16 | log_permission('polyjuice', user, has_permission) 17 | return has_permission 18 | 19 | try: 20 | from shell.utils.rights import has_polyjuice_rights as polyjuice 21 | has_permission = polyjuice(user) 22 | except ImportError: 23 | has_permission = user.is_superuser 24 | 25 | log_permission('polyjuice', user, has_permission) 26 | return has_permission 27 | 28 | 29 | class HasPolyjuiceRights(BasePermission): 30 | """ 31 | Allows access only to users who have Polyjuice rights 32 | """ 33 | 34 | def has_permission(self, request, view): 35 | return ( 36 | request.user is not None 37 | and has_polyjuice_rights(request.user) 38 | ) 39 | -------------------------------------------------------------------------------- /omniport/core/kernel/relations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/relations/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/relations/person.py: -------------------------------------------------------------------------------- 1 | from django.core.exceptions import ObjectDoesNotExist 2 | from rest_framework import serializers 3 | 4 | from base_auth.managers.get_user import get_user 5 | 6 | 7 | class PersonRelatedField(serializers.PrimaryKeyRelatedField): 8 | """ 9 | This field handles the proper input of related people, 10 | by overriding functions from PrimaryKeyRelatedField 11 | """ 12 | 13 | def to_internal_value(self, data): 14 | try: 15 | if type(data) is dict: 16 | # Dictionary sent by API should have ID in key 'id'... 17 | if 'id' in data: 18 | return self.queryset.get(pk=data['id']) 19 | # ...or username in key 'username' 20 | elif 'username' in data: 21 | return get_user(username=data['username']).person 22 | else: 23 | # Any other dictionary is not acceptable 24 | self.fail('incorrect_type', data_type=type(data).__name__) 25 | elif type(data) is int: 26 | # Integer sent by API should be the ID 27 | return self.queryset.get(pk=data) 28 | elif type(data) is str: 29 | # String sent by API should be the username 30 | return get_user(username=data).person 31 | else: 32 | # Any other data type sent by the API is not acceptable 33 | self.fail('incorrect_type', data_type=type(data).__name__) 34 | except ObjectDoesNotExist: 35 | self.fail('does_not_exist', pk_value=data) 36 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/serializers/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/institute/branch.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from formula_one.serializers.base import ModelSerializer 4 | from omniport.utils import switcher 5 | 6 | DegreeSerializer = switcher.load_serializer('kernel', 'Degree') 7 | DepartmentSerializer = switcher.load_serializer('kernel', 'Department') 8 | 9 | 10 | class BranchSerializer(ModelSerializer): 11 | """ 12 | Serializer for Branch objects 13 | """ 14 | 15 | degree = DegreeSerializer( 16 | read_only=True, 17 | ) 18 | department = DepartmentSerializer( 19 | read_only=True, 20 | ) 21 | 22 | class Meta: 23 | """ 24 | Meta class for BranchSerializer 25 | """ 26 | 27 | model = swapper.load_model('kernel', 'Branch') 28 | 29 | fields = [ 30 | 'id', 31 | 'code', 32 | 'name', 33 | 'degree', 34 | 'department', 35 | ] 36 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/institute/degree.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from rest_framework import serializers 3 | 4 | from formula_one.serializers.base import ModelSerializer 5 | 6 | 7 | class DegreeSerializer(ModelSerializer): 8 | """ 9 | Serializer for Branch objects 10 | """ 11 | 12 | graduation = serializers.SerializerMethodField( 13 | read_only=True, 14 | ) 15 | 16 | def get_graduation(self, instance): 17 | """ 18 | Return the graduation level of the degree, which is the first element 19 | of the graduation tuple 20 | :return: the first element of the graduation tuple 21 | """ 22 | 23 | return instance.graduation[1] 24 | 25 | class Meta: 26 | """ 27 | Meta class for DegreeSerializer 28 | """ 29 | 30 | model = swapper.load_model('kernel', 'Degree') 31 | 32 | fields = [ 33 | 'id', 34 | 'code', 35 | 'name', 36 | 'graduation', 37 | ] 38 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/institute/department.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from formula_one.serializers.base import ModelSerializer 4 | 5 | 6 | class DepartmentSerializer(ModelSerializer): 7 | """ 8 | Serializer for Departments objects 9 | """ 10 | 11 | class Meta: 12 | """ 13 | Meta class for DepartmentSerializer 14 | """ 15 | 16 | model = swapper.load_model('kernel', 'Department') 17 | 18 | fields = [ 19 | 'id', 20 | 'code', 21 | 'name', 22 | ] 23 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/institute/residence.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from formula_one.serializers.base import ModelSerializer 4 | 5 | 6 | class ResidenceSerializer(ModelSerializer): 7 | """ 8 | Serializer for Residence objects 9 | """ 10 | 11 | class Meta: 12 | """ 13 | Meta class for Residence 14 | """ 15 | 16 | model = swapper.load_model('kernel', 'Residence') 17 | fields = [ 18 | 'id', 19 | 'code', 20 | 'name', 21 | ] 22 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/personal_information/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/serializers/personal_information/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/personal_information/biological_information.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from formula_one.serializers.base import ModelSerializer 4 | 5 | BiologicalInformation = swapper.load_model('kernel', 'BiologicalInformation') 6 | 7 | 8 | class BiologicalInformationSerializer(ModelSerializer): 9 | """ 10 | Serializer for BiologicalInformation objects 11 | """ 12 | 13 | class Meta: 14 | """ 15 | Meta class for BiologicalInformationSerializer 16 | """ 17 | 18 | model = BiologicalInformation 19 | exclude = [ 20 | 'person', 21 | 'id', 22 | 'datetime_created', 23 | 'datetime_modified', 24 | ] 25 | read_only_fields = [ 26 | 'date_of_birth', 27 | ] 28 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/personal_information/financial_information.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from formula_one.serializers.base import ModelSerializer 4 | 5 | FinancialInformation = swapper.load_model('kernel', 'FinancialInformation') 6 | 7 | 8 | class FinancialInformationSerializer(ModelSerializer): 9 | """ 10 | Serializer for FinancialInformation objects 11 | """ 12 | 13 | class Meta: 14 | """ 15 | Meta class for FinancialInformationSerializer 16 | """ 17 | 18 | model = FinancialInformation 19 | exclude = [ 20 | 'person', 21 | 'id', 22 | 'datetime_created', 23 | 'datetime_modified', 24 | ] 25 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/roles/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/serializers/roles/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/roles/base.py: -------------------------------------------------------------------------------- 1 | from formula_one.serializers.base import ModelSerializer 2 | from omniport.utils import switcher 3 | 4 | AvatarSerializer = switcher.load_serializer('kernel', 'Person', 'Avatar') 5 | 6 | 7 | class RoleSerializer(ModelSerializer): 8 | """ 9 | Serializer for Role objects 10 | """ 11 | 12 | person = AvatarSerializer( 13 | read_only=True, 14 | ) 15 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/roles/faculty_member.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from kernel.serializers.roles.base import RoleSerializer 4 | from omniport.utils import switcher 5 | 6 | DepartmentSerializer = switcher.load_serializer('kernel', 'Department') 7 | 8 | 9 | class FacultyMemberSerializer(RoleSerializer): 10 | """ 11 | Serializer for FacultyMember objects 12 | """ 13 | 14 | department = DepartmentSerializer( 15 | read_only=True, 16 | ) 17 | 18 | class Meta: 19 | """ 20 | Meta class for FacultyMemberSerializer 21 | """ 22 | 23 | model = swapper.load_model('kernel', 'FacultyMember') 24 | 25 | fields = [ 26 | 'id', 27 | 'person', 28 | 'department', 29 | 'designation', 30 | ] 31 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/roles/guest.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from kernel.serializers.roles.base import RoleSerializer 4 | 5 | class GuestSerializer(RoleSerializer): 6 | """ 7 | Serializer for Guest Object 8 | """ 9 | 10 | class Meta: 11 | """ 12 | Meta class for guests 13 | """ 14 | 15 | model = swapper.load_model('kernel', 'Guest') 16 | 17 | fields = [ 18 | 'id', 19 | 'person', 20 | ] 21 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/roles/joint_faculty.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from formula_one.serializers.base import ModelSerializer 4 | from kernel.serializers.roles.base import RoleSerializer 5 | from omniport.utils import switcher 6 | 7 | DepartmentSerializer = switcher.load_serializer('kernel', 'Department') 8 | 9 | 10 | class JointFacultyMembershipSerializer(ModelSerializer): 11 | """ 12 | Serializer for JointFacultyMembership objects 13 | """ 14 | 15 | department = DepartmentSerializer( 16 | read_only=True, 17 | ) 18 | 19 | class Meta: 20 | """ 21 | Meta class for JointFacultyMembershipSerializer 22 | """ 23 | 24 | model = swapper.load_model('kernel', 'JointFacultyMembership') 25 | 26 | fields = [ 27 | 'department', 28 | 'designation', 29 | ] 30 | 31 | 32 | class JointFacultySerializer(RoleSerializer): 33 | """ 34 | Serializer for JointFaculty objects 35 | """ 36 | 37 | memberships = JointFacultyMembershipSerializer(many=True) 38 | 39 | 40 | class Meta: 41 | """ 42 | Meta class for JointFacultySerializer 43 | """ 44 | 45 | model = swapper.load_model('kernel', 'JointFaculty') 46 | 47 | fields = [ 48 | 'id', 49 | 'person', 50 | 'memberships', 51 | ] 52 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/roles/maintainer.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from kernel.serializers.roles.base import RoleSerializer 4 | 5 | 6 | class MaintainerSerializer(RoleSerializer): 7 | """ 8 | Serializer for Maintainer objects 9 | """ 10 | 11 | class Meta: 12 | """ 13 | Meta class for MaintainerSerializer 14 | """ 15 | 16 | model = swapper.load_model('kernel', 'Maintainer') 17 | 18 | fields = [ 19 | 'id', 20 | 'person', 21 | 'role', 22 | 'designation', 23 | 'post', 24 | ] 25 | -------------------------------------------------------------------------------- /omniport/core/kernel/serializers/roles/student.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from kernel.serializers.roles.base import RoleSerializer 4 | from omniport.utils import switcher 5 | 6 | BranchSerializer = switcher.load_serializer('kernel', 'Branch') 7 | 8 | 9 | class StudentSerializer(RoleSerializer): 10 | """ 11 | Serializer for Student objects 12 | """ 13 | 14 | branch = BranchSerializer( 15 | read_only=True, 16 | ) 17 | 18 | class Meta: 19 | """ 20 | Meta class for StudentSerializer 21 | """ 22 | 23 | model = swapper.load_model('kernel', 'Student') 24 | 25 | fields = [ 26 | 'id', 27 | 'enrolment_number', 28 | 'person', 29 | 'branch', 30 | 'current_year', 31 | 'current_semester', 32 | ] 33 | -------------------------------------------------------------------------------- /omniport/core/kernel/supervisor.d/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/supervisor.d/.gitignore -------------------------------------------------------------------------------- /omniport/core/kernel/supervisor.d/celery.conf: -------------------------------------------------------------------------------- 1 | [program:celery] 2 | command=celery -A omniport worker -l info 3 | 4 | stdout_logfile=/web_server_logs/supervisord_logs/celery-%(ENV_SITE_ID)s-stdout.log 5 | stdout_logfile_maxbytes=1048576 6 | stdout_logfile_backups=32 7 | 8 | stderr_logfile=/web_server_logs/supervisord_logs/celery-%(ENV_SITE_ID)s-stderr.log 9 | stderr_logfile_maxbytes=1048576 10 | stderr_logfile_backups=32 11 | -------------------------------------------------------------------------------- /omniport/core/kernel/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/utils/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/utils/logs.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | logger = logging.getLogger('kernel_permissions') 4 | 5 | 6 | def log_permission(permission_name, user, is_allowed): 7 | """ 8 | Form sentences to log requests for kernel permissions 9 | This takes the name of the permission, the user who made the request, and 10 | whether the user was allowed or not, logs a relevant message with 11 | appropriate level. 12 | :param permission_name: the kernel permission to be logged 13 | :param user: user requesting the permission 14 | :param is_allowed: whether the user was allowed or not 15 | """ 16 | 17 | log_type = 'info' if is_allowed else 'warning' 18 | getattr(logger, log_type)( 19 | f'[{permission_name.upper()}] ' 20 | f'User {user}({user.id}) was{" " if is_allowed else " not "}' 21 | f'given {permission_name} rights' 22 | ) 23 | -------------------------------------------------------------------------------- /omniport/core/kernel/utils/rights.py: -------------------------------------------------------------------------------- 1 | """ 2 | These functions are an essential part of the rights framework used by Omniport. 3 | They determine which users have access to the administrative features of the 4 | project, which are: 5 | 6 | - omnipotence 7 | The admin interface of the project which is a heavily customised 8 | implementation of the default Django administration view 9 | 10 | - alohomora 11 | The impersonation ability of maintainers to access the account of any user 12 | with their explicit permission, to be used strictly for debugging purposes 13 | under a strict oath of ethical behaviour 14 | 15 | - lockpicking 16 | The no-questions-asked password reset ability which is used by maintainers 17 | to reset the password of forgetful people upon request after verifying the 18 | identity of the requester 19 | 20 | - helpcentre 21 | The ability to access and answer user queries using the special Helpcentre 22 | service, which is also a bug tracker and ticketing system 23 | 24 | These can, and most probably should, be overridden in shell.utils.rights 25 | """ 26 | 27 | # TODO: Eliminate this file and if no other remains, the package utils 28 | from kernel.permissions.omnipotence import has_omnipotence_rights 29 | from kernel.permissions.polyjuice import has_polyjuice_rights 30 | from kernel.permissions.alohomora import has_alohomora_rights 31 | from kernel.permissions.helpcentre import has_helpcentre_rights 32 | -------------------------------------------------------------------------------- /omniport/core/kernel/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/kernel/views/__init__.py -------------------------------------------------------------------------------- /omniport/core/kernel/views/rights.py: -------------------------------------------------------------------------------- 1 | from rest_framework import status, generics, permissions, response 2 | 3 | from kernel.utils import rights 4 | 5 | 6 | class Rights(generics.GenericAPIView): 7 | """ 8 | This view shows if the current user has the given rights 9 | """ 10 | 11 | permission_classes = [permissions.IsAuthenticated, ] 12 | 13 | def get(self, request, *args, **kwargs): 14 | """ 15 | View to serve GET requests 16 | :param request: the request that is to be responded to 17 | :param args: arguments 18 | :param kwargs: keyword arguments 19 | :return: the response for request 20 | """ 21 | 22 | which = request.query_params.get('which') 23 | user = request.user 24 | try: 25 | rights_function = getattr(rights, f'has_{which}_rights') 26 | has_rights = rights_function(user) 27 | response_data = { 28 | 'hasRights': has_rights, 29 | } 30 | return response.Response( 31 | data=response_data, 32 | status=status.HTTP_200_OK 33 | ) 34 | except AttributeError: 35 | response_data = { 36 | 'errors': { 37 | "which": [ 38 | "Non-existent right", 39 | ], 40 | }, 41 | } 42 | return response.Response( 43 | data=response_data, 44 | status=status.HTTP_400_BAD_REQUEST 45 | ) 46 | -------------------------------------------------------------------------------- /omniport/core/kernel/views/who_am_i.py: -------------------------------------------------------------------------------- 1 | from rest_framework import status 2 | from rest_framework.generics import GenericAPIView 3 | from rest_framework.permissions import IsAuthenticated 4 | from rest_framework.response import Response 5 | 6 | from omniport.utils import switcher 7 | 8 | AvatarSerializer = switcher.load_serializer('kernel', 'Person', 'Avatar') 9 | 10 | 11 | class WhoAmI(GenericAPIView): 12 | """ 13 | This view shows some personal information of the currently logged in user 14 | """ 15 | 16 | permission_classes = [IsAuthenticated, ] 17 | serializer_class = AvatarSerializer 18 | 19 | def get(self, request, *args, **kwargs): 20 | """ 21 | View to serve GET requests 22 | :param request: the request that is to be responded to 23 | :param args: arguments 24 | :param kwargs: keyword arguments 25 | :return: the response for request 26 | """ 27 | 28 | person = request.person 29 | serializer = self.get_serializer_class()(person) 30 | return Response(serializer.data, status=status.HTTP_200_OK) 31 | -------------------------------------------------------------------------------- /omniport/core/open_auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/open_auth/__init__.py -------------------------------------------------------------------------------- /omniport/core/open_auth/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class OpenAuthConfig(AppConfig): 5 | name = 'open_auth' 6 | verbose_name = 'OAuth2-based authentication' 7 | 8 | def ready(self): 9 | import open_auth.signals 10 | -------------------------------------------------------------------------------- /omniport/core/open_auth/constants/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/open_auth/constants/__init__.py -------------------------------------------------------------------------------- /omniport/core/open_auth/http_urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from django.views.decorators.http import require_POST 3 | from oauth2_provider.views import ( 4 | AuthorizationView, 5 | TokenView, 6 | RevokeTokenView, 7 | ) 8 | from rest_framework import routers 9 | 10 | from open_auth.views.application import ApplicationViewSet 11 | from open_auth.views.retrieve_data import GetUserData 12 | 13 | router = routers.SimpleRouter() 14 | router.register('application', ApplicationViewSet, basename='application') 15 | 16 | app_name = 'open_auth' 17 | 18 | urlpatterns = [ 19 | path( 20 | 'authorise/', 21 | require_POST(AuthorizationView.as_view()), 22 | name='authorise' 23 | ), 24 | path( 25 | 'token/', 26 | TokenView.as_view(), 27 | name='token' 28 | ), 29 | path( 30 | 'revoke_token/', 31 | RevokeTokenView.as_view(), 32 | name='revoke_token' 33 | ), 34 | path( 35 | 'get_user_data/', 36 | GetUserData.as_view(), 37 | name='get_user_data' 38 | ), 39 | path('', include(router.urls)), 40 | ] 41 | -------------------------------------------------------------------------------- /omniport/core/open_auth/migrations/0002_auto_20211016_0005.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.8 on 2021-10-15 18:35 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('open_auth', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='application', 15 | name='algorithm', 16 | field=models.CharField(blank=True, choices=[('', 'No OIDC support'), ('RS256', 'RSA with SHA-2 256'), ('HS256', 'HMAC with SHA-2 256')], default='', max_length=5), 17 | ), 18 | migrations.AlterField( 19 | model_name='application', 20 | name='authorization_grant_type', 21 | field=models.CharField(choices=[('authorization-code', 'Authorization code'), ('implicit', 'Implicit'), ('password', 'Resource owner password-based'), ('client-credentials', 'Client credentials'), ('openid-hybrid', 'OpenID connect hybrid')], max_length=32), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /omniport/core/open_auth/migrations/0003_alter_application_data_points.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2 on 2022-06-22 19:03 2 | 3 | import django.contrib.postgres.fields 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('open_auth', '0002_auto_20211016_0005'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='application', 16 | name='data_points', 17 | field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(choices=[('person.short_name', 'Short name'), ('person.full_name', 'Full name'), ('person.display_picture', 'Display picture'), ('person.roles', 'Roles'), ('person.custom_roles', 'Custom Roles'), ('student.start_date', 'Joining date'), ('student.end_date', 'Graduation date'), ('student.enrolment_number', 'Enrolment number'), ('student.branch.name', 'Branch'), ('student.branch.degree.name', 'Degree'), ('student.current_year', 'Current year'), ('student.current_semester', 'Current semester'), ('student.branch.department.name', 'Department'), ('faculty_member.start_date', 'Joining date'), ('faculty_member.end_date', 'Leaving date'), ('faculty_member.designation', 'Designation'), ('faculty_member.department.name', 'Department'), ('biological_information.date_of_birth', 'Date of birth'), ('biological_information.blood_group', 'Blood group'), ('contact_information.email_address', 'Email address'), ('contact_information.email_address_verified', 'Email address verified'), ('contact_information.institute_webmail_address', 'Institute webmail address'), ('contact_information.primary_phone_number', 'Primary phone number'), ('contact_information.secondary_phone_number', 'Secondary phone number'), ('residential_information.residence.name', 'Residence'), ('residential_information.room_number', 'Room Number'), ('social_information.links', 'Links')], max_length=127), size=None), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /omniport/core/open_auth/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/open_auth/migrations/__init__.py -------------------------------------------------------------------------------- /omniport/core/open_auth/models/__init__.py: -------------------------------------------------------------------------------- 1 | from open_auth.models.application import Application 2 | -------------------------------------------------------------------------------- /omniport/core/open_auth/models/application.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | from django.contrib.postgres import fields 3 | from django.db import models 4 | from oauth2_provider.models import AbstractApplication 5 | 6 | from formula_one.models.base import Model 7 | from formula_one.utils.upload_to import UploadTo 8 | from formula_one.validators.aspect_ratio import AspectRatioValidator 9 | from open_auth.constants import data_points as data_point_choices 10 | 11 | 12 | class Application(AbstractApplication, Model): 13 | """ 14 | Extends the OAuth2 AbstractApplication model and replaces the default one 15 | supplied in order to add extended information and functionality beyond that 16 | provided by the package 17 | """ 18 | 19 | logo = models.ImageField( 20 | upload_to=UploadTo('open_auth', 'application_logos'), 21 | max_length=255, 22 | validators=[ 23 | AspectRatioValidator(1, 0.05), 24 | ], 25 | blank=True, 26 | null=True, 27 | ) 28 | 29 | description = models.TextField() 30 | 31 | agrees_to_terms = models.BooleanField( 32 | default=False, 33 | ) 34 | is_approved = models.BooleanField( 35 | default=False, 36 | ) 37 | 38 | team_members = models.ManyToManyField( 39 | to=swapper.get_model_name('kernel', 'Person'), 40 | blank=True, 41 | ) 42 | 43 | data_points = fields.ArrayField( 44 | models.CharField( 45 | max_length=127, 46 | choices=data_point_choices.DATA_POINTS, 47 | ) 48 | ) 49 | 50 | def __str__(self): 51 | """ 52 | Return the string representation of the model 53 | :return: the string representation of the model 54 | """ 55 | 56 | name = self.name 57 | return f'{name}' 58 | -------------------------------------------------------------------------------- /omniport/core/open_auth/serializers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/open_auth/serializers/__init__.py -------------------------------------------------------------------------------- /omniport/core/open_auth/signals/__init__.py: -------------------------------------------------------------------------------- 1 | from open_auth.signals.app_authorisation import send_authorisation_notification 2 | -------------------------------------------------------------------------------- /omniport/core/open_auth/signals/app_authorisation.py: -------------------------------------------------------------------------------- 1 | from oauth2_provider.signals import app_authorized 2 | 3 | from open_auth.utils import send_authorisation_notification 4 | 5 | 6 | def handle_app_authorized(sender, request, token, **kwargs): 7 | person = token.user.person 8 | if person is None: 9 | pass 10 | else: 11 | send_authorisation_notification(token.application.name, person.id) 12 | 13 | 14 | app_authorized.connect(handle_app_authorized) 15 | -------------------------------------------------------------------------------- /omniport/core/open_auth/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/open_auth/views/__init__.py -------------------------------------------------------------------------------- /omniport/core/open_auth/views/application.py: -------------------------------------------------------------------------------- 1 | from rest_framework import viewsets, mixins, permissions 2 | 3 | from open_auth.models import Application 4 | from open_auth.serializers.application import ApplicationAuthoriseSerializer 5 | 6 | 7 | class ApplicationViewSet( 8 | mixins.RetrieveModelMixin, 9 | viewsets.GenericViewSet, 10 | ): 11 | """ 12 | Viewset for R operations on Application 13 | """ 14 | 15 | permission_classes = [permissions.IsAuthenticated, ] 16 | serializer_class = ApplicationAuthoriseSerializer 17 | queryset = Application.objects.filter(is_approved=True) 18 | lookup_field = 'client_id' 19 | pagination_class = None 20 | -------------------------------------------------------------------------------- /omniport/core/session_auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/session_auth/__init__.py -------------------------------------------------------------------------------- /omniport/core/session_auth/admin.py: -------------------------------------------------------------------------------- 1 | from omniport.admin.site import omnipotence 2 | 3 | from session_auth.models import SessionMap 4 | 5 | omnipotence.register(SessionMap) 6 | -------------------------------------------------------------------------------- /omniport/core/session_auth/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class SessionAuthConfig(AppConfig): 5 | name = 'session_auth' 6 | verbose_name = 'Session-based authentication' 7 | -------------------------------------------------------------------------------- /omniport/core/session_auth/constants/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/session_auth/constants/__init__.py -------------------------------------------------------------------------------- /omniport/core/session_auth/constants/device_types.py: -------------------------------------------------------------------------------- 1 | # Device types 2 | COMPUTER = 'com' 3 | MOBILE = 'mob' 4 | TABLET = 'tab' 5 | UNKNOWN = 'unk' 6 | DEVICE_TYPES = ( 7 | (COMPUTER, 'Computer'), 8 | (MOBILE, 'Mobile'), 9 | (TABLET, 'Tablet'), 10 | (UNKNOWN, 'Unknown device'), 11 | ) 12 | -------------------------------------------------------------------------------- /omniport/core/session_auth/http_urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from session_auth.views.login import Login 4 | from session_auth.views.logout import Logout 5 | from session_auth.views.illustration_roulette import IllustrationRoulette 6 | 7 | app_name = 'session_auth' 8 | 9 | urlpatterns = [ 10 | path('login/', Login.as_view(), name='login'), 11 | path('logout/', Logout.as_view(), name='logout'), 12 | path( 13 | 'illustration_roulette/', 14 | IllustrationRoulette.as_view(), 15 | name='illustration_roulette' 16 | ) 17 | ] 18 | -------------------------------------------------------------------------------- /omniport/core/session_auth/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.4 on 2018-12-15 21:20 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='SessionMap', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('datetime_created', models.DateTimeField(auto_now_add=True)), 22 | ('datetime_modified', models.DateTimeField(auto_now=True)), 23 | ('session_key', models.CharField(max_length=63, unique=True)), 24 | ('ip_address', models.GenericIPAddressField(verbose_name='IP address')), 25 | ('location', models.CharField(max_length=255)), 26 | ('user_agent', models.CharField(max_length=255)), 27 | ('browser_family', models.CharField(max_length=31)), 28 | ('browser_version', models.CharField(max_length=31)), 29 | ('operating_system_family', models.CharField(max_length=31)), 30 | ('operating_system_version', models.CharField(max_length=31)), 31 | ('device_type', models.CharField(choices=[('com', 'Computer'), ('mob', 'Mobile'), ('tab', 'Tablet'), ('unk', 'Unknown device')], max_length=3)), 32 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 33 | ], 34 | options={ 35 | 'abstract': False, 36 | }, 37 | ), 38 | ] 39 | -------------------------------------------------------------------------------- /omniport/core/session_auth/migrations/0002_alter_sessionmap_user_agent.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2 on 2022-04-18 17:29 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('session_auth', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='sessionmap', 15 | name='user_agent', 16 | field=models.CharField(max_length=511), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /omniport/core/session_auth/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/session_auth/migrations/__init__.py -------------------------------------------------------------------------------- /omniport/core/session_auth/models/__init__.py: -------------------------------------------------------------------------------- 1 | from session_auth.models.session_map import SessionMap 2 | -------------------------------------------------------------------------------- /omniport/core/session_auth/serializers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/session_auth/serializers/__init__.py -------------------------------------------------------------------------------- /omniport/core/session_auth/serializers/login.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import authenticate 2 | from rest_framework import serializers 3 | from rest_framework_simplejwt.serializers import PasswordField 4 | 5 | 6 | class LoginSerializer(serializers.Serializer): 7 | """ 8 | Stores the username and password for logging a user in 9 | """ 10 | 11 | user = None 12 | username = serializers.CharField() 13 | password = PasswordField() 14 | 15 | def validate(self, data): 16 | """ 17 | Authenticate the username and password to see if they are valid 18 | :param data: the data to check for validity 19 | :return: the data if it is valid 20 | :raise ValidationError: if the username and password do not match 21 | """ 22 | 23 | request = self.context.get('request') 24 | 25 | user = authenticate( 26 | request, 27 | username=data.get('username'), 28 | password=data.get('password') 29 | ) 30 | if user is not None: 31 | self.user = user 32 | else: 33 | raise serializers.ValidationError('Invalid credentials provided.') 34 | 35 | return data 36 | -------------------------------------------------------------------------------- /omniport/core/session_auth/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/session_auth/utils/__init__.py -------------------------------------------------------------------------------- /omniport/core/session_auth/utils/ip_address.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | from core.utils.logs import get_logging_function 4 | 5 | 6 | session_auth_log = get_logging_function('session_auth') 7 | 8 | 9 | def get_location(ip_address): 10 | """ 11 | Get the location of an IP address 12 | :param ip_address: the IP address to geo-locate 13 | :return: the approximate location of the IP address 14 | """ 15 | try: 16 | 17 | fields = ','.join([ 18 | 'status', 19 | 'message', 20 | 'city', 21 | 'country', 22 | 'countryCode', 23 | ]) 24 | response = requests.get( 25 | url=f'http://ip-api.com/json/{ip_address}', 26 | params={'fields': fields}, 27 | ) 28 | response = response.json() 29 | if response.pop('status') == 'success': 30 | location = ', '.join([ 31 | response.get('city'), 32 | response.get('country'), 33 | response.get('countryCode'), 34 | ]) 35 | else: 36 | if response.get('message') == 'private range': 37 | location = 'Intranet' 38 | elif response.get('message') == 'reserved range': 39 | location = 'Reserved' 40 | else: 41 | location = 'The Void' 42 | except requests.ConnectionError: 43 | session_auth_log(f'Error finding location of {ip_address}', 'warning') 44 | location = 'The Void' 45 | 46 | return location 47 | -------------------------------------------------------------------------------- /omniport/core/session_auth/utils/user_agent.py: -------------------------------------------------------------------------------- 1 | from user_agents import parse 2 | 3 | from session_auth.constants import device_types 4 | 5 | 6 | def get_agent_information(user_agent_string): 7 | """ 8 | Get additional information about the user agent, such as browser and OS 9 | :param user_agent_string: the user-agent string sent by the browser 10 | :return: the additional information produced by parsing the string 11 | """ 12 | 13 | user_agent = parse(user_agent_string) 14 | if user_agent.is_pc: 15 | device_type = device_types.COMPUTER 16 | elif user_agent.is_tablet: 17 | device_type = device_types.TABLET 18 | elif user_agent.is_mobile: 19 | device_type = device_types.MOBILE 20 | else: 21 | device_type = device_types.UNKNOWN 22 | 23 | return user_agent.browser, user_agent.os, device_type, 24 | -------------------------------------------------------------------------------- /omniport/core/session_auth/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/session_auth/views/__init__.py -------------------------------------------------------------------------------- /omniport/core/session_auth/views/illustration_roulette.py: -------------------------------------------------------------------------------- 1 | from rest_framework.generics import GenericAPIView 2 | from rest_framework.response import Response 3 | from rest_framework.status import HTTP_200_OK 4 | 5 | 6 | class IllustrationRoulette(GenericAPIView): 7 | """ 8 | Return the number of available illustrations to choose from 9 | """ 10 | 11 | def get(self, request, *args, **kwargs): 12 | """ 13 | View to serve GET requests 14 | :param request: the request that is to be responded to 15 | :param args: arguments 16 | :param kwargs: keyword arguments 17 | :return: the response for request 18 | """ 19 | 20 | response = { 21 | 'count': 5 22 | } 23 | 24 | return Response(response, status=HTTP_200_OK) 25 | -------------------------------------------------------------------------------- /omniport/core/session_auth/views/logout.py: -------------------------------------------------------------------------------- 1 | from rest_framework import status, permissions, generics, response 2 | 3 | from session_auth.models import SessionMap 4 | from core.utils.logs import get_logging_function 5 | 6 | 7 | session_auth_log = get_logging_function('session_auth') 8 | 9 | 10 | class Logout(generics.GenericAPIView): 11 | """ 12 | This view deletes the cookie-based session authentication token from the 13 | database, thereby logging out the user 14 | 15 | Works only when authenticated 16 | """ 17 | 18 | permission_classes = [permissions.IsAuthenticated, ] 19 | 20 | def get(self, request, *args, **kwargs): 21 | """ 22 | View to serve GET requests 23 | :param request: the request that is to be responded to 24 | :param args: arguments 25 | :param kwargs: keyword arguments 26 | :return: the response for request 27 | """ 28 | 29 | user = request.user 30 | session_key = request.session.session_key 31 | # This is a direct replacement for django.contrib.auth.logout() 32 | SessionMap.delete_session_map(request=request) 33 | session_auth_log( 34 | f'Successfully logged out of session {session_key}', 35 | 'info', 36 | user 37 | ) 38 | response_data = { 39 | 'status': 'Successfully logged out', 40 | } 41 | return response.Response( 42 | data=response_data, 43 | status=status.HTTP_200_OK 44 | ) 45 | -------------------------------------------------------------------------------- /omniport/core/token_auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/token_auth/__init__.py -------------------------------------------------------------------------------- /omniport/core/token_auth/admin.py: -------------------------------------------------------------------------------- 1 | from omniport.admin.site import omnipotence 2 | 3 | from token_auth.models import AppAccessToken 4 | 5 | omnipotence.register(AppAccessToken) 6 | -------------------------------------------------------------------------------- /omniport/core/token_auth/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class TokenAuthConfig(AppConfig): 5 | name = 'token_auth' 6 | verbose_name = 'Token-based authentication' 7 | -------------------------------------------------------------------------------- /omniport/core/token_auth/authentication/__init__.py: -------------------------------------------------------------------------------- 1 | from token_auth.authentication.app_access_token_authentication import AppAccessTokenAuthentication -------------------------------------------------------------------------------- /omniport/core/token_auth/authentication/app_access_token_authentication.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from rest_framework import authentication 4 | from rest_framework import exceptions 5 | 6 | from token_auth.models import AppAccessToken 7 | from token_auth.constants import HTTP_X_ACCESS_TOKEN 8 | 9 | class AppAccessTokenAuthentication(authentication.BaseAuthentication): 10 | def authenticate(self, request): 11 | access_token = request.META.get(HTTP_X_ACCESS_TOKEN) 12 | ip_address = request.source_ip_address 13 | 14 | if access_token and ip_address: 15 | try: 16 | app_access_token = AppAccessToken.objects.get( 17 | access_token=access_token 18 | ) 19 | allowed_ip_address_regex = app_access_token.ip_address_regex 20 | if re.search(allowed_ip_address_regex, ip_address): 21 | return (app_access_token, None) 22 | else: 23 | raise exceptions.AuthenticationFailed('Request not allowed from' \ 24 | ' this IP address. This event will be logged.' 25 | ) 26 | except AppAccessToken.DoesNotExist: 27 | raise exceptions.AuthenticationFailed('No such app access token') 28 | except Exception as exception: 29 | raise exception 30 | 31 | return None 32 | -------------------------------------------------------------------------------- /omniport/core/token_auth/constants.py: -------------------------------------------------------------------------------- 1 | HTTP_X_ACCESS_TOKEN = 'HTTP_X_ACCESS_TOKEN' -------------------------------------------------------------------------------- /omniport/core/token_auth/http_urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from token_auth.views import ( 4 | ObtainPair, 5 | Refresh, 6 | Verify, 7 | ) 8 | 9 | app_name = 'token_auth' 10 | 11 | urlpatterns = [ 12 | path('obtain_pair/', ObtainPair.as_view(), name='obtain_pair'), 13 | path('refresh/', Refresh.as_view(), name='refresh'), 14 | path('verify/', Verify.as_view(), name='verify'), 15 | ] 16 | -------------------------------------------------------------------------------- /omniport/core/token_auth/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.3 on 2021-10-06 14:52 2 | 3 | import django.contrib.postgres.fields 4 | from django.db import migrations, models 5 | import uuid 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='AppAccessToken', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('datetime_created', models.DateTimeField(auto_now_add=True)), 21 | ('datetime_modified', models.DateTimeField(auto_now=True)), 22 | ('app_name', models.CharField(blank=True, max_length=63, null=True)), 23 | ('description', models.TextField()), 24 | ('permission_keys', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=127), size=None)), 25 | ('access_token', models.CharField(blank=True, default=uuid.uuid4, max_length=255, null=True, unique=True)), 26 | ('ip_address_regex', models.TextField()), 27 | ], 28 | options={ 29 | 'abstract': False, 30 | }, 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /omniport/core/token_auth/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/token_auth/migrations/__init__.py -------------------------------------------------------------------------------- /omniport/core/token_auth/models/__init__.py: -------------------------------------------------------------------------------- 1 | from token_auth.models.app_access_token import AppAccessToken -------------------------------------------------------------------------------- /omniport/core/token_auth/models/app_access_token.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | from django.db import models 3 | from django.contrib.postgres import fields 4 | 5 | from formula_one.models.base import Model 6 | 7 | class AppAccessToken(Model): 8 | """ 9 | Store the tokens which could be used by various apps to make an authenticated 10 | request 11 | """ 12 | 13 | app_name = models.CharField( 14 | max_length=63, 15 | blank=True, 16 | null=True, 17 | ) 18 | 19 | description = models.TextField() 20 | 21 | permission_keys = fields.ArrayField( 22 | models.CharField( 23 | max_length=127, 24 | blank=False, 25 | null=False, 26 | ) 27 | ) 28 | 29 | access_token = models.CharField( 30 | max_length=255, 31 | blank=True, 32 | null=True, 33 | unique=True, 34 | default=uuid.uuid4, 35 | ) 36 | 37 | ip_address_regex = models.TextField() 38 | 39 | def __str__(self): 40 | """ 41 | Return the string representation of the model 42 | :return: the string representation of the model 43 | """ 44 | 45 | name = self.app_name 46 | return f'{name}' 47 | -------------------------------------------------------------------------------- /omniport/core/token_auth/permission/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/token_auth/permission/__init__.py -------------------------------------------------------------------------------- /omniport/core/token_auth/permission/app_access_token.py: -------------------------------------------------------------------------------- 1 | from rest_framework.permissions import BasePermission 2 | 3 | class TokenHasPermissionKey(BasePermission): 4 | """ 5 | Check if the given app access token is authenticated for the permission key 6 | of the view 7 | """ 8 | 9 | def has_permission(self, request, view): 10 | permission_key = view.permission_key 11 | app_access_token = request.user 12 | try: 13 | has_permission_key = permission_key in app_access_token.permission_keys 14 | return has_permission_key 15 | except Exception: 16 | return False 17 | -------------------------------------------------------------------------------- /omniport/core/token_auth/views.py: -------------------------------------------------------------------------------- 1 | """ 2 | Since the SimpleJWT project is incompatible with the JSON API plugin for the 3 | Django REST framework, we override the views to explicitly use the parsers and 4 | renderers as they were before JSON API came along. 5 | """ 6 | 7 | from rest_framework.parsers import ( 8 | JSONParser, 9 | FormParser, 10 | MultiPartParser, 11 | ) 12 | from rest_framework.renderers import ( 13 | JSONRenderer, 14 | BrowsableAPIRenderer, 15 | ) 16 | from rest_framework_simplejwt.views import ( 17 | TokenObtainPairView, 18 | TokenRefreshView, 19 | TokenVerifyView, 20 | ) 21 | 22 | PARSERS_MINUS_JSON_API = (JSONParser, FormParser, MultiPartParser,) 23 | RENDERERS_MINUS_JSON_API = (JSONRenderer, BrowsableAPIRenderer,) 24 | 25 | 26 | class ObtainPair(TokenObtainPairView): 27 | """ 28 | Remove the effect of the addition of project-wide JSON API from the view 29 | """ 30 | 31 | parser_classes = PARSERS_MINUS_JSON_API 32 | renderer_classes = RENDERERS_MINUS_JSON_API 33 | 34 | 35 | class Refresh(TokenRefreshView): 36 | """ 37 | Remove the effect of the addition of project-wide JSON API from the view 38 | """ 39 | 40 | parser_classes = PARSERS_MINUS_JSON_API 41 | renderer_classes = RENDERERS_MINUS_JSON_API 42 | 43 | 44 | class Verify(TokenVerifyView): 45 | """ 46 | Remove the effect of the addition of project-wide JSON API from the view 47 | """ 48 | 49 | parser_classes = PARSERS_MINUS_JSON_API 50 | renderer_classes = RENDERERS_MINUS_JSON_API 51 | -------------------------------------------------------------------------------- /omniport/core/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/core/utils/__init__.py -------------------------------------------------------------------------------- /omniport/core/utils/logs.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | 4 | def get_logging_function(module_name): 5 | """ 6 | This function is used to create a logging function for different modules 7 | in core using the specified logger. 8 | :param module_name: the module name 9 | :return: the logging function 10 | """ 11 | 12 | logger = logging.getLogger('core') 13 | 14 | def log(message, log_type='info', user=None): 15 | """ 16 | Logs the message with user information 17 | :param message: the message to be logged 18 | :param log_type: type of event to be logged 19 | :param user: user responsible for the event 20 | """ 21 | 22 | if user is not None: 23 | user_information = f'User: {user}({user.id}) ' 24 | else: 25 | user_information = '' 26 | 27 | getattr(logger, log_type, 'info')( 28 | f'{[module_name.upper()]} ' 29 | f'{user_information}' 30 | f'{message}' 31 | ) 32 | 33 | return log 34 | -------------------------------------------------------------------------------- /omniport/core/utils/slack.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from django.core.exceptions import ImproperlyConfigured 3 | 4 | from omniport.settings.configuration.base import CONFIGURATION 5 | 6 | 7 | def get_slack_md_section(md_text): 8 | """ 9 | This function wraps a markdown string as a slack markdown section 10 | :param md_text: markdown_text 11 | :return: Slack section block 12 | """ 13 | return { 14 | 'type': 'section', 15 | 'text': { 16 | 'type': 'mrkdwn', 17 | 'text': md_text 18 | } 19 | } 20 | 21 | 22 | def get_slack_app_config(slack_app): 23 | """ 24 | This function fetches the configuration for a given Slack app 25 | :param slack_app: name of the Slack app 26 | :return: Slack app configuration 27 | """ 28 | 29 | slack = CONFIGURATION.integrations.get('slack', None) 30 | error_message = f'Slack App not configured for {slack_app}' 31 | 32 | if slack: 33 | app_config = slack.get(slack_app, None) 34 | if app_config and app_config.get('url', None): 35 | return app_config 36 | 37 | raise ImproperlyConfigured(error_message) 38 | 39 | raise ImproperlyConfigured(error_message) 40 | 41 | 42 | def send_slack_notification(slack_app, message): 43 | """ 44 | This function is used to send notifications via a Slack app 45 | :param slack_app: name of the Slack app 46 | :param message: formatted notification message for the Slack app 47 | """ 48 | 49 | app_config = get_slack_app_config(slack_app) 50 | 51 | response = requests.post(app_config.get('url'), json=message) 52 | response.raise_for_status() 53 | -------------------------------------------------------------------------------- /omniport/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'omniport.settings') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | 'Couldn\'t import Django. Are you sure it\'s installed and ' 18 | 'available on your PYTHONPATH environment variable? Did you ' 19 | 'forget to activate a virtual environment?' 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /omniport/omniport/__init__.py: -------------------------------------------------------------------------------- 1 | # __ 2 | # __ /\ \__ 3 | # ___ ___ ___ ___ /\_\ __ _____ ___ _ __\ \ ,_\ 4 | # / __`\ /' __` __`\ /' _ `\/\ \/\_\ /\ '__`\ / __`\/\`'__\ \ \/ 5 | # /\ \L\ \/\ \/\ \/\ \/\ \/\ \ \ \/_/_\ \ \L\ \/\ \L\ \ \ \/ \ \ \_ 6 | # \ \____/\ \_\ \_\ \_\ \_\ \_\ \_\/\_\\ \ ,__/\ \____/\ \_\ \ \__\ 7 | # \/___/ \/_/\/_/\/_/\/_/\/_/\/_/\/_/ \ \ \/ \/___/ \/_/ \/__/ 8 | # ______ \ \ \ 9 | # /\_____\ \ \_\ 10 | # \/_____/ \/_/ 11 | # 12 | -------------------------------------------------------------------------------- /omniport/omniport/admin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/admin/__init__.py -------------------------------------------------------------------------------- /omniport/omniport/asgi/__init__.py: -------------------------------------------------------------------------------- 1 | from omniport.asgi.asgi import application 2 | -------------------------------------------------------------------------------- /omniport/omniport/asgi/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for Omniport. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | http://channels.readthedocs.io/en/latest/deploying.html 8 | """ 9 | 10 | import os 11 | 12 | import django 13 | from channels.routing import get_default_application 14 | 15 | # Set the Django environment with the settings module 16 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', "omniport.settings") 17 | 18 | # Since this is not the Django-backed WSGI spec, we need to configure Django 19 | django.setup() 20 | 21 | # Return the ASGI application 22 | application = get_default_application() 23 | -------------------------------------------------------------------------------- /omniport/omniport/celery/__init__.py: -------------------------------------------------------------------------------- 1 | from .celery import app as celery_app 2 | -------------------------------------------------------------------------------- /omniport/omniport/celery/celery.py: -------------------------------------------------------------------------------- 1 | import os 2 | from celery import Celery 3 | 4 | # set the default Django settings module for the 'celery' program. 5 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'omniport.settings') 6 | 7 | app = Celery('omniport') 8 | 9 | # Using a string here means the worker doesn't have to serialize 10 | # the configuration object to child processes. 11 | # - namespace='CELERY' means all celery-related configuration keys 12 | # should have a `CELERY_` prefix. 13 | app.config_from_object('django.conf:settings', namespace='CELERY') 14 | 15 | # Load task modules from all registered Django app configs. 16 | app.autodiscover_tasks() 17 | 18 | 19 | @app.task(bind=True) 20 | def debug_task(self): 21 | print('Request: {0!r}'.format(self.request)) 22 | -------------------------------------------------------------------------------- /omniport/omniport/context/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/context/__init__.py -------------------------------------------------------------------------------- /omniport/omniport/context/branding.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | from configuration.serializers.project.branding import BrandSerializer 4 | from configuration.serializers.project.site import SiteSerializer 5 | 6 | 7 | def branding_site(_=None): 8 | """ 9 | Add the branding of the site to the context 10 | :param _: the request being served 11 | :return: the data to add to the context 12 | """ 13 | 14 | data = { 15 | 'site': SiteSerializer(settings.SITE).data, 16 | } 17 | return data 18 | 19 | 20 | def branding_maintainers(_=None): 21 | """ 22 | Add the branding of the maintainers to the context 23 | :param _: the request being served 24 | :return: the data to add to the context 25 | """ 26 | 27 | data = { 28 | 'maintainers': BrandSerializer(settings.MAINTAINERS).data, 29 | } 30 | return data 31 | 32 | 33 | def branding_institute(_=None): 34 | """ 35 | Add the branding of the institute to the context 36 | :param _: the request being served 37 | :return: the data to add to the context 38 | """ 39 | 40 | data = { 41 | 'institute': BrandSerializer(settings.INSTITUTE).data, 42 | } 43 | return data 44 | -------------------------------------------------------------------------------- /omniport/omniport/middleware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/middleware/__init__.py -------------------------------------------------------------------------------- /omniport/omniport/middleware/last_seen.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from session_auth.models import SessionMap 4 | 5 | 6 | class LastSeen: 7 | """ 8 | Set the datetime_modified attribute of the SessionMap object if request is 9 | authenticated 10 | """ 11 | 12 | def __init__(self, get_response): 13 | """ 14 | Write the __init__ function exactly as the Django documentations says 15 | """ 16 | 17 | self.get_response = get_response 18 | 19 | def __call__(self, request): 20 | """ 21 | Perform the actual processing on the request before it goes to the view 22 | and on the response returned by the view 23 | :param request: the request being processed 24 | :return: the processed response 25 | """ 26 | 27 | if request.user and request.user.is_authenticated: 28 | try: 29 | session_key = request.session.session_key 30 | if session_key is not None and not session_key == '': 31 | # Session authentication was used to log in 32 | try: 33 | session_map = SessionMap.objects.get( 34 | session_key=session_key 35 | ) 36 | session_map.datetime_modified = datetime.datetime.now() 37 | session_map.save() 38 | except SessionMap.DoesNotExist: 39 | SessionMap.create_session_map( 40 | request=request, 41 | user=request.user, 42 | new=False 43 | ) 44 | else: 45 | # JWT authentication was used to log in 46 | pass 47 | except AttributeError: 48 | pass 49 | 50 | response = self.get_response(request) 51 | 52 | return response 53 | -------------------------------------------------------------------------------- /omniport/omniport/middleware/person_roles.py: -------------------------------------------------------------------------------- 1 | import swapper 2 | 3 | from kernel.managers.get_role import get_all_roles 4 | 5 | Person = swapper.load_model('kernel', 'Person') 6 | 7 | 8 | class PersonRoles: 9 | """ 10 | Set the person attribute on the request object pointing to the person 11 | attached to the user and the roles attribute on the request object 12 | containing a list of all roles the person has been assigned 13 | """ 14 | 15 | def __init__(self, get_response): 16 | """ 17 | Write the __init__ function exactly as the Django documentations says 18 | """ 19 | 20 | self.get_response = get_response 21 | 22 | def __call__(self, request): 23 | """ 24 | Perform the actual processing on the request before it goes to the view 25 | and on the response returned by the view 26 | :param request: the request being processed 27 | :return: the processed response 28 | """ 29 | 30 | if request.user and request.user.is_authenticated: 31 | try: 32 | person = request.user.person 33 | request.person = person 34 | request.roles = get_all_roles(person) 35 | except Person.DoesNotExist: 36 | request.person = None 37 | request.roles = None 38 | else: 39 | request.person = None 40 | request.roles = None 41 | 42 | response = self.get_response(request) 43 | 44 | return response 45 | -------------------------------------------------------------------------------- /omniport/omniport/routing/__init__.py: -------------------------------------------------------------------------------- 1 | from omniport.routing.routing import application 2 | -------------------------------------------------------------------------------- /omniport/omniport/routing/routing.py: -------------------------------------------------------------------------------- 1 | from channels.auth import AuthMiddlewareStack 2 | from channels.routing import ProtocolTypeRouter, URLRouter 3 | from django.urls import path 4 | 5 | from omniport.urls import ws_urlpatterns 6 | 7 | ws_urlpatterns = [ 8 | path('ws/', URLRouter(ws_urlpatterns)), 9 | ] 10 | 11 | application = ProtocolTypeRouter({ 12 | # http -> Django views is added by default 13 | 'websocket': AuthMiddlewareStack( 14 | URLRouter(ws_urlpatterns) 15 | ), 16 | }) 17 | -------------------------------------------------------------------------------- /omniport/omniport/settings/__init__.py: -------------------------------------------------------------------------------- 1 | from omniport.settings.settings import * 2 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/__init__.py: -------------------------------------------------------------------------------- 1 | from omniport.settings.base.admin import * 2 | from omniport.settings.base.applications import * 3 | from omniport.settings.base.authentication import * 4 | from omniport.settings.base.directories import * 5 | from omniport.settings.base.discovery import * 6 | from omniport.settings.base.files import * 7 | from omniport.settings.base.middleware import * 8 | from omniport.settings.base.models import * 9 | from omniport.settings.base.security import * 10 | from omniport.settings.base.shell import * 11 | from omniport.settings.base.templates import * -------------------------------------------------------------------------------- /omniport/omniport/settings/base/admin.py: -------------------------------------------------------------------------------- 1 | """ 2 | This setting is related to the Django admin site, the complete administrative 3 | panel of the portal for maintenance of data in the database for all apps and 4 | services. 5 | 6 | This settings define the route path to the admin panel 7 | """ 8 | 9 | ADMIN_SITE_URL = 'omnipotence/' 10 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/applications.py: -------------------------------------------------------------------------------- 1 | """ 2 | Omniport serves two application entry points namely a WSGI entry point served 3 | by Gunicorn and an ASGI entry point served by Daphne. 4 | 5 | This setting file exposes these two application paths. 6 | """ 7 | 8 | # WSGI application served by Gunicorn 9 | WSGI_APPLICATION = 'omniport.wsgi.application' 10 | 11 | # ASGI application served by Daphne 12 | ASGI_APPLICATION = 'omniport.routing.application' 13 | 14 | # Primary URLconf served by Gunicorn and Daphne 15 | ROOT_URLCONF = 'omniport.urls' 16 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/authentication.py: -------------------------------------------------------------------------------- 1 | """ 2 | Omniport overrides the default Django user with a custom user defined in the 3 | kernel. This also implies the use of a generalised authentication backend for 4 | said user. 5 | 6 | This setting file exposes variables pertaining to authentication. 7 | """ 8 | 9 | AUTH_USER_MODEL = 'base_auth.User' 10 | 11 | GUEST_USERNAME = 'Guest User' 12 | 13 | AUTHENTICATION_BACKENDS = [ 14 | 'base_auth.backends.generalised.GeneralisedAuthBackend', # Custom backend 15 | 'guardian.backends.ObjectPermissionBackend', # Django Guardian 16 | ] 17 | 18 | # Password validation 19 | # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators 20 | AUTH_PASSWORD_VALIDATORS = [ 21 | { 22 | 'NAME': 'django.contrib.auth.password_validation' 23 | '.UserAttributeSimilarityValidator', 24 | }, 25 | { 26 | 'NAME': 'django.contrib.auth.password_validation' 27 | '.MinimumLengthValidator', 28 | }, 29 | { 30 | 'NAME': 'django.contrib.auth.password_validation' 31 | '.CommonPasswordValidator', 32 | }, 33 | { 34 | 'NAME': 'django.contrib.auth.password_validation' 35 | '.NumericPasswordValidator', 36 | }, 37 | ] 38 | 39 | PASSWORD_HASHERS = [ 40 | 'django.contrib.auth.hashers.Argon2PasswordHasher', 41 | 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 42 | 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 43 | 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', 44 | ] 45 | 46 | SESSION_ENGINE = 'django.contrib.sessions.backends.cache' 47 | SESSION_CACHE_ALIAS = 'session' 48 | 49 | SESSION_COOKIE_NAME = 'omniport_session' 50 | 51 | OAUTH2_PROVIDER_APPLICATION_MODEL = 'open_auth.Application' 52 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/files.py: -------------------------------------------------------------------------------- 1 | """ 2 | This setting file maps Django's file variables and similar variables of our own 3 | to various directories defined in the 'directories' setting file. 4 | """ 5 | 6 | from omniport.settings.base.directories import ( 7 | NETWORK_STORAGE_DIR, 8 | STATIC_DIR, 9 | BRANDING_DIR, 10 | MEDIA_DIR, 11 | PERSONAL_DIR, 12 | ) 13 | 14 | # Network storage files 15 | NETWORK_STORAGE_URL = '/external/' 16 | NETWORK_STORAGE_ROOT = NETWORK_STORAGE_DIR 17 | 18 | # Static files 19 | STATIC_URL = '/static/' 20 | STATIC_ROOT = STATIC_DIR 21 | 22 | # Branding files 23 | BRANDING_URL = '/branding/' 24 | BRANDING_ROOT = BRANDING_DIR 25 | 26 | # Media files 27 | MEDIA_URL = '/media/' 28 | MEDIA_ROOT = MEDIA_DIR 29 | 30 | # Personal files 31 | PERSONAL_URL = '/personal/' 32 | PERSONAL_ROOT = PERSONAL_DIR 33 | 34 | __all__ = [ 35 | 'NETWORK_STORAGE_URL', 36 | 'NETWORK_STORAGE_ROOT', 37 | 'STATIC_URL', 38 | 'STATIC_ROOT', 39 | 'BRANDING_URL', 40 | 'BRANDING_ROOT', 41 | 'MEDIA_URL', 42 | 'MEDIA_ROOT', 43 | 'PERSONAL_URL', 44 | 'PERSONAL_ROOT', 45 | ] 46 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/middleware.py: -------------------------------------------------------------------------------- 1 | """ 2 | Omniport relies on a whole bunch of middleware for pre- and post-view 3 | processing, including Django middleware, third-party middleware and self-written 4 | middleware. 5 | 6 | This settings file exposes the middleware employed in the project. 7 | """ 8 | 9 | MIDDLEWARE = [ 10 | 'corsheaders.middleware.CorsMiddleware', 11 | 12 | 'django.middleware.security.SecurityMiddleware', 13 | 'django.contrib.sessions.middleware.SessionMiddleware', 14 | 'django.middleware.common.CommonMiddleware', 15 | 'django.middleware.csrf.CsrfViewMiddleware', 16 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 17 | 'django.contrib.messages.middleware.MessageMiddleware', 18 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 19 | 20 | 'omniport.middleware.drf_auth.DrfAuth', 21 | 22 | 'omniport.middleware.ip_address_rings.IpAddressRings', 23 | 'omniport.middleware.routes_control.RoutesControl', 24 | 'omniport.middleware.person_roles.PersonRoles', 25 | 'omniport.middleware.last_seen.LastSeen', 26 | 'omniport.middleware.routes_control_roles.RoutesControlRoles' 27 | ] 28 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/models.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes the configuration settings for the models and its fields. 3 | """ 4 | 5 | DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' 6 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/security.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file defines the security options for Omniport 3 | """ 4 | 5 | SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') 6 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/shell.py: -------------------------------------------------------------------------------- 1 | """ 2 | Nearly every aspect of Omniport can be overridden with a shell. Shell provides a 3 | way to override Omniport in a progressive way, only customising the aspects that 4 | need to be altered. 5 | 6 | This settings file exposes a variable indicated whether a shell has been 7 | installed in the current Omniport configuration. 8 | """ 9 | 10 | SHELL_PRESENT = False 11 | try: 12 | from shell.apps import ShellConfig 13 | 14 | # Shell has been installed 15 | SHELL_PRESENT = True 16 | except ImportError: 17 | # Shell has not been installed 18 | pass 19 | 20 | __all__ = [ 21 | 'SHELL_PRESENT' 22 | ] 23 | -------------------------------------------------------------------------------- /omniport/omniport/settings/base/templates.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes the configuration settings for templates. 3 | """ 4 | 5 | import os 6 | 7 | from omniport.settings.base.directories import PROJECT_DIR, OMNIPORT_DIR 8 | 9 | TEMPLATES = [ 10 | { 11 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 12 | 'DIRS': [ 13 | os.path.join(PROJECT_DIR, 'templates'), 14 | os.path.join(OMNIPORT_DIR, 'templates'), 15 | ], 16 | 'APP_DIRS': True, 17 | 'OPTIONS': { 18 | 'context_processors': [ 19 | 'django.template.context_processors.debug', 20 | 'django.template.context_processors.request', 21 | 'django.contrib.auth.context_processors.auth', 22 | 'django.contrib.messages.context_processors.messages', 23 | 'omniport.context.branding.branding_site', 24 | 'omniport.context.branding.branding_maintainers', 25 | 'omniport.context.branding.branding_institute', 26 | ], 27 | }, 28 | }, 29 | ] 30 | 31 | __all__ = [ 32 | 'TEMPLATES', 33 | ] 34 | -------------------------------------------------------------------------------- /omniport/omniport/settings/configuration/__init__.py: -------------------------------------------------------------------------------- 1 | from omniport.settings.configuration.allowances import * 2 | from omniport.settings.configuration.branding import * 3 | from omniport.settings.configuration.i18n import * 4 | from omniport.settings.configuration.integrations import * 5 | from omniport.settings.configuration.secrets import * 6 | from omniport.settings.configuration.emails import * 7 | from omniport.settings.configuration.services import * 8 | from omniport.settings.configuration.site import * 9 | from omniport.settings.configuration.logging import * 10 | -------------------------------------------------------------------------------- /omniport/omniport/settings/configuration/allowances.py: -------------------------------------------------------------------------------- 1 | """ 2 | Omniport allows configuring the allowed hosts, apps and IP addresses via 3 | external YAML files. 4 | 5 | This settings file exposes settings pertaining to allowances. 6 | """ 7 | 8 | from omniport.settings.base.discovery import DISCOVERY as _DISCOVERY 9 | from omniport.settings.configuration.base import CONFIGURATION as _CONF 10 | 11 | # Allowed hosts 12 | ALLOWED_HOSTS = _CONF.allowances.hosts 13 | 14 | # Allowed apps 15 | ALLOWED_APPS = _CONF.allowances.apps 16 | 17 | for (_app, _app_configuration) in _DISCOVERY.services: 18 | _app_configuration.is_allowed = True # Hack to allow all services 19 | 20 | for (_app, _app_configuration) in _DISCOVERY.apps: 21 | if ( 22 | ALLOWED_APPS == '__all__' 23 | or _app_configuration.nomenclature.name in ALLOWED_APPS 24 | ): 25 | _app_configuration.is_allowed = True 26 | else: 27 | _app_configuration.is_allowed = False 28 | 29 | # IP address rings 30 | IP_ADDRESS_RINGS = dict() 31 | _ip_address_rings = _CONF.ip_address_rings 32 | 33 | for _ip_address_ring in _ip_address_rings: 34 | _name = _ip_address_ring.name 35 | _patterns = _ip_address_ring.patterns 36 | IP_ADDRESS_RINGS[_name] = _patterns 37 | 38 | ALLOWED_IP_ADDRESS_RINGS = _CONF.allowances.ip_address_rings 39 | if ALLOWED_IP_ADDRESS_RINGS == '__all__': 40 | ALLOWED_IP_ADDRESS_RINGS = list(IP_ADDRESS_RINGS.keys()) 41 | -------------------------------------------------------------------------------- /omniport/omniport/settings/configuration/branding.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes the names and home pages of the institute and the 3 | maintainers. 4 | """ 5 | 6 | from omniport.settings.configuration.base import CONFIGURATION as _CONF 7 | 8 | INSTITUTE = _CONF.branding.institute 9 | 10 | MAINTAINERS = _CONF.branding.maintainers 11 | -------------------------------------------------------------------------------- /omniport/omniport/settings/configuration/emails.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes critical configurations for email service. 3 | """ 4 | 5 | from omniport.settings.configuration.base import CONFIGURATION as _CONF 6 | 7 | EMAIL_BACKEND = _CONF.emails.email_backend 8 | EMAIL_HOST = _CONF.emails.email_host 9 | EMAIL_USE_TLS = _CONF.emails.email_use_tls 10 | EMAIL_PORT = _CONF.emails.email_port 11 | EMAIL_HOST_USER = _CONF.emails.email_host_user 12 | EMAIL_HOST_PASSWORD = _CONF.emails.email_host_password 13 | -------------------------------------------------------------------------------- /omniport/omniport/settings/configuration/i18n.py: -------------------------------------------------------------------------------- 1 | """ 2 | Internationalisation i18n (lowercase i to differentiate it from 1) and 3 | localisation L10n (uppercase L to differentiate it from 1) are used to open 4 | the app to a broader global audience. 5 | 6 | Omniport supports and enables both i18n and L10n by default. 7 | 8 | This settings file exposes the variables for enabling i18n and L10n. 9 | """ 10 | 11 | from omniport.settings.configuration.base import CONFIGURATION as _CONF 12 | 13 | USE_I18N = True 14 | USE_L10N = True 15 | USE_TZ = True 16 | 17 | LANGUAGE_CODE = _CONF.i18n.language_code 18 | TIME_ZONE = _CONF.i18n.time_zone 19 | -------------------------------------------------------------------------------- /omniport/omniport/settings/configuration/integrations.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file connects Django to various integrations for various purposes 3 | such as Sentry for error-logging or Grafana for monitoring, to name a few. 4 | """ 5 | 6 | import sentry_sdk 7 | from sentry_sdk.integrations.django import DjangoIntegration 8 | 9 | from omniport.settings.configuration.base import CONFIGURATION as _CONF 10 | 11 | # Sentry 12 | if 'sentry' in _CONF.integrations: 13 | sentry_sdk.init( 14 | dsn=_CONF.integrations.get('sentry').get('dsn'), 15 | integrations=[ 16 | DjangoIntegration(), 17 | ], 18 | ) 19 | -------------------------------------------------------------------------------- /omniport/omniport/settings/configuration/secrets.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes critical secrets of the instance. 3 | """ 4 | 5 | from omniport.settings.configuration.base import CONFIGURATION as _CONF 6 | 7 | # This key, as implied by the name, should be a well-protected secret 8 | SECRET_KEY = _CONF.secrets.secret_key 9 | -------------------------------------------------------------------------------- /omniport/omniport/settings/configuration/site.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes variables pertaining to the current site such as 3 | codename and verbose name. 4 | """ 5 | 6 | from omniport.settings.configuration.base import CONFIGURATION as _CONF 7 | 8 | SITE = _CONF.site 9 | 10 | # Should be True in testing environments and False otherwise 11 | DEBUG = _CONF.site.debug 12 | -------------------------------------------------------------------------------- /omniport/omniport/settings/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | This setting file imports all settings from various setting files and then some. 3 | """ 4 | 5 | from omniport.settings.base import * # Hardcoded settings 6 | from omniport.settings.configuration import * # Settings parsed from YAML files 7 | from omniport.settings.third_party import * # Settings for PyPI packages 8 | 9 | if DEBUG: 10 | REST_FRAMEWORK['DEFAULT_RENDERER_CLASSES'] += ( 11 | 'rest_framework.renderers.BrowsableAPIRenderer', 12 | ) 13 | else: 14 | SESSION_COOKIE_SECURE = True 15 | 16 | # Import shell models to replace swappable models from other apps 17 | if SHELL_PRESENT: 18 | from shell.swapper_replacements import * 19 | 20 | # Roles 21 | ROLES = list() 22 | 23 | # Serializers 24 | from kernel.serializers.registration import * 25 | 26 | if SHELL_PRESENT: 27 | from shell.serializers.registration import * 28 | 29 | FILE_UPLOAD_HANDLERS = [ 30 | 'django.core.files.uploadhandler.TemporaryFileUploadHandler', 31 | ] 32 | -------------------------------------------------------------------------------- /omniport/omniport/settings/third_party/__init__.py: -------------------------------------------------------------------------------- 1 | from omniport.settings.third_party.celery import * 2 | from omniport.settings.third_party.cors import * 3 | from omniport.settings.third_party.drf import * 4 | from omniport.settings.third_party.guardian import * 5 | from omniport.settings.third_party.jwt import * 6 | from omniport.settings.third_party.mptt import * 7 | from omniport.settings.third_party.tinymce import * 8 | -------------------------------------------------------------------------------- /omniport/omniport/settings/third_party/celery.py: -------------------------------------------------------------------------------- 1 | from omniport.settings.configuration.base import CONFIGURATION as _CONF 2 | 3 | # Celery configuration 4 | 5 | CELERY_BROKER_URL = ( 6 | f'amqp://' 7 | f'{_CONF.services.message_broker.user}' 8 | f':{_CONF.services.message_broker.password}' 9 | f'@{_CONF.services.message_broker.host}' 10 | f':{_CONF.services.message_broker.port}' 11 | ) 12 | 13 | # CELERY_RESULT_BACKEND = 'django-cache' 14 | 15 | CELERY_TASK_SERIALIZER = 'json' 16 | 17 | CELERY_RESULT_SERIALIZER = 'json' 18 | 19 | CELERY_TIMEZONE = _CONF.i18n.time_zone 20 | 21 | CELERY_RESULT_BACKEND = 'django-cache' 22 | 23 | CELERY_TASK_TIME_LIMIT = 15*60 24 | 25 | -------------------------------------------------------------------------------- /omniport/omniport/settings/third_party/cors.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes settings for CORS headers 3 | """ 4 | 5 | CORS_ALLOW_CREDENTIALS = False 6 | CORS_ORIGIN_WHITELIST = list() 7 | CORS_ORIGIN_ALLOW_ALL = False 8 | -------------------------------------------------------------------------------- /omniport/omniport/settings/third_party/drf.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes settings for Django REST framework 3 | """ 4 | 5 | REST_FRAMEWORK = { 6 | 'DEFAULT_AUTHENTICATION_CLASSES': ( 7 | 'rest_framework_simplejwt.authentication.JWTAuthentication', 8 | 'rest_framework.authentication.SessionAuthentication', 9 | ), 10 | 'DEFAULT_PARSER_CLASSES': ( 11 | 'djangorestframework_camel_case.parser.CamelCaseJSONParser', 12 | 'djangorestframework_camel_case.parser.CamelCaseFormParser', 13 | 'djangorestframework_camel_case.parser.CamelCaseMultiPartParser', 14 | 'rest_framework.parsers.JSONParser', 15 | 'rest_framework.parsers.FormParser', 16 | 'rest_framework.parsers.MultiPartParser', 17 | ), 18 | 'DEFAULT_RENDERER_CLASSES': ( 19 | 'djangorestframework_camel_case.render.CamelCaseJSONRenderer', 20 | 'rest_framework.renderers.JSONRenderer', 21 | ), 22 | 'DEFAULT_FILTER_BACKENDS': ( 23 | 'django_filters.rest_framework.DjangoFilterBackend', 24 | ), 25 | 'DEFAULT_PAGINATION_CLASS': ( 26 | 'rest_framework.pagination.PageNumberPagination' # No commas 27 | ), 28 | 'PAGE_SIZE': 10, 29 | } 30 | -------------------------------------------------------------------------------- /omniport/omniport/settings/third_party/guardian.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings files exposes settings for the Django guardian package 3 | """ 4 | 5 | GUARDIAN_MONKEY_PATCH = False 6 | 7 | ANONYMOUS_USER_NAME = 'guardian_anon' 8 | -------------------------------------------------------------------------------- /omniport/omniport/settings/third_party/jwt.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes settings for Simple JWT 3 | """ 4 | 5 | import datetime as _datetime 6 | 7 | SIMPLE_JWT = { 8 | 'ACCESS_TOKEN_LIFETIME': _datetime.timedelta(days=1), 9 | 'REFRESH_TOKEN_LIFETIME': _datetime.timedelta(weeks=26), 10 | } 11 | -------------------------------------------------------------------------------- /omniport/omniport/settings/third_party/mptt.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes settings for Django MPTT 3 | """ 4 | 5 | MPTT_ADMIN_LEVEL_INDENT = 20 6 | -------------------------------------------------------------------------------- /omniport/omniport/settings/third_party/tinymce.py: -------------------------------------------------------------------------------- 1 | """ 2 | This settings file exposes settings for TinyMCE 3 | """ 4 | 5 | TINYMCE_DEFAULT_CONFIG = { 6 | 'plugins': 'contextmenu ' 7 | 'lists link table image codesample charmap ' 8 | 'fullscreen ' 9 | 'wordcount', 10 | 'contextmenu': 'bold italic underline strikethrough ' 11 | 'superscript subscript ' 12 | 'link', 13 | 'toolbar1': 'formatselect ' 14 | '| bold italic underline strikethrough blockquote removeformat ' 15 | '| alignleft aligncenter alignright alignjustify', 16 | 'toolbar2': 'undo redo ' 17 | '| bullist numlist outdent indent ' 18 | '| link unlink ' 19 | '| table image codesample charmap ' 20 | '| fullscreen', 21 | 'height': 512, 22 | 'width': 'auto', 23 | 'menubar': False, 24 | 'branding': False, 25 | } 26 | -------------------------------------------------------------------------------- /omniport/omniport/static/@fullcalendar/semantic.fullCalendar.css: -------------------------------------------------------------------------------- 1 | .fc-day-number { 2 | color: #3a87ad; 3 | color: #3a87ad; 4 | } 5 | 6 | .fc-widget-content { 7 | background-color: #ffffff; 8 | } 9 | 10 | .fc-day-header { 11 | background-color: #f2f4f7; 12 | } 13 | 14 | .fc-toolbar-chunk { 15 | height: 40px; 16 | } 17 | 18 | .fc-button-group { 19 | box-shadow: none; 20 | border-radius: 0.28571429rem !important; 21 | } 22 | 23 | .fc-today-button { 24 | border-radius: 0.28571429rem !important; 25 | } 26 | 27 | .fc-button { 28 | font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif !important; 29 | border: 1px solid rgba(34,36,38,.15) !important; 30 | box-shadow: none !important; 31 | background: #fff !important; 32 | color: rgba(0,0,0,.8) !important; 33 | height: 40px; 34 | padding: 0px 21px 0px 21px !important; 35 | } 36 | 37 | .fc-button:active { 38 | background-color: rgba(74, 75, 77, 0.35) !important; 39 | } -------------------------------------------------------------------------------- /omniport/omniport/static/errors/dart.svg: -------------------------------------------------------------------------------- 1 | Asset 3 -------------------------------------------------------------------------------- /omniport/omniport/static/errors/dart_stuck.svg: -------------------------------------------------------------------------------- 1 | Asset 3 -------------------------------------------------------------------------------- /omniport/omniport/static/errors/dartboard.svg: -------------------------------------------------------------------------------- 1 | Asset 2 -------------------------------------------------------------------------------- /omniport/omniport/static/omniport/css/layout.css: -------------------------------------------------------------------------------- 1 | html { 2 | } 3 | 4 | /* General layout of the page */ 5 | 6 | body { 7 | margin: 0; 8 | padding: 0; 9 | height: 100%; 10 | display: flex; 11 | flex-direction: column; 12 | } 13 | 14 | body > * { 15 | flex-shrink: 0; 16 | } 17 | 18 | header { 19 | flex-grow: 0; 20 | padding: 1em; 21 | } 22 | 23 | main { 24 | flex-grow: 1; 25 | display: flex; 26 | justify-content: center; 27 | align-items: center; 28 | } 29 | 30 | footer { 31 | flex-grow: 0; 32 | padding: 1em; 33 | } 34 | 35 | /* Customisations in the title bar */ 36 | 37 | #title-bar { 38 | display: flex; 39 | flex-direction: row; 40 | align-items: center; 41 | justify-content: space-between; 42 | } 43 | 44 | #site-name { 45 | margin: 0; 46 | } 47 | 48 | #institute { 49 | flex-grow: 0; 50 | margin-right: 1em; 51 | } 52 | 53 | #institute-logo { 54 | margin: 0; 55 | } 56 | 57 | .title-bar-logo { 58 | height: 3.5em; 59 | } 60 | 61 | /* Customisations in the main section */ 62 | 63 | main .ui.container .ui.segment { 64 | margin: 2em; 65 | width: 500px; 66 | max-width: 90%; 67 | } 68 | 69 | /* Customisations in the footer */ 70 | 71 | #end-bar { 72 | display: flex; 73 | flex-direction: row; 74 | align-items: center; 75 | } 76 | 77 | #maintainers-logo { 78 | height: 16px; 79 | margin-left: 0.5em; 80 | margin-right: 0.5em; 81 | vertical-align: middle; 82 | } -------------------------------------------------------------------------------- /omniport/omniport/static/omniport/css/styling.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #fafafa; 3 | } 4 | 5 | a { 6 | color: black; 7 | } -------------------------------------------------------------------------------- /omniport/omniport/static/react-semantic-toasts/react-semantic-alert.css: -------------------------------------------------------------------------------- 1 | .ui-alerts { 2 | position: fixed; 3 | z-index: 2060; 4 | padding: 23px; 5 | } 6 | 7 | .ui-alerts.center { 8 | top: 50%; 9 | left: 50%; 10 | margin-top: -100px; 11 | margin-left: -222px; 12 | } 13 | 14 | .ui-alerts.top-right { 15 | top: 20px; 16 | right: 20px; 17 | } 18 | 19 | .ui-alerts.top-center { 20 | top: 20px; 21 | margin-left: -222px; 22 | left: 50%; 23 | } 24 | 25 | .ui-alerts.top-left { 26 | top: 20px; 27 | left: 20px; 28 | } 29 | 30 | .ui-alerts.bottom-right { 31 | bottom: 0; 32 | right: 20px; 33 | } 34 | .ui-alerts.bottom-center { 35 | bottom: 0; 36 | margin-left: -222px; 37 | left: 50%; 38 | } 39 | 40 | .ui-alerts.bottom-left { 41 | bottom: 0; 42 | left: 20px; 43 | } 44 | 45 | .ui-alerts.ui-alerts > .message > .content > .header { 46 | padding-right: 13px; 47 | } 48 | 49 | @media (min-width: 320px) { 50 | /* smartphones, portrait iPhone, portrait 480x320 phones (Android) */ 51 | .ui-alerts.top-center { 52 | margin-left: -163px; 53 | } 54 | } 55 | @media (min-width: 480px) { 56 | /* smartphones, Android phones, landscape iPhone */ 57 | } 58 | @media (min-width: 600px) { 59 | /* portrait tablets, portrait iPad, e-readers (Nook/Kindle), landscape 800x480 phones 60 | * (Android) */ 61 | } 62 | @media (min-width: 801px) { 63 | /* tablet, landscape iPad, lo-res laptops ands desktops */ 64 | } 65 | @media (min-width: 1025px) { 66 | /* big landscape tablets, laptops, and desktops */ 67 | } 68 | @media (min-width: 1281px) { 69 | /* hi-res laptops and desktops */ 70 | } 71 | -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/semantic.fix.css: -------------------------------------------------------------------------------- 1 | /* I'm sorry. */ 2 | /* Fuck you Semantic UI! */ 3 | .ui.form textarea { 4 | font-family: inherit; 5 | } 6 | 7 | /* Unhide images in mobile view of Semantic UI cards */ 8 | @media only screen and (max-width: 767px) { 9 | .ui.stackable.cards > .card { 10 | display: flex !important; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/brand-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/brand-icons.eot -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/brand-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/brand-icons.ttf -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/brand-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/brand-icons.woff -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/brand-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/brand-icons.woff2 -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.eot -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.otf -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.ttf -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.woff -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/icons.woff2 -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/outline-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/outline-icons.eot -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/outline-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/outline-icons.ttf -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/outline-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/outline-icons.woff -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/fonts/outline-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/fonts/outline-icons.woff2 -------------------------------------------------------------------------------- /omniport/omniport/static/semantic-ui/themes/default/assets/images/flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/static/semantic-ui/themes/default/assets/images/flags.png -------------------------------------------------------------------------------- /omniport/omniport/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block title %}404: Not found{% endblock %} 4 | 5 | {% block box_content %} 6 |

404: Foundn't

7 |

Now that could be anyone's fault.

8 |
9 | 10 | 11 |

12 |

13 | If that was our link you followed we are sorry. In fact, we've been 14 | notified and are already working on it. 15 |

16 |

17 | But if it was a link from a third party, please inform them that their 18 | link's broken. Maybe they'll fix it. 19 |

20 | 23 | {% endblock %} -------------------------------------------------------------------------------- /omniport/omniport/templates/500.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block title %}500: Server error{% endblock %} 4 | 5 | {% block box_content %} 6 |

500: I II II L

7 |

Now that is most certainly our fault.

8 |
9 | 10 | 11 |

12 |

13 | This is as embarrassing for us as it is confusing for you. We've been 14 | notified and are already working on it. 15 |

16 |

17 | If you think an invalid input of yours caused this, please hit yourself, 18 | go back and redo whatever you were doing, correctly this time. 19 |

20 | {% endblock %} -------------------------------------------------------------------------------- /omniport/omniport/templates/maintenance.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block title %}Routine maintenance{% endblock %} 4 | 5 | {% block box_content %} 6 |

Routine maintenance

7 |

Prevention is better than cure.

8 |
9 | 10 | 11 | 12 | 13 |

14 |

15 | We are just running routine maintenance and will be back shortly. We 16 | thank you for your patience. 17 |

18 |

19 | While we deeply regret any inconvenience this may have caused, you do 20 | understand the importance of periodic housekeeping. 21 |

22 | {% endblock %} -------------------------------------------------------------------------------- /omniport/omniport/urls/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Omniport URL Configuration 3 | 4 | The `urlpatterns` list routes URLs to views. 5 | Likewise, the `ws_urlpatterns` list routes URLs to consumers. 6 | """ 7 | 8 | from omniport.urls.urls import http_urlpatterns as urlpatterns 9 | from omniport.urls.urls import ws_urlpatterns 10 | -------------------------------------------------------------------------------- /omniport/omniport/urls/http_urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from django.conf import settings 3 | 4 | from omniport.admin.site import omnipotence 5 | 6 | http_urlpatterns = [ 7 | # Django admin URL dispatcher 8 | path(settings.ADMIN_SITE_URL, omnipotence.urls), 9 | 10 | # PyPI packages URL dispatcher 11 | path('tinymce/', include('tinymce.urls')), 12 | 13 | # The almighty swappable kernel 14 | path('kernel/', include('kernel.http_urls')), 15 | 16 | # Authentication 17 | path('base_auth/', include('base_auth.http_urls')), 18 | path('session_auth/', include('session_auth.http_urls')), 19 | path('token_auth/', include('token_auth.http_urls')), 20 | path('open_auth/', include('open_auth.http_urls')), 21 | path('guest_auth/', include('guest_auth.http_urls')), 22 | 23 | # Bootstrapping 24 | path('bootstrap/', include('bootstrap.http_urls')), 25 | ] 26 | 27 | http_urlpatterns_fallthrough = [ 28 | # Formula 1 29 | path('', include('formula_one.http_urls')), 30 | ] 31 | -------------------------------------------------------------------------------- /omniport/omniport/urls/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.conf.urls.static import static 3 | 4 | from omniport.urls.http_urls import ( 5 | http_urlpatterns, 6 | http_urlpatterns_fallthrough, 7 | ) 8 | from omniport.urls.ws_urls import ws_urlpatterns 9 | 10 | settings.DISCOVERY.prepare_urlpatterns() 11 | 12 | http_urlpatterns += settings.DISCOVERY.service_http_urlpatterns 13 | http_urlpatterns += settings.DISCOVERY.app_http_urlpatterns 14 | http_urlpatterns += http_urlpatterns_fallthrough 15 | 16 | ws_urlpatterns += settings.DISCOVERY.service_ws_urlpatterns 17 | ws_urlpatterns += settings.DISCOVERY.app_ws_urlpatterns 18 | 19 | if settings.DEBUG: 20 | http_urlpatterns += static( 21 | settings.NETWORK_STORAGE_URL, 22 | document_root=settings.NETWORK_STORAGE_ROOT 23 | ) 24 | http_urlpatterns += static( 25 | settings.MEDIA_URL, 26 | document_root=settings.MEDIA_ROOT 27 | ) 28 | http_urlpatterns += static( 29 | settings.BRANDING_URL, 30 | document_root=settings.BRANDING_ROOT 31 | ) 32 | http_urlpatterns += static( 33 | settings.PERSONAL_URL, 34 | document_root=settings.PERSONAL_ROOT 35 | ) 36 | -------------------------------------------------------------------------------- /omniport/omniport/urls/ws_urls.py: -------------------------------------------------------------------------------- 1 | ws_urlpatterns = [ 2 | ] 3 | -------------------------------------------------------------------------------- /omniport/omniport/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/omniport/omniport/utils/__init__.py -------------------------------------------------------------------------------- /omniport/omniport/utils/switcher.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | 3 | from django.conf import settings 4 | 5 | 6 | def load_serializer(app_name, model_name, version_name=None): 7 | """ 8 | This function returns the appropriate serializer class based on the names of 9 | the app, model and version 10 | :param app_name: the name of the app whose model is being serialized 11 | :param model_name: the name of the model being serialized 12 | :param version_name: the name of the serializer if many exist 13 | :return: the serializer class 14 | """ 15 | 16 | app_name = app_name 17 | model_name = model_name 18 | setting_name = f'{app_name}_{model_name}' 19 | if version_name is not None: 20 | setting_name = f'{setting_name}_{version_name}' 21 | setting_name = f'{setting_name}_SERIALIZER'.upper() 22 | 23 | setting = getattr(settings, setting_name, None) 24 | if setting is not None: 25 | module_name, _, class_name = setting.rpartition('.') 26 | module = importlib.import_module(module_name) 27 | dictionary = module.__dict__ 28 | SerializerClass = dictionary[class_name] 29 | return SerializerClass 30 | else: 31 | return None 32 | -------------------------------------------------------------------------------- /omniport/omniport/wsgi/__init__.py: -------------------------------------------------------------------------------- 1 | from omniport.wsgi.wsgi import application 2 | -------------------------------------------------------------------------------- /omniport/omniport/wsgi/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for Omniport. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | # Set the Django environment with the settings module 15 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "omniport.settings") 16 | 17 | # Return the WSGI application 18 | application = get_wsgi_application() 19 | -------------------------------------------------------------------------------- /omniport/services/README.md: -------------------------------------------------------------------------------- 1 | # Services 2 | 3 | > A collection of services that Omniport apps rely on for various utilities 4 | 5 | Omniport has a set of applications that apps depend on for some functionality. 6 | These services must be placed in this folder, `services/`. 7 | 8 | Services are not plug-and-play like apps, and therefore all services must be 9 | cloned in order to ensure that everything works as expected. -------------------------------------------------------------------------------- /omniport/templates/admin/base.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/base.html' %} 2 | {% load i18n static %} 3 | {% block userlinks %} 4 | {% if site_url %} 5 | {% trans 'View site' %} / 6 | {% endif %} 7 | {% if user.is_active and user.is_staff %} 8 | {% url 'django-admindocs-docroot' as docsroot %} 9 | {% if docsroot %} 10 | {% trans 'Documentation' %} / 11 | {% endif %} 12 | {% endif %} 13 | {% if user.has_usable_password %} 14 | {% trans 'Change password' %} / 15 | {% endif %} 16 | {% trans 'Log out' %} 17 | {% endblock %} -------------------------------------------------------------------------------- /omniport/templates/admin/change_form.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/change_form.html' %} 2 | {% load static %} 3 | 4 | {% block admin_change_form_document_ready %} 5 | {{ block.super }} 6 | 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /omniport/templates/rest_framework/api.html: -------------------------------------------------------------------------------- 1 | {% extends 'rest_framework/api.html' %} 2 | {% load i18n %} 3 | 4 | {% block title %} 5 | {% if name %}{{ name }} – {% endif %}{% trans site.nomenclature.verbose_name %} 6 | {% endblock %} 7 | 8 | {% block head %} 9 | {{ block.super }} 10 | 11 | 12 | {% endblock %} 13 | 14 | {% block userlinks %} 15 | {% if request.user.is_authenticated %} 16 | 33 | {% else %} 34 |
  • Log in
  • 35 | {% endif %} 36 | {% endblock %} 37 | 38 | {% block branding %} 39 | 40 | {% trans site.nomenclature.verbose_name %} 41 | 42 | {% endblock %} -------------------------------------------------------------------------------- /personal_files/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/personal_files/.gitignore -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "omniport" 3 | version = "0.1.0" 4 | description = "An extensible, customizable, performant and powerful portal for educational institutes." 5 | authors = ["IMG "] 6 | license = "GPL-3.0" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.10" 10 | Django = {extras = ["argon2"], version = "^4.1.5"} 11 | inflection = "^0.5.1" 12 | PyYAML = "^6.0" 13 | celery = "^5.2.3" 14 | firebase-admin = "^5.2.0" 15 | psycopg2-binary = "^2.9.3" 16 | Pillow = "^9.0.1" 17 | gunicorn = "^20.1.0" 18 | channels = "^3.0.4" 19 | channels-redis = "^3.3.1" 20 | djangorestframework = "^3.13.1" 21 | Markdown = "^3.3.6" 22 | django-crispy-forms = "^1.14.0" 23 | django-filter = "^21.1" 24 | django-guardian = "^2.4.0" 25 | djangorestframework-camel-case = "^1.3.0" 26 | djangorestframework-simplejwt = "^5.0.0" 27 | django-cors-headers = "^3.11.0" 28 | django-countries = "^7.2.1" 29 | django-mptt = "^0.13.4" 30 | django-permanent = "^1.1.6" 31 | django-redis = "^5.2.0" 32 | swapper = "^1.3.0" 33 | weasyprint = "^54.1" 34 | django-celery-results = "^2.2.0" 35 | user-agents = "^2.2.0" 36 | django-oauth-toolkit = "^1.7.0" 37 | pydash = "^5.1.0" 38 | sentry-sdk = "^1.5.5" 39 | numpy = "^1.22.2" 40 | pandas = "^1.4.1" 41 | pdf2image = "^1.16.0" 42 | rstr = "^3.0.0" 43 | qrcode = "^7.3.1" 44 | Twisted = {extras = ["http2", "tls"], version = "^22.1.0"} 45 | django-tinymce = "^3.5.0" 46 | pymemcache = "^4.0.0" 47 | 48 | [tool.poetry.dev-dependencies] 49 | ipdb = "^0.13.9" 50 | ipython = "^8.0.1" 51 | pipdeptree = "^2.2.1" 52 | 53 | [build-system] 54 | requires = ["poetry-core>=1.0.0"] 55 | build-backend = "poetry.core.masonry.api" 56 | -------------------------------------------------------------------------------- /scripts/clone/everything.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Clone Shell, with consent 4 | read -p "Clone the shell for IIT Roorkee? (y/N): " CLONE_SHELL 5 | if [ "$CLONE_SHELL" == 'y' -o "$CLONE_SHELL" == 'Y' ]; then 6 | bash ./scripts/clone/shell.sh 7 | else 8 | printf "Skipping Shell\n" 9 | fi 10 | 11 | # Clone Formula 1 12 | bash ./scripts/clone/formula_one.sh 13 | 14 | # Clone services 15 | bash ./scripts/clone/services.sh 16 | -------------------------------------------------------------------------------- /scripts/clone/formula_one.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Import the utility functions 4 | source ./scripts/clone/utils.sh 5 | 6 | # Enter the directory to clone into 7 | cd omniport/ 8 | 9 | # Clone Formula 1 10 | clonerepo "Formula 1" "omniport-backend-formula-one" "formula_one" 11 | -------------------------------------------------------------------------------- /scripts/clone/services.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Import the utility functions 4 | source ./scripts/clone/utils.sh 5 | 6 | # Enter the directory to clone into 7 | cd omniport/services/ 8 | 9 | # Clone services except GIF 10 | clonerepo "Apps" "omniport-service-apps" "apps" 11 | clonerepo "Categories" "omniport-service-categories" "categories" 12 | clonerepo "Comments" "omniport-service-comments" "comments" 13 | clonerepo "Developer" "omniport-service-developer" "developer" 14 | clonerepo "Django Filemanager" "omniport-django-filemanager" "django_filemanager" 15 | clonerepo "Emails" "omniport-service-emails" "emails" 16 | clonerepo "Feed" "omniport-service-feed" "feed" 17 | clonerepo "Groups" "omniport-service-groups" "groups" 18 | clonerepo "Helpcentre" "omniport-service-helpcentre" "helpcentre" 19 | clonerepo "Links" "omniport-service-links" "links" 20 | clonerepo "Maintainer Site" "omniport-service-maintainer-site" "maintainer_site" 21 | clonerepo "Notifications" "omniport-service-notifications" "notifications" 22 | clonerepo "Settings" "omniport-service-settings" "settings" 23 | clonerepo "Yellow pages" "omniport-service-yellow-pages" "yellow_pages" 24 | 25 | # Warn the user about the size of the GIF repository 26 | printf "About to clone GIF, which has a huge size due to its assets\n" 27 | printf "If you are on a slow connection, you can skip the cloning\n" 28 | printf "If you are on a fast connection, clone it for an optimal experience\n" 29 | 30 | # Clone GIF, with consent 31 | read -p "Clone the service GIF? (y/N): " CLONE_GIF 32 | if [ "$CLONE_GIF" == 'y' -o "$CLONE_GIF" == 'Y' ]; then 33 | clonerepo "GIF" "omniport-service-gif" "gif" 34 | else 35 | printf "Skipping GIF\n" 36 | fi 37 | -------------------------------------------------------------------------------- /scripts/clone/shell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Import the utility functions 4 | source ./scripts/clone/utils.sh 5 | 6 | # Enter the directory to clone into 7 | cd omniport/ 8 | 9 | # Clone shell 10 | clonerepo "Shell" "omniport-shell" "shell" 11 | -------------------------------------------------------------------------------- /scripts/clone/utils.sh: -------------------------------------------------------------------------------- 1 | # Encore the given string to a URLencoded format 2 | # 3 | # Syntax: urlencode 4 | urlencode() { 5 | # Preserve current LC_COLLATE 6 | old_lc_collate=$LC_COLLATE 7 | 8 | LC_COLLATE=C 9 | local length="${#1}" 10 | for (( i = 0; i < length; i++ )); do 11 | local c="${1:i:1}" 12 | case $c in 13 | [a-zA-Z0-9.~_-]) printf "$c" ;; 14 | *) printf '%%%02X' "'$c" ;; 15 | esac 16 | done 17 | 18 | # Restore the original value 19 | LC_COLLATE=$old_lc_collate 20 | } 21 | 22 | # Clone the given repository from GitHub 23 | # 24 | # Syntax: clonerepo 25 | clonerepo() { 26 | # Setting required values from arguments 27 | DISPLAY_NAME=$1 28 | REPO_NAME=$2 29 | FOLDER_NAME=$3 30 | 31 | # Clone the given repository 32 | printf "Cloning ${DISPLAY_NAME}... " 33 | git clone https://github.com/IMGIITRoorkee/${REPO_NAME}.git ${FOLDER_NAME} &> /dev/null 34 | printf "done\n" 35 | } 36 | -------------------------------------------------------------------------------- /static_files/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/static_files/.gitignore -------------------------------------------------------------------------------- /supervisor.d/.gitignore: -------------------------------------------------------------------------------- 1 | *.conf 2 | -------------------------------------------------------------------------------- /web_server_logs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/web_server_logs/.gitignore -------------------------------------------------------------------------------- /web_server_logs/server_logs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IMGIITRoorkee/omniport-backend/ff61b7ec404a84f1e681cbb9b2dfec77243584e3/web_server_logs/server_logs/.gitignore --------------------------------------------------------------------------------