diff --git a/.gitignore b/.gitignore index e19940f..7a35e79 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ __pycache__ .vscode build *.d.ts +.env +yarn-error.log diff --git a/package.json b/package.json index 6cb419a..f86fcde 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "main": "index.js", "scripts": { "build": "webpack --progress", - "watch": "TERMINUS_DEV=1 webpack --progress --watch" + "watch": "DEV=1 webpack --progress --watch", + "start": "./manage.py runserver" }, "private": true, "devDependencies": { @@ -19,6 +20,7 @@ "@fortawesome/angular-fontawesome": "0.8", "@fortawesome/fontawesome-free": "^5.7.2", "@fortawesome/fontawesome-svg-core": "^1.2.35", + "@fortawesome/free-brands-svg-icons": "^5.15.3", "@fortawesome/free-solid-svg-icons": "^5.15.3", "@ng-bootstrap/ng-bootstrap": "11.0.0-beta.1", "@ngtools/webpack": "^12.0.4", diff --git a/poetry.lock b/poetry.lock index 01e05f9..bd1f119 100644 --- a/poetry.lock +++ b/poetry.lock @@ -350,6 +350,17 @@ six = ">=1.5.2" docs = ["sphinx", "sphinx-rtd-theme"] test = ["flaky", "pretend", "pytest (>=3.0.1)"] +[[package]] +name = "python-dotenv" +version = "0.17.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "python3-openid" version = "3.2.0" @@ -577,7 +588,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "ddf1bd292c78d2b6919ec1a9eb9b76b48ff4d97e7a20a3a46783dcdbf5ec1163" +content-hash = "8b1f2a003502e099b7a3995cfbbbc413401adf08c391d3b07e749e919916ab85" [metadata.files] asgiref = [ @@ -770,6 +781,10 @@ pyopenssl = [ {file = "pyOpenSSL-20.0.1-py2.py3-none-any.whl", hash = "sha256:818ae18e06922c066f777a33f1fca45786d85edfe71cd043de6379337a7f274b"}, {file = "pyOpenSSL-20.0.1.tar.gz", hash = "sha256:4c231c759543ba02560fcd2480c48dcec4dae34c9da7d3747c508227e0624b51"}, ] +python-dotenv = [ + {file = "python-dotenv-0.17.1.tar.gz", hash = "sha256:b1ae5e9643d5ed987fc57cc2583021e38db531946518130777734f9589b3141f"}, + {file = "python_dotenv-0.17.1-py2.py3-none-any.whl", hash = "sha256:00aa34e92d992e9f8383730816359647f358f4a3be1ba45e5a5cefd27ee91544"}, +] python3-openid = [ {file = "python3-openid-3.2.0.tar.gz", hash = "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf"}, {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"}, diff --git a/pyproject.toml b/pyproject.toml index 3eae99c..06c847e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ channels = "^3.0.3" uvloop = "^0.15.2" djangorestframework-dataclasses = "^0.9" social-auth-app-django = "^4.0.0" +python-dotenv = "^0.17.1" [tool.poetry.dev-dependencies] flake8 = "^3.9.2" diff --git a/src/components/app.component.pug b/src/components/app.component.pug index b36a2dc..63f69d5 100644 --- a/src/components/app.component.pug +++ b/src/components/app.component.pug @@ -1,2 +1,10 @@ main(*ngIf='ready && user') -login(*ngIf='ready && !user') +.login-view(*ngIf='ready && !user') + .buttons + a.btn( + *ngFor='let provider of providers', + [class]='provider.cls', + href='/api/1/auth/social/login/{{provider.id}}' + ) + fa-icon([icon]='provider.icon', [fixedWidth]='true') + span Log in with {{provider.name}} diff --git a/src/components/app.component.scss b/src/components/app.component.scss index e69de29..c4cdcbe 100644 --- a/src/components/app.component.scss +++ b/src/components/app.component.scss @@ -0,0 +1,25 @@ +:host { + position: absolute; + left: 0; + top: 0; + width: 100vw; + height: 100vh; + overflow: hidden; + display: flex; +} + +.login-view { + margin: auto; + flex: none; +} + +.buttons > * { + min-width: 200px; + display: flex; + align-items: center; + margin-bottom: 10px; + + >span { + margin: auto; + } +} diff --git a/src/components/app.component.ts b/src/components/app.component.ts index 34f6da9..e0d0e93 100644 --- a/src/components/app.component.ts +++ b/src/components/app.component.ts @@ -1,6 +1,8 @@ import { Component } from '@angular/core' import { HttpClient } from '@angular/common/http' +import { faGithub, faGitlab, faGoogle, faMicrosoft } from '@fortawesome/free-brands-svg-icons' + @Component({ selector: 'app', templateUrl: './app.component.pug', @@ -10,6 +12,13 @@ export class AppComponent { user: any ready = false + providers = [ + { name: 'GitHub', icon: faGithub, cls: 'btn-primary', id: 'github' }, + { name: 'GitLab', icon: faGitlab, cls: 'btn-warning', id: 'gitlab' }, + { name: 'Google', icon: faGoogle, cls: 'btn-secondary', id: 'google-oauth2' }, + { name: 'Microsoft', icon: faMicrosoft, cls: 'btn-light', id: 'microsoft-graph' }, + ] + constructor ( private http: HttpClient, ) { } diff --git a/terminus/settings.py b/terminus/settings.py index c3f7f39..e62e8ff 100644 --- a/terminus/settings.py +++ b/terminus/settings.py @@ -1,17 +1,9 @@ -""" -Django settings for terminus project. - -Generated by 'django-admin startproject' using Django 3.2.3. - -For more information on this file, see -https://docs.djangoproject.com/en/3.2/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.2/ref/settings/ -""" - +import os +from dotenv import load_dotenv from pathlib import Path +load_dotenv() + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -25,7 +17,7 @@ SECRET_KEY = 'django-insecure-jw3fshufj(1$iv+&9bie=r%27+^e2sz0!_gq38*5p5!csrm&#s # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ['*'] # Application definition @@ -135,4 +127,27 @@ CSRF_COOKIE_HTTPONLY = False CSRF_COOKIE_NAME = 'XSRF-TOKEN' CSRF_HEADER_NAME = 'HTTP_X_XSRF_TOKEN' +AUTHENTICATION_BACKENDS = ( + 'social_core.backends.github.GithubOAuth2', + 'social_core.backends.gitlab.GitLabOAuth2', + 'social_core.backends.azuread.AzureADOAuth2', + 'social_core.backends.microsoft.MicrosoftOAuth2', + 'social_core.backends.google.GoogleOAuth2', + 'django.contrib.auth.backends.ModelBackend', +) + +LOGIN_REDIRECT_URL = '/' + APP_DIST_PATH = BASE_DIR / 'app-dist' + +for key in [ + 'SOCIAL_AUTH_GITHUB_KEY', + 'SOCIAL_AUTH_GITHUB_SECRET', + 'SOCIAL_AUTH_GITLAB_KEY', + 'SOCIAL_AUTH_GITLAB_SECRET', + 'SOCIAL_AUTH_GOOGLE_OAUTH2_KEY', + 'SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET', + 'SOCIAL_AUTH_MICROSOFT_GRAPH_KEY', + 'SOCIAL_AUTH_MICROSOFT_GRAPH_SECRET', +]: + globals()[key] = os.getenv(key) diff --git a/terminus/urls.py b/terminus/urls.py index 82f16df..acd111b 100644 --- a/terminus/urls.py +++ b/terminus/urls.py @@ -19,6 +19,6 @@ from .app.urls import urlpatterns urlpatterns = [ path('', include(urlpatterns)), - path('', include('social_django.urls', namespace='social')), + path('api/1/auth/social/', include('social_django.urls', namespace='social')), path('admin/', admin.site.urls), ] diff --git a/webpack.main.config.js b/webpack.main.config.js index 1552091..227b09e 100644 --- a/webpack.main.config.js +++ b/webpack.main.config.js @@ -8,7 +8,7 @@ module.exports = { 'index.ignore': 'file-loader?name=index.html!pug-html-loader!' + path.resolve(__dirname, './src/index.pug'), index: path.resolve(__dirname, 'src/index.ts'), }, - mode: process.env.TERMINUS_DEV ? 'development' : 'production', + mode: process.env.DEV ? 'development' : 'production', context: __dirname, devtool: 'cheap-module-source-map', output: { diff --git a/webpack.terminal.config.js b/webpack.terminal.config.js index c72c931..9bd6dbd 100644 --- a/webpack.terminal.config.js +++ b/webpack.terminal.config.js @@ -8,7 +8,7 @@ module.exports = { 'terminal.ignore': 'file-loader?name=terminal.html!pug-html-loader!' + path.resolve(__dirname, './src/terminal.pug'), terminal: path.resolve(__dirname, 'src/terminal.ts'), }, - mode: process.env.TERMINUS_DEV ? 'development' : 'production', + mode: process.env.DEV ? 'development' : 'production', context: __dirname, devtool: 'cheap-module-source-map', output: { diff --git a/yarn.lock b/yarn.lock index e85963d..8472ea0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -300,6 +300,13 @@ dependencies: "@fortawesome/fontawesome-common-types" "^0.2.35" +"@fortawesome/free-brands-svg-icons@^5.15.3": + version "5.15.3" + resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz#bec2821d23b9c667be1d192a6c5bfb2667e588eb" + integrity sha512-1hirPcbjj72ZJtFvdnXGPbAbpn3Ox6mH3g5STbANFp3vGSiE5u5ingAKV06mK6ZVqNYxUPlh4DlTnaIvLtF2kw== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.35" + "@fortawesome/free-solid-svg-icons@^5.15.3": version "5.15.3" resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz#52eebe354f60dc77e0bde934ffc5c75ffd04f9d8"