Browse Source

Merge pull request #51 from volosoft/k8s-deploy

Deploy to local k8s environment
pull/53/head
Halil İbrahim Kalkan 5 years ago
committed by GitHub
parent
commit
6c49ca6e0a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .gitignore
  2. BIN
      etc/dev-cert/localhost.pfx
  3. 21
      etc/k8s/README.md
  4. 1
      etc/k8s/helm-chart/deploy-azure.ps1
  5. 6
      etc/k8s/helm-chart/eventhub/Chart.yaml
  6. 6
      etc/k8s/helm-chart/eventhub/charts/account/Chart.yaml
  7. 28
      etc/k8s/helm-chart/eventhub/charts/account/templates/account-ingress.yaml
  8. 14
      etc/k8s/helm-chart/eventhub/charts/account/templates/account-service.yaml
  9. 27
      etc/k8s/helm-chart/eventhub/charts/account/templates/account.yaml
  10. 0
      etc/k8s/helm-chart/eventhub/charts/account/values.yaml
  11. 6
      etc/k8s/helm-chart/eventhub/charts/admin-api/Chart.yaml
  12. 26
      etc/k8s/helm-chart/eventhub/charts/admin-api/templates/admin-api-ingress.yaml
  13. 14
      etc/k8s/helm-chart/eventhub/charts/admin-api/templates/admin-api-service.yaml
  14. 27
      etc/k8s/helm-chart/eventhub/charts/admin-api/templates/admin-api.yaml
  15. 0
      etc/k8s/helm-chart/eventhub/charts/admin-api/values.yaml
  16. 6
      etc/k8s/helm-chart/eventhub/charts/admin/Chart.yaml
  17. 28
      etc/k8s/helm-chart/eventhub/charts/admin/templates/admin-ingress.yaml
  18. 14
      etc/k8s/helm-chart/eventhub/charts/admin/templates/admin-service.yaml
  19. 24
      etc/k8s/helm-chart/eventhub/charts/admin/templates/admin.yaml
  20. 0
      etc/k8s/helm-chart/eventhub/charts/admin/values.yaml
  21. 6
      etc/k8s/helm-chart/eventhub/charts/api/Chart.yaml
  22. 26
      etc/k8s/helm-chart/eventhub/charts/api/templates/api-ingress.yaml
  23. 14
      etc/k8s/helm-chart/eventhub/charts/api/templates/api-service.yaml
  24. 27
      etc/k8s/helm-chart/eventhub/charts/api/templates/api.yaml
  25. 0
      etc/k8s/helm-chart/eventhub/charts/api/values.yaml
  26. 6
      etc/k8s/helm-chart/eventhub/charts/background-services/Chart.yaml
  27. 18
      etc/k8s/helm-chart/eventhub/charts/background-services/templates/background-services.yaml
  28. 0
      etc/k8s/helm-chart/eventhub/charts/background-services/values.yaml
  29. 6
      etc/k8s/helm-chart/eventhub/charts/dbmigrator/Chart.yaml
  30. 24
      etc/k8s/helm-chart/eventhub/charts/dbmigrator/templates/migrator.yaml
  31. 0
      etc/k8s/helm-chart/eventhub/charts/dbmigrator/values.yaml
  32. 6
      etc/k8s/helm-chart/eventhub/charts/postgresql/Chart.yaml
  33. 14
      etc/k8s/helm-chart/eventhub/charts/postgresql/templates/postgresql-service.yaml
  34. 43
      etc/k8s/helm-chart/eventhub/charts/postgresql/templates/postgresql.yaml
  35. 0
      etc/k8s/helm-chart/eventhub/charts/postgresql/values.yaml
  36. 6
      etc/k8s/helm-chart/eventhub/charts/redis/Chart.yaml
  37. 13
      etc/k8s/helm-chart/eventhub/charts/redis/templates/redis-service.yaml
  38. 20
      etc/k8s/helm-chart/eventhub/charts/redis/templates/redis.yaml
  39. 0
      etc/k8s/helm-chart/eventhub/charts/redis/values.yaml
  40. 6
      etc/k8s/helm-chart/eventhub/charts/www/Chart.yaml
  41. 36
      etc/k8s/helm-chart/eventhub/charts/www/templates/www-ingress.yaml
  42. 14
      etc/k8s/helm-chart/eventhub/charts/www/templates/www-service.yaml
  43. 24
      etc/k8s/helm-chart/eventhub/charts/www/templates/www.yaml
  44. 0
      etc/k8s/helm-chart/eventhub/charts/www/values.yaml
  45. 24
      etc/k8s/helm-chart/eventhub/templates/_helpers.tpl
  46. 11
      etc/k8s/helm-chart/eventhub/templates/managed-premium-retain.yaml
  47. 35
      etc/k8s/helm-chart/eventhub/values.azure.yaml
  48. 35
      etc/k8s/helm-chart/eventhub/values.yaml
  49. 18
      etc/k8s/scripts/azure/cluster-issuer.yaml
  50. 2
      etc/k8s/scripts/azure/configure-dns.ps1
  51. 8
      etc/k8s/scripts/azure/corednsms.yaml
  52. 69
      etc/k8s/scripts/azure/install-ingress.ps1
  53. 22
      etc/k8s/scripts/azure/push-images.ps1
  54. 63
      etc/k8s/scripts/build-images.ps1
  55. 7
      etc/k8s/scripts/minikube-load-images.ps1
  56. 4
      src/EventHub.Admin.HttpApi.Host/Dockerfile
  57. 18
      src/EventHub.Admin.HttpApi.Host/EventHubAdminHttpApiHostModule.cs
  58. 2
      src/EventHub.Admin.HttpApi.Host/Program.cs
  59. 71
      src/EventHub.Admin.HttpApi.Host/Utils/SameSiteCookiesServiceCollectionExtensions.cs
  60. 2
      src/EventHub.Admin.HttpApi.Host/appsettings.Development.json
  61. 8
      src/EventHub.Admin.HttpApi.Host/appsettings.json
  62. 3
      src/EventHub.Admin.Web/Dockerfile
  63. 7
      src/EventHub.Admin.Web/nginx.conf
  64. 3
      src/EventHub.Admin.Web/wwwroot/appsettings.Development.json
  65. 13
      src/EventHub.Admin.Web/wwwroot/appsettings.Production.json
  66. 13
      src/EventHub.Admin.Web/wwwroot/appsettings.Staging.json
  67. 4
      src/EventHub.BackgroundServices/Dockerfile
  68. 4
      src/EventHub.DbMigrator/Dockerfile
  69. 6
      src/EventHub.Domain.Shared/EventHubDomainSharedModule.cs
  70. 18
      src/EventHub.Domain.Shared/Web/EventHubExternalUrls.cs
  71. 49
      src/EventHub.Domain.Shared/Web/EventHubUrlOptions.cs
  72. 9
      src/EventHub.Domain/Emailing/EventHubEmailTemplateRenderingEngine.cs
  73. 1
      src/EventHub.Domain/EventHubDomainModule.cs
  74. 4
      src/EventHub.HttpApi.Host/Dockerfile
  75. 25
      src/EventHub.HttpApi.Host/EventHubHttpApiHostModule.cs
  76. 2
      src/EventHub.HttpApi.Host/Program.cs
  77. 71
      src/EventHub.HttpApi.Host/Utils/SameSiteCookiesServiceCollectionExtensions.cs
  78. 2
      src/EventHub.HttpApi.Host/appsettings.Development.json
  79. 8
      src/EventHub.HttpApi.Host/appsettings.json
  80. 4
      src/EventHub.IdentityServer/Dockerfile
  81. 4
      src/EventHub.IdentityServer/EventHub.IdentityServer.csproj
  82. 88
      src/EventHub.IdentityServer/EventHubIdentityServerModule.cs
  83. 2
      src/EventHub.IdentityServer/Program.cs
  84. 71
      src/EventHub.IdentityServer/Utils/SameSiteCookiesServiceCollectionExtensions.cs
  85. BIN
      src/EventHub.IdentityServer/account.openeventhub.pfx
  86. 2
      src/EventHub.IdentityServer/appsettings.Development.json
  87. 21
      src/EventHub.IdentityServer/appsettings.json
  88. 8
      src/EventHub.Web.Theme/Themes/EventHub/Components/Footer/Default.cshtml
  89. 20
      src/EventHub.Web.Theme/Themes/EventHub/Components/MainNavbar/Default.cshtml
  90. 7
      src/EventHub.Web.Theme/Themes/EventHub/Layouts/Application.cshtml
  91. 6
      src/EventHub.Web.Theme/wwwroot/themes/eventhub/owl-edit.css
  92. 6
      src/EventHub.Web.Theme/wwwroot/themes/eventhub/style.css
  93. 4
      src/EventHub.Web/Dockerfile
  94. 26
      src/EventHub.Web/EventHubWebModule.cs
  95. 2
      src/EventHub.Web/Menus/EventHubMenuContributor.cs
  96. 6
      src/EventHub.Web/Pages/Events/Detail.cshtml
  97. 4
      src/EventHub.Web/Pages/Index.cshtml
  98. 2
      src/EventHub.Web/Program.cs
  99. 71
      src/EventHub.Web/Utils/SameSiteCookiesServiceCollectionExtensions.cs
  100. 3
      src/EventHub.Web/appsettings.Development.json

1
.gitignore

@ -226,7 +226,6 @@ ClientBin/
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

BIN
etc/dev-cert/localhost.pfx

Binary file not shown.

21
etc/k8s/README.md

@ -0,0 +1,21 @@
### Pre-requirements
* Docker Desktop with Kubernetes enabled
* Install [NGINX ingress](https://kubernetes.github.io/ingress-nginx/deploy/) for k8s
### How to run?
* Add entries to the hosts file (in Windows: `C:\Windows\System32\drivers\etc\hosts`):
````
127.0.0.1 eh-st-account
127.0.0.1 eh-st-www
127.0.0.1 eh-st-api
127.0.0.1 eh-st-admin
127.0.0.1 eh-st-admin-api
````
* Run `build-images.ps1` in the `scripts` directory.
* Run `helm install eh-st eventhub` in the `helm-chart` directory.
* Browse https://eh-st-www and https://eh-st-admin
* Username: `admin`, password: `1q2w3E*`.

1
etc/k8s/helm-chart/deploy-azure.ps1

@ -0,0 +1 @@
helm upgrade --install eh-az eventhub -f .\eventhub\values.azure.yaml --namespace eventhub --create-namespace

6
etc/k8s/helm-chart/eventhub/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: eventhub
appVersion: "1.0"
description: EventHub solution
version: 1.0.0
type: application

6
etc/k8s/helm-chart/eventhub/charts/account/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: account
appVersion: "1.0"
description: EventHub Account Application
version: 1.0.0
type: application

28
etc/k8s/helm-chart/eventhub/charts/account/templates/account-ingress.yaml

@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffer-size: "{{ .Values.global.nginxProxyBufferSize }}"
nginx.ingress.kubernetes.io/proxy-buffers-number: "{{ .Values.global.nginxProxyBuffersNumber }}"
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_input_headers "from-ingress: true";
spec:
tls:
- hosts:
- {{ .Values.global.accountDomain }}
secretName: {{ .Release.Name }}-{{ .Chart.Name }}-tls
rules:
- host: "{{ .Values.global.accountDomain }}"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-{{ .Chart.Name }}
port:
number: 80

14
etc/k8s/helm-chart/eventhub/charts/account/templates/account-service.yaml

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
labels:
name: {{ .Release.Name }}-{{ .Chart.Name }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
ports:
- name: "80"
port: 80
- name: "443"
port: 443
selector:
app: {{ .Release.Name }}-{{ .Chart.Name }}

27
etc/k8s/helm-chart/eventhub/charts/account/templates/account.yaml

@ -0,0 +1,27 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
selector:
matchLabels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
containers:
- image: {{ .Values.containerImage }}
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
env:
{{ include "eventhub.global.env" . | indent 8 }}
- name: "ConnectionStrings__Default"
value: {{ .Values.global.defaultConnString }}

0
etc/k8s/helm-chart/eventhub/charts/account/values.yaml

6
etc/k8s/helm-chart/eventhub/charts/admin-api/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: admin-api
appVersion: "1.0"
description: EventHub Admin API Application
version: 1.0.0
type: application

26
etc/k8s/helm-chart/eventhub/charts/admin-api/templates/admin-api-ingress.yaml

@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffer-size: "{{ .Values.global.nginxProxyBufferSize }}"
nginx.ingress.kubernetes.io/proxy-buffers-number: "{{ .Values.global.nginxProxyBuffersNumber }}"
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- {{ .Values.global.adminApiDomain }}
secretName: {{ .Release.Name }}-{{ .Chart.Name }}-tls
rules:
- host: "{{ .Values.global.adminApiDomain }}"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-{{ .Chart.Name }}
port:
number: 80

14
etc/k8s/helm-chart/eventhub/charts/admin-api/templates/admin-api-service.yaml

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
labels:
name: {{ .Release.Name }}-{{ .Chart.Name }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
ports:
- name: "80"
port: 80
- name: "443"
port: 443
selector:
app: {{ .Release.Name }}-{{ .Chart.Name }}

27
etc/k8s/helm-chart/eventhub/charts/admin-api/templates/admin-api.yaml

@ -0,0 +1,27 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
selector:
matchLabels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
containers:
- image: {{ .Values.containerImage }}
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
env:
{{ include "eventhub.global.env" . | indent 8 }}
- name: "ConnectionStrings__Default"
value: {{ .Values.global.defaultConnString }}

0
etc/k8s/helm-chart/eventhub/charts/admin-api/values.yaml

6
etc/k8s/helm-chart/eventhub/charts/admin/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: admin
appVersion: "1.0"
description: EventHub Admin Application
version: 1.0.0
type: application

28
etc/k8s/helm-chart/eventhub/charts/admin/templates/admin-ingress.yaml

@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffer-size: "{{ .Values.global.nginxProxyBufferSize }}"
nginx.ingress.kubernetes.io/proxy-buffers-number: "{{ .Values.global.nginxProxyBuffersNumber }}"
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "blazor-environment: {{ .Values.global.dotnetEnvironment }}";
spec:
tls:
- hosts:
- {{ .Values.global.adminDomain }}
secretName: {{ .Release.Name }}-{{ .Chart.Name }}-tls
rules:
- host: "{{ .Values.global.adminDomain }}"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-{{ .Chart.Name }}
port:
number: 80

14
etc/k8s/helm-chart/eventhub/charts/admin/templates/admin-service.yaml

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
labels:
name: {{ .Release.Name }}-{{ .Chart.Name }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
ports:
- name: "80"
port: 80
- name: "443"
port: 443
selector:
app: {{ .Release.Name }}-{{ .Chart.Name }}

24
etc/k8s/helm-chart/eventhub/charts/admin/templates/admin.yaml

@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
selector:
matchLabels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
containers:
- image: {{ .Values.containerImage }}
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
env:
{{ include "eventhub.global.env" . | indent 8 }}

0
etc/k8s/helm-chart/eventhub/charts/admin/values.yaml

6
etc/k8s/helm-chart/eventhub/charts/api/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: api
appVersion: "1.0"
description: EventHub API Application
version: 1.0.0
type: application

26
etc/k8s/helm-chart/eventhub/charts/api/templates/api-ingress.yaml

@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffer-size: "{{ .Values.global.nginxProxyBufferSize }}"
nginx.ingress.kubernetes.io/proxy-buffers-number: "{{ .Values.global.nginxProxyBuffersNumber }}"
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- {{ .Values.global.apiDomain }}
secretName: {{ .Release.Name }}-{{ .Chart.Name }}-tls
rules:
- host: "{{ .Values.global.apiDomain }}"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-{{ .Chart.Name }}
port:
number: 80

14
etc/k8s/helm-chart/eventhub/charts/api/templates/api-service.yaml

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
labels:
name: {{ .Release.Name }}-{{ .Chart.Name }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
ports:
- name: "80"
port: 80
- name: "443"
port: 443
selector:
app: {{ .Release.Name }}-{{ .Chart.Name }}

27
etc/k8s/helm-chart/eventhub/charts/api/templates/api.yaml

@ -0,0 +1,27 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
selector:
matchLabels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
containers:
- image: {{ .Values.containerImage }}
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
env:
{{ include "eventhub.global.env" . | indent 8 }}
- name: "ConnectionStrings__Default"
value: {{ .Values.global.defaultConnString }}

0
etc/k8s/helm-chart/eventhub/charts/api/values.yaml

6
etc/k8s/helm-chart/eventhub/charts/background-services/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: background-services
appVersion: "1.0"
description: EventHub Background Services Application
version: 1.0.0
type: application

18
etc/k8s/helm-chart/eventhub/charts/background-services/templates/background-services.yaml

@ -0,0 +1,18 @@
apiVersion: batch/v1
kind: Job
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
activeDeadlineSeconds: 180
template:
spec:
containers:
- name: {{ .Release.Name }}-{{ .Chart.Name }}
image: {{ .Values.containerImage }}
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
env:
{{ include "eventhub.global.env" . | indent 8 }}
- name: "ConnectionStrings__Default"
value: {{ .Values.global.defaultConnString }}
restartPolicy: Never
backoffLimit: 10

0
etc/k8s/helm-chart/eventhub/charts/background-services/values.yaml

6
etc/k8s/helm-chart/eventhub/charts/dbmigrator/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: dbmigrator
appVersion: "1.0"
description: EventHub Migrator Application
version: 1.0.0
type: application

24
etc/k8s/helm-chart/eventhub/charts/dbmigrator/templates/migrator.yaml

@ -0,0 +1,24 @@
apiVersion: batch/v1
kind: Job
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
activeDeadlineSeconds: 180
template:
spec:
containers:
- name: {{ .Release.Name }}-{{ .Chart.Name }}
image: {{ .Values.containerImage }}
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
env:
{{ include "eventhub.global.env" . | indent 8 }}
- name: "ConnectionStrings__Default"
value: {{ .Values.global.defaultConnString }}
- name: "IdentityServer__Clients__EventHub_Web__RootUrl"
value: {{ .Values.global.wwwUrl }}
- name: "IdentityServer__Clients__EventHub_Blazor__RootUrl"
value: {{ .Values.global.adminUrl }}
- name: "IdentityServer__Clients__EventHub_Swagger__RootUrl"
value: {{ .Values.global.apiUrl }}
restartPolicy: Never
backoffLimit: 10

0
etc/k8s/helm-chart/eventhub/charts/dbmigrator/values.yaml

6
etc/k8s/helm-chart/eventhub/charts/postgresql/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: postgresql
appVersion: "1.0"
description: Runs PostgreSQL Instance
version: 1.0.0
type: application

14
etc/k8s/helm-chart/eventhub/charts/postgresql/templates/postgresql-service.yaml

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
labels:
name: {{ .Release.Name }}-{{ .Chart.Name }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
type: ClusterIP
ports:
- name: postgresql
port: 5432
selector:
app: {{ .Release.Name }}-{{ .Chart.Name }}

43
etc/k8s/helm-chart/eventhub/charts/postgresql/templates/postgresql.yaml

@ -0,0 +1,43 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
serviceName: {{ .Release.Name }}-{{ .Chart.Name }}
replicas: 1
selector:
matchLabels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
containers:
- image: postgres
name: {{ .Release.Name }}-{{ .Chart.Name }}
{{- if eq .Release.Name "eh-az" }}
volumeMounts:
- mountPath: "/var/lib/postgresql/data"
name: {{ .Release.Name }}-{{ .Chart.Name }}-database-volume
subPath: postgresql-data
{{- end }}
ports:
- name: postgresql
containerPort: 5432
env:
- name: POSTGRES_USER
value: "root"
- name: POSTGRES_PASSWORD
value: "root"
{{- if eq .Release.Name "eh-az" }}
volumeClaimTemplates:
- metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}-database-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "managed-premium-retain"
resources:
requests:
storage: 64Gi
{{- end }}

0
etc/k8s/helm-chart/eventhub/charts/postgresql/values.yaml

6
etc/k8s/helm-chart/eventhub/charts/redis/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: redis
appVersion: "1.0"
description: Runs Redis instance
version: 1.0.0
type: application

13
etc/k8s/helm-chart/eventhub/charts/redis/templates/redis-service.yaml

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
labels:
name: {{ .Release.Name }}-{{ .Chart.Name }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
type: ClusterIP
ports:
- name: redis
port: 6379
selector:
app: {{ .Release.Name }}-{{ .Chart.Name }}

20
etc/k8s/helm-chart/eventhub/charts/redis/templates/redis.yaml

@ -0,0 +1,20 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
containers:
- image: redis:6.0.10-alpine
name: {{ .Release.Name }}-{{ .Chart.Name }}
ports:
- name: redis
containerPort: 6379

0
etc/k8s/helm-chart/eventhub/charts/redis/values.yaml

6
etc/k8s/helm-chart/eventhub/charts/www/Chart.yaml

@ -0,0 +1,6 @@
apiVersion: v2
name: www
appVersion: "1.0"
description: EventHub WWW Application
version: 1.0.0
type: application

36
etc/k8s/helm-chart/eventhub/charts/www/templates/www-ingress.yaml

@ -0,0 +1,36 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffer-size: "{{ .Values.global.nginxProxyBufferSize }}"
nginx.ingress.kubernetes.io/proxy-buffers-number: "{{ .Values.global.nginxProxyBuffersNumber }}"
{{- if eq .Release.Name "eh-az" }}
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
{{- end }}
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- {{ .Values.global.wwwDomain }}
{{- if eq .Release.Name "eh-az" }}
- {{ print "www." .Values.global.wwwDomain }}
{{- end }}
secretName: {{ .Release.Name }}-{{ .Chart.Name }}-tls
rules:
{{- if eq .Release.Name "eh-az" }}
- host: "{{ print "www." .Values.global.wwwDomain }}"
{{- else }}
- host: "{{ .Values.global.wwwDomain }}"
{{- end }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-{{ .Chart.Name }}
port:
number: 80

14
etc/k8s/helm-chart/eventhub/charts/www/templates/www-service.yaml

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
labels:
name: {{ .Release.Name }}-{{ .Chart.Name }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
ports:
- name: "80"
port: 80
- name: "443"
port: 443
selector:
app: {{ .Release.Name }}-{{ .Chart.Name }}

24
etc/k8s/helm-chart/eventhub/charts/www/templates/www.yaml

@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
selector:
matchLabels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
containers:
- image: {{ .Values.containerImage }}
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
name: {{ .Release.Name }}-{{ .Chart.Name }}
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
env:
{{ include "eventhub.global.env" . | indent 8 }}

0
etc/k8s/helm-chart/eventhub/charts/www/values.yaml

24
etc/k8s/helm-chart/eventhub/templates/_helpers.tpl

@ -0,0 +1,24 @@
{{- define "eventhub.global.env" -}}
- name: "DOTNET_ENVIRONMENT"
value: "{{ .Values.global.dotnetEnvironment }}"
- name: "AppUrls__Account"
value: "{{ .Values.global.accountUrl }}"
- name: "AppUrls__Www"
value: "{{ .Values.global.wwwUrl }}"
- name: "AppUrls__Api"
value: "{{ .Values.global.apiUrl }}"
- name: "AppUrls__ApiInternal"
value: "{{ .Values.global.apiUrlInternal }}"
- name: "AppUrls__Admin"
value: "{{ .Values.global.adminUrl }}"
- name: "AppUrls__AdminApi"
value: "{{ .Values.global.adminApiUrl }}"
- name: "Redis__Configuration"
value: "{{ .Values.global.redisConfiguration }}"
- name: "AuthServer__Authority"
value: "{{ .Values.global.internalAuthServerAuthority }}"
- name: "AuthServer__RequireHttpsMetadata"
value: "{{ .Values.global.internalAuthServerRequireHttpsMetadata }}"
- name: "StringEncryption__DefaultPassPhrase"
value: "{{ .Values.global.stringEncryptionDefaultPassPhrase }}"
{{- end }}

11
etc/k8s/helm-chart/eventhub/templates/managed-premium-retain.yaml

@ -0,0 +1,11 @@
{{- if eq .Release.Name "eh-az" }}
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: managed-premium-retain
provisioner: kubernetes.io/azure-disk
reclaimPolicy: Retain
parameters:
storageaccounttype: Premium_LRS
kind: Managed
{{- end }}

35
etc/k8s/helm-chart/eventhub/values.azure.yaml

@ -0,0 +1,35 @@
global:
dotnetEnvironment: 'Production'
accountDomain: account.openeventhub.com
accountUrl: https://account.openeventhub.com
apiDomain: api.openeventhub.com
apiUrl: https://api.openeventhub.com
apiUrlInternal: http://eh-az-api
wwwDomain: openeventhub.com
wwwUrl: "https://www.openeventhub.com"
adminDomain: admin.openeventhub.com
adminUrl: https://admin.openeventhub.com
adminApiDomain: admin-api.openeventhub.com
adminApiUrl: https://admin-api.openeventhub.com
nginxProxyBufferSize: "32k"
nginxProxyBuffersNumber: "8"
defaultConnString: "Host=eh-az-postgresql;Port=5432;Database=EventHub;Username=root;Password=root"
redisConfiguration: "eh-az-redis"
internalAuthServerAuthority: "http://account.openeventhub.com"
internalAuthServerRequireHttpsMetadata: "false"
stringEncryptionDefaultPassPhrase: "TxVIZFPxK33czbbv"
imagePullPolicy: Always
account:
containerImage: "volocr.azurecr.io/eventhub.account"
api:
containerImage: "volocr.azurecr.io/eventhub.api"
www:
containerImage: "volocr.azurecr.io/eventhub.www"
admin-api:
containerImage: "volocr.azurecr.io/eventhub.admin-api"
admin:
containerImage: "volocr.azurecr.io/eventhub.admin"
dbmigrator:
containerImage: "volocr.azurecr.io/eventhub.dbmigrator"
background-services:
containerImage: "volocr.azurecr.io/eventhub.background-services"

35
etc/k8s/helm-chart/eventhub/values.yaml

@ -0,0 +1,35 @@
global:
dotnetEnvironment: 'Staging'
accountDomain: eh-st-account
accountUrl: https://eh-st-account
apiDomain: eh-st-api
apiUrl: https://eh-st-api
apiUrlInternal: http://eh-st-api
wwwDomain: eh-st-www
wwwUrl: "https://eh-st-www"
adminDomain: eh-st-admin
adminUrl: https://eh-st-admin
adminApiDomain: eh-st-admin-api
adminApiUrl: https://eh-st-admin-api
nginxProxyBufferSize: "32k"
nginxProxyBuffersNumber: "8"
defaultConnString: "Host=eh-st-postgresql;Port=5432;Database=EventHub;Username=root;Password=root"
redisConfiguration: "eh-st-redis"
internalAuthServerAuthority: "http://eh-st-account"
internalAuthServerRequireHttpsMetadata: "false"
stringEncryptionDefaultPassPhrase: "TxVIZFPxK33czbbv"
imagePullPolicy: Never
account:
containerImage: "eventhub.account"
api:
containerImage: "eventhub.api"
www:
containerImage: "eventhub.www"
admin-api:
containerImage: "eventhub.admin-api"
admin:
containerImage: "eventhub.admin"
dbmigrator:
containerImage: "eventhub.dbmigrator"
background-services:
containerImage: "eventhub.background-services"

18
etc/k8s/scripts/azure/cluster-issuer.yaml

@ -0,0 +1,18 @@
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: info@volosoft.com
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
podTemplate:
spec:
nodeSelector:
"kubernetes.io/os": linux

2
etc/k8s/scripts/azure/configure-dns.ps1

@ -0,0 +1,2 @@
kubectl apply -f .\corednsms.yaml
kubectl delete pod --namespace kube-system -l k8s-app=kube-dns

8
etc/k8s/scripts/azure/corednsms.yaml

@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-custom
namespace: kube-system
data:
Corefile.override: |
rewrite name substring account.openeventhub.com eh-az-account

69
etc/k8s/scripts/azure/install-ingress.ps1

@ -0,0 +1,69 @@
$REGISTRY_NAME="volocr.azurecr.io"
$ACR_URL="volocr.azurecr.io"
$CONTROLLER_REGISTRY="k8s.gcr.io"
$CONTROLLER_IMAGE="ingress-nginx/controller"
$CONTROLLER_TAG="v0.48.1"
$PATCH_REGISTRY="docker.io"
$PATCH_IMAGE="jettech/kube-webhook-certgen"
$PATCH_TAG="v1.5.1"
$DEFAULTBACKEND_REGISTRY="k8s.gcr.io"
$DEFAULTBACKEND_IMAGE="defaultbackend-amd64"
$DEFAULTBACKEND_TAG="1.5"
$CERT_MANAGER_REGISTRY="quay.io"
$CERT_MANAGER_TAG="v1.3.1"
$CERT_MANAGER_IMAGE_CONTROLLER="jetstack/cert-manager-controller"
$CERT_MANAGER_IMAGE_WEBHOOK="jetstack/cert-manager-webhook"
$CERT_MANAGER_IMAGE_CAINJECTOR="jetstack/cert-manager-cainjector"
az acr import --name $REGISTRY_NAME --source ${CONTROLLER_REGISTRY}/${CONTROLLER_IMAGE}:${CONTROLLER_TAG} --image ${CONTROLLER_IMAGE}:${CONTROLLER_TAG}
az acr import --name $REGISTRY_NAME --source ${PATCH_REGISTRY}/${PATCH_IMAGE}:${PATCH_TAG} --image ${PATCH_IMAGE}:${PATCH_TAG}
az acr import --name $REGISTRY_NAME --source ${DEFAULTBACKEND_REGISTRY}/${DEFAULTBACKEND_IMAGE}:${DEFAULTBACKEND_TAG} --image ${DEFAULTBACKEND_IMAGE}:${DEFAULTBACKEND_TAG}
az acr import --name $REGISTRY_NAME --source ${CERT_MANAGER_REGISTRY}/${CERT_MANAGER_IMAGE_CONTROLLER}:${CERT_MANAGER_TAG} --image ${CERT_MANAGER_IMAGE_CONTROLLER}:${CERT_MANAGER_TAG}
az acr import --name $REGISTRY_NAME --source ${CERT_MANAGER_REGISTRY}/${CERT_MANAGER_IMAGE_WEBHOOK}:${CERT_MANAGER_TAG} --image ${CERT_MANAGER_IMAGE_WEBHOOK}:${CERT_MANAGER_TAG}
az acr import --name $REGISTRY_NAME --source ${CERT_MANAGER_REGISTRY}/${CERT_MANAGER_IMAGE_CAINJECTOR}:${CERT_MANAGER_TAG} --image ${CERT_MANAGER_IMAGE_CAINJECTOR}:${CERT_MANAGER_TAG}
# Create a namespace for your ingress resources
kubectl create namespace ingress-basic
# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# Use Helm to deploy an NGINX ingress controller
helm install nginx-ingress ingress-nginx/ingress-nginx `
--namespace ingress-basic `
--set controller.replicaCount=1 `
--set controller.nodeSelector."kubernetes\.io/os"=linux `
--set controller.image.registry=$ACR_URL `
--set controller.image.image=$CONTROLLER_IMAGE `
--set controller.image.tag=$CONTROLLER_TAG `
--set controller.image.digest="" `
--set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux `
--set controller.admissionWebhooks.patch.image.registry=$ACR_URL `
--set controller.admissionWebhooks.patch.image.image=$PATCH_IMAGE `
--set controller.admissionWebhooks.patch.image.tag=$PATCH_TAG `
--set defaultBackend.nodeSelector."kubernetes\.io/os"=linux `
--set defaultBackend.image.registry=$ACR_URL `
--set defaultBackend.image.image=$DEFAULTBACKEND_IMAGE `
--set defaultBackend.image.tag=$DEFAULTBACKEND_TAG
# Label the ingress-basic namespace to disable resource validation
kubectl label namespace ingress-basic cert-manager.io/disable-validation=true
# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
# Update your local Helm chart repository cache
helm repo update
# Install the cert-manager Helm chart
helm install cert-manager jetstack/cert-manager `
--namespace ingress-basic `
--version ${CERT_MANAGER_TAG} `
--set installCRDs=true `
--set nodeSelector."kubernetes\.io/os"=linux `
--set image.repository=${ACR_URL}/${CERT_MANAGER_IMAGE_CONTROLLER} `
--set image.tag=${CERT_MANAGER_TAG} `
--set webhook.image.repository=${ACR_URL}/${CERT_MANAGER_IMAGE_WEBHOOK} `
--set webhook.image.tag=${CERT_MANAGER_TAG} `
--set cainjector.image.repository=${ACR_URL}/${CERT_MANAGER_IMAGE_CAINJECTOR} `
--set cainjector.image.tag=${CERT_MANAGER_TAG}

22
etc/k8s/scripts/azure/push-images.ps1

@ -0,0 +1,22 @@
az acr login --name volocr
docker tag eventhub.dbmigrator:latest volocr.azurecr.io/eventhub.dbmigrator:latest
docker push volocr.azurecr.io/eventhub.dbmigrator:latest
docker tag eventhub.www:latest volocr.azurecr.io/eventhub.www:latest
docker push volocr.azurecr.io/eventhub.www:latest
docker tag eventhub.api:latest volocr.azurecr.io/eventhub.api:latest
docker push volocr.azurecr.io/eventhub.api:latest
docker tag eventhub.admin:latest volocr.azurecr.io/eventhub.admin:latest
docker push volocr.azurecr.io/eventhub.admin:latest
docker tag eventhub.admin-api:latest volocr.azurecr.io/eventhub.admin-api:latest
docker push volocr.azurecr.io/eventhub.admin-api:latest
docker tag eventhub.account:latest volocr.azurecr.io/eventhub.account:latest
docker push volocr.azurecr.io/eventhub.account:latest
docker tag eventhub.background-services:latest volocr.azurecr.io/eventhub.background-services:latest
docker push volocr.azurecr.io/eventhub.background-services:latest

63
etc/k8s/scripts/build-images.ps1

@ -0,0 +1,63 @@
$currentFolder = (Get-Item -Path "./" -Verbose).FullName
$slnFolder = Join-Path $currentFolder "../../../"
$dbmigratorFolder = Join-Path $slnFolder "src/EventHub.DbMigrator"
$webFolder = Join-Path $slnFolder "src/EventHub.Web"
$apiFolder = Join-Path $slnFolder "src/EventHub.HttpApi.Host"
$adminFolder = Join-Path $slnFolder "src/EventHub.Admin.Web"
$adminApiFolder = Join-Path $slnFolder "src/EventHub.Admin.HttpApi.Host"
$identityServerFolder = Join-Path $slnFolder "src/EventHub.IdentityServer"
$backgroundServicesFolder = Join-Path $slnFolder "src/EventHub.BackgroundServices"
### DB MIGRATOR
Write-Host "*** BUILDING DB MIGRATOR ****************" -ForegroundColor Green
Set-Location $dbmigratorFolder
dotnet publish -c Release
docker build -t eventhub.dbmigrator .
### WEB (WWW)
Write-Host "*** BUILDING WEB (WWW) ****************" -ForegroundColor Green
Set-Location $webFolder
dotnet publish -c Release
docker build -t eventhub.www .
### API
Write-Host "*** BUILDING API ****************" -ForegroundColor Green
Set-Location $apiFolder
dotnet publish -c Release
docker build -t eventhub.api .
### ADMIN (BLAZOR)
Write-Host "*** BUILDING ADMIN (BLAZOR) ****************" -ForegroundColor Green
Set-Location $adminFolder
dotnet publish -c Release
docker build -t eventhub.admin .
### ADMIN API
Write-Host "*** BUILDING ADMIN API ****************" -ForegroundColor Green
Set-Location $adminApiFolder
dotnet publish -c Release
docker build -t eventhub.admin-api .
### IDENTITY SERVER (ACCOUNT)
Write-Host "*** BUILDING IDENTITY SERVER (ACCOUNT) ****************" -ForegroundColor Green
Set-Location $identityServerFolder
dotnet publish -c Release
docker build -t eventhub.account .
### BACKGROUND SERVICES
Write-Host "*** BUILDING BACKGROUND SERVICES ****************" -ForegroundColor Green
Set-Location $backgroundServicesFolder
dotnet publish -c Release
docker build -t eventhub.background-services .
### ALL COMPLETED
Write-Host "ALL COMPLETED" -ForegroundColor Green
Set-Location $currentFolder

7
etc/k8s/scripts/minikube-load-images.ps1

@ -0,0 +1,7 @@
minikube image load eventhub.dbmigrator:latest
minikube image load eventhub.www:latest
minikube image load eventhub.api:latest
minikube image load eventhub.admin:latest
minikube image load eventhub.admin-api:latest
minikube image load eventhub.account:latest
minikube image load eventhub.background-services:latest

4
src/EventHub.Admin.HttpApi.Host/Dockerfile

@ -0,0 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY bin/Release/net5.0/publish/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "EventHub.Admin.HttpApi.Host.dll"]

18
src/EventHub.Admin.HttpApi.Host/EventHubAdminHttpApiHostModule.cs

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using EventHub.Admin.Utils;
using EventHub.EntityFrameworkCore;
using EventHub.Web;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
@ -54,6 +56,7 @@ namespace EventHub.Admin
ConfigureVirtualFileSystem(context);
ConfigureRedis(context, configuration);
ConfigureCors(context, configuration);
ConfigureCookies(context);
ConfigureSwaggerServices(context, configuration);
ConfigureBackgroundJobs();
}
@ -109,7 +112,7 @@ namespace EventHub.Admin
private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAbpSwaggerGenWithOAuth(
configuration["AuthServer:Authority"],
configuration[EventHubUrlOptions.GetAccountConfigKey()],
new Dictionary<string, string>
{
{"EventHubAdmin", "EventHub Admin API"}
@ -148,10 +151,7 @@ namespace EventHub.Admin
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
configuration[EventHubUrlOptions.GetAdminConfigKey()]
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
@ -162,6 +162,11 @@ namespace EventHub.Admin
});
}
private void ConfigureCookies(ServiceConfigurationContext context)
{
context.Services.AddSameSiteCookiePolicy();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
@ -194,8 +199,9 @@ namespace EventHub.Admin
app.UseErrorPage();
}
app.UseCookiePolicy();
app.UseCorrelationId();
app.UseVirtualFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(DefaultCorsPolicyName);
app.UseAuthentication();

2
src/EventHub.Admin.HttpApi.Host/Program.cs

@ -20,9 +20,7 @@ namespace EventHub.Admin
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Async(c => c.File("Logs/logs.txt"))
#if DEBUG
.WriteTo.Async(c => c.Console())
#endif
.CreateLogger();
try

71
src/EventHub.Admin.HttpApi.Host/Utils/SameSiteCookiesServiceCollectionExtensions.cs

@ -0,0 +1,71 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace EventHub.Admin.Utils
{
public static class SameSiteCookiesServiceCollectionExtensions
{
public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
return services;
}
private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent))
{
// For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
options.SameSite = SameSiteMode.Unspecified;
}
}
}
private static bool DisallowsSameSiteNone(string userAgent)
{
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking stack
if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
}
}

2
src/EventHub.Admin.HttpApi.Host/appsettings.Development.json

@ -1,2 +0,0 @@
{
}

8
src/EventHub.Admin.HttpApi.Host/appsettings.json

@ -1,20 +1,14 @@
{
"App": {
"CorsOrigins": "https://*.openeventhub.com,https://localhost:44307,https://localhost:44308"
},
"ConnectionStrings": {
"Default": "Host=localhost;Database=EventHub;Username=root;Password=root;Port=5432"
},
"Redis": {
"Configuration": "127.0.0.1"
"Configuration": "localhost"
},
"AuthServer": {
"Authority": "https://localhost:44313",
"RequireHttpsMetadata": "true",
"SwaggerClientId": "EventHub_Swagger",
"SwaggerClientSecret": "1q2w3e*"
},
"StringEncryption": {
"DefaultPassPhrase": "TxVIZFPxK33czbbv"
}
}

3
src/EventHub.Admin.Web/Dockerfile

@ -0,0 +1,3 @@
FROM nginx:latest
COPY ./bin/Release/net5.0/publish/wwwroot/ /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/conf.d/default.conf

7
src/EventHub.Admin.Web/nginx.conf

@ -0,0 +1,7 @@
server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri /index.html;
}
}

3
src/EventHub.Admin.Web/wwwroot/appsettings.Development.json

@ -1,3 +0,0 @@
{
}

13
src/EventHub.Admin.Web/wwwroot/appsettings.Production.json

@ -0,0 +1,13 @@
{
"App": {
"SelfUrl": "https://admin.openeventhub.com"
},
"AuthServer": {
"Authority": "https://account.openeventhub.com"
},
"RemoteServices": {
"Default": {
"BaseUrl": "https://admin-api.openeventhub.com"
}
}
}

13
src/EventHub.Admin.Web/wwwroot/appsettings.Staging.json

@ -0,0 +1,13 @@
{
"App": {
"SelfUrl": "https://eh-st-admin"
},
"AuthServer": {
"Authority": "https://eh-st-account"
},
"RemoteServices": {
"Default": {
"BaseUrl": "https://eh-st-admin-api"
}
}
}

4
src/EventHub.BackgroundServices/Dockerfile

@ -0,0 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY bin/Release/net5.0/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "EventHub.BackgroundServices.dll"]

4
src/EventHub.DbMigrator/Dockerfile

@ -0,0 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY bin/Release/net5.0/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "EventHub.DbMigrator.dll"]

6
src/EventHub.Domain.Shared/EventHubDomainSharedModule.cs

@ -1,4 +1,6 @@
using EventHub.Localization;
using EventHub.Web;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AuditLogging;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Identity;
@ -33,6 +35,8 @@ namespace EventHub
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<EventHubDomainSharedModule>();
@ -52,6 +56,8 @@ namespace EventHub
{
options.MapCodeNamespace("EventHub", typeof(EventHubResource));
});
Configure<EventHubUrlOptions>(configuration.GetSection("AppUrls"));
}
}
}

18
src/EventHub.Domain.Shared/Web/EventHubExternalUrls.cs

@ -1,18 +0,0 @@
namespace EventHub.Web
{
public static class EventHubExternalUrls
{
#if DEBUG
public const string EhAccount = "https://localhost:44313";
public const string EhApi = "https://localhost:44362";
public const string EhAdmin = "https://localhost:44307";
public const string EhWww = "https://localhost:44308";
#else
// TODO: Change these production links
public const string EhAccount = "https://localhost:44313";
public const string EhApi = "https://localhost:44362";
public const string EhAdmin = "https://localhost:44307";
public const string EhWww = "https://localhost:44308";
#endif
}
}

49
src/EventHub.Domain.Shared/Web/EventHubUrlOptions.cs

@ -0,0 +1,49 @@
namespace EventHub.Web
{
public class EventHubUrlOptions
{
private const string ConfigurationName = "AppUrls";
public string Account { get; set; } = "https://localhost:44313";
public string Www { get; set; } = "https://localhost:44308";
public string Api { get; set; } = "https://localhost:44362";
public string ApiInternal { get; set; } = "https://localhost:44362";
public string Admin { get; set; } = "https://localhost:44307";
public string AdminApi { get; set; } = "https://localhost:44305";
public static string GetAccountConfigKey()
{
return GetConfigKey(nameof(Account));
}
public static string GetWwwConfigKey()
{
return GetConfigKey(nameof(Www));
}
public static string GetApiInternalConfigKey()
{
return GetConfigKey(nameof(ApiInternal));
}
public static string GetApiConfigKey()
{
return GetConfigKey(nameof(Api));
}
public static string GetAdminConfigKey()
{
return GetConfigKey(nameof(Admin));
}
public static string GetAdminApiConfigKey()
{
return GetConfigKey(nameof(AdminApi));
}
private static string GetConfigKey(string appName)
{
return $"{ConfigurationName}:{appName}";
}
}
}

9
src/EventHub.Domain/Emailing/EventHubEmailTemplateRenderingEngine.cs

@ -5,6 +5,7 @@ using EventHub.Web;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.TextTemplating;
using Volo.Abp.TextTemplating.Scriban;
@ -18,15 +19,19 @@ namespace EventHub.Emailing
)]
public class EventHubEmailTemplateRenderingEngine : ScribanTemplateRenderingEngine
{
private readonly EventHubUrlOptions _options;
public EventHubEmailTemplateRenderingEngine(
ITemplateDefinitionManager templateDefinitionManager,
ITemplateContentProvider templateContentProvider,
IStringLocalizerFactory stringLocalizerFactory
IStringLocalizerFactory stringLocalizerFactory,
IOptions<EventHubUrlOptions> options
) : base(
templateDefinitionManager,
templateContentProvider,
stringLocalizerFactory)
{
_options = options.Value;
}
public override async Task<string> RenderAsync(
@ -41,7 +46,7 @@ namespace EventHub.Emailing
}
globalContext["current_year"] = DateTime.Today.Year;
globalContext["app_url"] = EventHubExternalUrls.EhWww;
globalContext["app_url"] = _options.Www;
return await base.RenderAsync(templateName, model, cultureName, globalContext);
}

1
src/EventHub.Domain/EventHubDomainModule.cs

@ -34,7 +34,6 @@ namespace EventHub
{
options.FileSets.AddEmbedded<EventHubDomainModule>();
});
#if DEBUG
context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>());
#endif

4
src/EventHub.HttpApi.Host/Dockerfile

@ -0,0 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY bin/Release/net5.0/publish/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "EventHub.HttpApi.Host.dll"]

25
src/EventHub.HttpApi.Host/EventHubHttpApiHostModule.cs

@ -11,6 +11,8 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using EventHub.EntityFrameworkCore;
using EventHub.Utils;
using EventHub.Web;
using Microsoft.AspNetCore.Localization;
using StackExchange.Redis;
using Microsoft.OpenApi.Models;
@ -26,6 +28,7 @@ using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
namespace EventHub
@ -55,6 +58,7 @@ namespace EventHub
ConfigureVirtualFileSystem(context);
ConfigureRedis(context, configuration);
ConfigureCors(context, configuration);
ConfigureCookies(context);
ConfigureSwaggerServices(context, configuration);
ConfigureBackgroundJobs();
}
@ -110,7 +114,7 @@ namespace EventHub
private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAbpSwaggerGenWithOAuth(
configuration["AuthServer:Authority"],
configuration[EventHubUrlOptions.GetAccountConfigKey()],
new Dictionary<string, string>
{
{"EventHub", "EventHub API"}
@ -149,10 +153,7 @@ namespace EventHub
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
configuration[EventHubUrlOptions.GetWwwConfigKey()]
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
@ -163,6 +164,11 @@ namespace EventHub
});
}
private void ConfigureCookies(ServiceConfigurationContext context)
{
context.Services.AddSameSiteCookiePolicy();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
@ -172,6 +178,12 @@ namespace EventHub
{
app.UseDeveloperExceptionPage();
}
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
var supportedCultures = new[]
{
@ -195,8 +207,9 @@ namespace EventHub
app.UseErrorPage();
}
app.UseCookiePolicy();
app.UseCorrelationId();
app.UseVirtualFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(DefaultCorsPolicyName);
app.UseAuthentication();

2
src/EventHub.HttpApi.Host/Program.cs

@ -20,9 +20,7 @@ namespace EventHub
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Async(c => c.File("Logs/logs.txt"))
#if DEBUG
.WriteTo.Async(c => c.Console())
#endif
.CreateLogger();
try

71
src/EventHub.HttpApi.Host/Utils/SameSiteCookiesServiceCollectionExtensions.cs

@ -0,0 +1,71 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace EventHub.Utils
{
public static class SameSiteCookiesServiceCollectionExtensions
{
public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
return services;
}
private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent))
{
// For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
options.SameSite = SameSiteMode.Unspecified;
}
}
}
private static bool DisallowsSameSiteNone(string userAgent)
{
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking stack
if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
}
}

2
src/EventHub.HttpApi.Host/appsettings.Development.json

@ -1,2 +0,0 @@
{
}

8
src/EventHub.HttpApi.Host/appsettings.json

@ -1,20 +1,14 @@
{
"App": {
"CorsOrigins": "https://*.openeventhub.com,https://localhost:44307,https://localhost:44308"
},
"ConnectionStrings": {
"Default": "Host=localhost;Database=EventHub;Username=root;Password=root;Port=5432"
},
"Redis": {
"Configuration": "127.0.0.1"
"Configuration": "localhost"
},
"AuthServer": {
"Authority": "https://localhost:44313",
"RequireHttpsMetadata": "true",
"SwaggerClientId": "EventHub_Swagger",
"SwaggerClientSecret": "1q2w3e*"
},
"StringEncryption": {
"DefaultPassPhrase": "TxVIZFPxK33czbbv"
}
}

4
src/EventHub.IdentityServer/Dockerfile

@ -0,0 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY bin/Release/net5.0/publish/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "EventHub.IdentityServer.dll"]

4
src/EventHub.IdentityServer/EventHub.IdentityServer.csproj

@ -20,6 +20,10 @@
<Content Remove="Logs\**" />
<EmbeddedResource Remove="Logs\**" />
<None Remove="Logs\**" />
<None Remove="account.openeventhub.pfx" />
<Content Include="account.openeventhub.pfx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>

88
src/EventHub.IdentityServer/EventHubIdentityServerModule.cs

@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using Localization.Resources.AbpUi;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
@ -9,16 +8,19 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using EventHub.EntityFrameworkCore;
using EventHub.Localization;
using EventHub.Utils;
using EventHub.Web;
using EventHub.Web.Theme;
using EventHub.Web.Theme.Bundling;
using IdentityServer4.Configuration;
using IdentityServer4.Extensions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
using Volo.Abp;
using Volo.Abp.Account;
using Volo.Abp.Account.Web;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Auditing;
@ -26,6 +28,7 @@ using Volo.Abp.Autofac;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.IdentityServer;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation.Urls;
@ -46,6 +49,40 @@ namespace EventHub
{
private const string DefaultCorsPolicyName = "Default";
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
if (!hostingEnvironment.IsDevelopment())
{
var configuration = context.Services.GetConfiguration();
PreConfigure<AbpIdentityServerBuilderOptions>(options =>
{
options.AddDeveloperSigningCredential = false;
});
PreConfigure<IIdentityServerBuilder>(builder =>
{
builder.AddSigningCredential(GetSigningCertificate(hostingEnvironment, configuration));
});
}
}
private X509Certificate2 GetSigningCertificate(IWebHostEnvironment hostingEnv, IConfiguration configuration)
{
var fileName = "account.openeventhub.pfx";
var passPhrase = "a8202f07-66e5-4619-be07-72ba76fde97f";
var file = Path.Combine(hostingEnv.ContentRootPath, fileName);
if (!File.Exists(file))
{
throw new FileNotFoundException($"Signing Certificate couldn't found: {file}");
}
return new X509Certificate2(file, passPhrase);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
@ -79,17 +116,11 @@ namespace EventHub
options.ApplicationName = "AuthServer";
});
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = EventHubExternalUrls.EhAccount;
});
Configure<IdentityServerOptions>(options =>
{
options.IssuerUri = EventHubExternalUrls.EhAccount;
options.IssuerUri = configuration[EventHubUrlOptions.GetAccountConfigKey()];
});
if (hostingEnvironment.IsDevelopment())
{
Configure<AbpVirtualFileSystemOptions>(options =>
@ -102,8 +133,15 @@ namespace EventHub
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(','));
options.Applications["MVC"].RootUrl = configuration[EventHubUrlOptions.GetAccountConfigKey()];
options.RedirectAllowedUrls.AddRange(
new[]
{
configuration[EventHubUrlOptions.GetWwwConfigKey()],
configuration[EventHubUrlOptions.GetAdminConfigKey()],
configuration[EventHubUrlOptions.GetApiConfigKey()],
configuration[EventHubUrlOptions.GetAdminApiConfigKey()]
});
});
Configure<AbpBackgroundJobOptions>(options =>
@ -127,10 +165,10 @@ namespace EventHub
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
configuration[EventHubUrlOptions.GetWwwConfigKey()],
configuration[EventHubUrlOptions.GetApiConfigKey()],
configuration[EventHubUrlOptions.GetAdminConfigKey()],
configuration[EventHubUrlOptions.GetAdminApiConfigKey()]
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
@ -139,13 +177,26 @@ namespace EventHub
.AllowCredentials();
});
});
context.Services.AddSameSiteCookiePolicy();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>();
app.Use(async (ctx, next) =>
{
if (ctx.Request.Headers.ContainsKey("from-ingress"))
{
ctx.SetIdentityServerOrigin(configuration[EventHubUrlOptions.GetAccountConfigKey()]);
}
await next();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
@ -157,9 +208,10 @@ namespace EventHub
{
app.UseErrorPage();
}
app.UseCookiePolicy();
app.UseCorrelationId();
app.UseVirtualFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(DefaultCorsPolicyName);
app.UseAuthentication();

2
src/EventHub.IdentityServer/Program.cs

@ -20,9 +20,7 @@ namespace EventHub
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Async(c => c.File("Logs/logs.txt"))
#if DEBUG
.WriteTo.Async(c => c.Console())
#endif
.CreateLogger();
try

71
src/EventHub.IdentityServer/Utils/SameSiteCookiesServiceCollectionExtensions.cs

@ -0,0 +1,71 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace EventHub.Utils
{
public static class SameSiteCookiesServiceCollectionExtensions
{
public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
return services;
}
private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent))
{
// For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
options.SameSite = SameSiteMode.Unspecified;
}
}
}
private static bool DisallowsSameSiteNone(string userAgent)
{
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking stack
if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
}
}

BIN
src/EventHub.IdentityServer/account.openeventhub.pfx

Binary file not shown.

2
src/EventHub.IdentityServer/appsettings.Development.json

@ -1,2 +0,0 @@
{
}

21
src/EventHub.IdentityServer/appsettings.json

@ -1,27 +1,8 @@
{
"App": {
"SelfUrl": "https://localhost:44313",
"CorsOrigins": "https://*.EventHub.com,http://localhost:4200,https://localhost:44307,https://localhost:44362",
"RedirectAllowedUrls": "http://localhost:4200,https://localhost:44307"
},
"ConnectionStrings": {
"Default": "Host=localhost;Database=EventHub;Username=root;Password=root;Port=5432"
},
"Redis": {
"Configuration": "127.0.0.1"
},
"StringEncryption": {
"DefaultPassPhrase": "TxVIZFPxK33czbbv"
},
"Settings": {
"Abp.Mailing.Smtp.Host": "127.0.0.1",
"Abp.Mailing.Smtp.Port": "25",
"Abp.Mailing.Smtp.UserName": "",
"Abp.Mailing.Smtp.Password": "",
"Abp.Mailing.Smtp.Domain": "",
"Abp.Mailing.Smtp.EnableSsl": "false",
"Abp.Mailing.Smtp.UseDefaultCredentials": "true",
"Abp.Mailing.DefaultFromAddress": "noreply@abp.io",
"Abp.Mailing.DefaultFromDisplayName": "ABP application"
"Configuration": "localhost"
}
}

8
src/EventHub.Web.Theme/Themes/EventHub/Components/Footer/Default.cshtml

@ -1,7 +1,9 @@
@using EventHub.Web
@using Microsoft.AspNetCore.Http.Extensions
@using Microsoft.Extensions.Options
@using Volo.Abp.Users
@inject ICurrentUser CurrentUser
@inject IOptions<EventHubUrlOptions> UrlOptions
<footer class="mt-5">
<div class="container">
@ -18,7 +20,7 @@
<h5>Account</h5>
<div class="footer-links">
<a href="@EventHubExternalUrls.EhAccount/account/register?returnUrl=@EventHubExternalUrls.EhWww@(System.Net.WebUtility.UrlEncode(Context.Request.GetEncodedPathAndQuery()))" class="d-block">Sign Up</a>
<a href="@UrlOptions.Value.Account/account/register?returnUrl=@UrlOptions.Value.Www@(System.Net.WebUtility.UrlEncode(Context.Request.GetEncodedPathAndQuery()))" class="d-block">Sign Up</a>
<a href="/account/login?returnUrl=@(System.Net.WebUtility.UrlEncode(Context.Request.GetEncodedPathAndQuery()))" class="d-block">Log In</a>
</div>
@ -51,13 +53,13 @@
<span class="copyright">© 2021 EventHub</span>
</div>
<div class="col-md text-center text-md-right">
<a href="@EventHubExternalUrls.EhWww/terms-service">
<a href="@UrlOptions.Value.Www/terms-service">
Terms of Service
</a>
<span>
<img src="/assets/seperator2.svg" class="mx-3">
</span>
<a href="@EventHubExternalUrls.EhWww/privacy-policy">
<a href="@UrlOptions.Value.Www/privacy-policy">
Privacy Policy
</a>
</div>

20
src/EventHub.Web.Theme/Themes/EventHub/Components/MainNavbar/Default.cshtml

@ -3,10 +3,12 @@
@using Volo.Abp.Users
@using EventHub.Localization
@using Microsoft.AspNetCore.Http.Extensions
@using Microsoft.Extensions.Options
@using Volo.Abp.Localization
@inject ICurrentUser CurrentUser
@inject ILanguageProvider LanguageProvider
@inject IStringLocalizer<EventHubResource> L
@inject IOptions<EventHubUrlOptions> UrlOptions
@{
var returnUrl = System.Net.WebUtility.UrlEncode(Context.Request.GetEncodedPathAndQuery());
@ -26,22 +28,22 @@
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav mx-auto">
<li class="nav-item @(GetPageActiveClassOrEmpty(ViewContext, "/index"))">
<a class="nav-link" href="@EventHubExternalUrls.EhWww@Url.Page("/index")">
<a class="nav-link" href="@UrlOptions.Value.Www@Url.Page("/index")">
Home
</a>
</li>
<li class="nav-item @(GetPageActiveClassOrEmpty(ViewContext, "/events/index"))">
<a class="nav-link" href="@EventHubExternalUrls.EhWww/events">Events</a>
<a class="nav-link" href="@UrlOptions.Value.Www/events">Events</a>
</li>
<li class="nav-item @(GetPageActiveClassOrEmpty(ViewContext, "/organizations/index"))">
<a class="nav-link" href="@EventHubExternalUrls.EhWww/organizations">Organizations</a>
<a class="nav-link" href="@UrlOptions.Value.Www/organizations">Organizations</a>
</li>
</ul>
@if (EventHubExternalUrls.EhWww.Contains(Context.Request.Host.ToString()))
@if (UrlOptions.Value.Www.Contains(Context.Request.Host.ToString()))
{
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link event-link" href="@EventHubExternalUrls.EhWww@Url.Page("/events/new")">+ Create an Event</a>
<a class="nav-link event-link" href="@UrlOptions.Value.Www@Url.Page("/events/new")">+ Create an Event</a>
</li>
</ul>
}
@ -68,10 +70,10 @@
</span>
</a>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="@(EventHubExternalUrls.EhAccount.EnsureEndsWith('/') + "account/manage")" title="@L["Account"]">
<a class="dropdown-item" href="@(UrlOptions.Value.Account.EnsureEndsWith('/') + "account/manage")" title="@L["Account"]">
<i class="fas fa-cog"></i> @L["Account"]
</a>
<a class="dropdown-item" href="@EventHubExternalUrls.EhWww/users/@CurrentUser.UserName" title="@L["Profile"]">
<a class="dropdown-item" href="@UrlOptions.Value.Www/users/@CurrentUser.UserName" title="@L["Profile"]">
<i class="fas fa-user"></i> @L["Profile"]
</a>
<a class="dropdown-item" href="/account/logout?returnUrl=@returnUrl" title="@L["Logout"]">
@ -86,7 +88,7 @@
<a class="nav-link" href="/account/login?returnUrl=@returnUrl">Log In</a>
</li>
<li class="nav-item">
<a class="btn btn-primary ml-lg-2" href="@EventHubExternalUrls.EhAccount/account/register?returnUrl=@returnUrl">Sign Up</a>
<a class="btn btn-primary ml-lg-2" href="@UrlOptions.Value.Account/account/register?returnUrl=@returnUrl">Sign Up</a>
</li>
}
</ul>
@ -97,7 +99,7 @@
@functions{
public string GetPageActiveClassOrEmpty(ViewContext viewContext, string pageUrl)
{
if (!EventHubExternalUrls.EhWww.Contains(Context.Request.Host.ToString()))
if (!UrlOptions.Value.Www.Contains(Context.Request.Host.ToString()))
{
return "";
}

7
src/EventHub.Web.Theme/Themes/EventHub/Layouts/Application.cshtml

@ -11,8 +11,11 @@
@using EventHub.Web.Theme.Themes.EventHub.Components.PageAlerts
@using EventHub.Web
@using Microsoft.AspNetCore.Http.Extensions
@using Microsoft.Extensions.Options
@inject IBrandingProvider BrandingProvider
@inject IPageLayout PageLayout
@inject IOptions<EventHubUrlOptions> UrlOptions
@{
Layout = null;
var pageTitle = ViewBag.Title == null ? "EventHub" : ViewBag.Title;
@ -47,12 +50,12 @@
<meta property="og:url" content="@Context.Request.GetDisplayUrl()"/>
<meta property="og:type" content="@(!string.IsNullOrWhiteSpace(ViewBag.OgType) ? ViewBag.OgType : "website")"/>
<meta property="og:description" content="@(!string.IsNullOrWhiteSpace(ViewBag.OgDescription) ? ViewBag.OgDescription : "EventHub Description")"/>
<meta property="og:image" content="@(!string.IsNullOrWhiteSpace(ViewBag.OgImage) ? ViewBag.OgImage : EventHubExternalUrls.EhWww + "/assets/slide.jpg")"/>
<meta property="og:image" content="@(!string.IsNullOrWhiteSpace(ViewBag.OgImage) ? ViewBag.OgImage : UrlOptions.Value.Www + "/assets/slide.jpg")"/>
<meta property="twitter:card" content="summary_large_image"/>
<meta property="twitter:site" content="@Html.Raw("@openeventhub")"/>
<meta property="twitter:title" content="@(!string.IsNullOrWhiteSpace(ViewBag.TwitterTitle) ? ViewBag.TwitterTitle : "EventHub")"/>
<meta property="twitter:description" content="@(!string.IsNullOrWhiteSpace(ViewBag.TwitterDescription) ? ViewBag.TwitterDescription : "EventHub Description")"/>
<meta property="twitter:image" content="@(!string.IsNullOrWhiteSpace(ViewBag.TwitterImage) ? ViewBag.TwitterImage : EventHubExternalUrls.EhWww + "/assets/slide.jpg")"/>
<meta property="twitter:image" content="@(!string.IsNullOrWhiteSpace(ViewBag.TwitterImage) ? ViewBag.TwitterImage : UrlOptions.Value.Www + "/assets/slide.jpg")"/>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">

6
src/EventHub.Web.Theme/wwwroot/themes/eventhub/owl-edit.css

@ -10,7 +10,7 @@
.main-slider .owl-carousel .owl-nav button.owl-next {
width: 40px;
height: 40px;
background: rgb(0 4 74 / 20%);
background: rgba(0, 4, 74, 0.2);
transition: background-color .3s ease;
position: absolute;
display: inline-block;
@ -24,7 +24,7 @@
}
.main-slider .owl-carousel .owl-nav button.owl-prev:hover,
.main-slider .owl-carousel .owl-nav button.owl-next:hover {
background: rgb(255 255 255 / 35%);
background: rgba(255, 255, 255, 0.35);
}
.main-slider .owl-carousel .owl-nav button span {
font-size: 40px;
@ -65,7 +65,7 @@
.card-slider .owl-carousel .owl-nav button.owl-next {
width: 9px;
height: 15px;
background: rgb(255 255 255 / 22%);
background: rgba(255, 255, 255, 0.22);
transition: background-color .3s ease;
display: inline-block;
overflow: hidden;

6
src/EventHub.Web.Theme/wwwroot/themes/eventhub/style.css

@ -754,7 +754,7 @@ div.checkbox.switcher label, div.radio.switcher label {
margin-right: 10px;
width: 56px;
height: 30px;
background: rgb(107 126 146 / 20%);
background: rgba(107, 126, 146, 0.20);
border: 3px solid #e1e5e9;
border-radius: 50px;
transition: all 0.3s ease-in-out;
@ -791,7 +791,7 @@ div.checkbox.switcher label, div.radio.switcher label {
.image-area {
border: 2px dashed rgb(218 224 229);
border: 2px dashed rgb(218, 224, 229);
padding: 1em;
position: relative;
border-radius: 10px;
@ -802,7 +802,7 @@ div.checkbox.switcher label, div.radio.switcher label {
.image-area::before {
content: 'Uploaded image result';
color: rgb(218 224 229);
color: rgb(218, 224, 229);
font-weight: bold;
text-transform: uppercase;
position: absolute;

4
src/EventHub.Web/Dockerfile

@ -0,0 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0
COPY bin/Release/net5.0/publish/ app/
WORKDIR /app
ENTRYPOINT ["dotnet", "EventHub.Web.dll"]

26
src/EventHub.Web/EventHubWebModule.cs

@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
@ -11,6 +12,7 @@ using EventHub.Localization;
using EventHub.Web.Menus;
using EventHub.Web.Theme;
using EventHub.Web.Theme.Bundling;
using EventHub.Web.Utils;
using Microsoft.AspNetCore.Mvc.RazorPages;
using StackExchange.Redis;
using Microsoft.OpenApi.Models;
@ -27,6 +29,7 @@ using Volo.Abp.Autofac;
using Volo.Abp.AutoMapper;
using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.IdentityModel.Web;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
@ -78,6 +81,7 @@ namespace EventHub.Web
ConfigureAutoMapper();
ConfigureVirtualFileSystem(hostingEnvironment);
ConfigureNavigationServices(configuration);
ConfigureCookies(context);
ConfigureSwaggerServices(context.Services);
ConfigureRazorPageOptions();
}
@ -108,7 +112,15 @@ namespace EventHub.Web
{
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
options.Applications["MVC"].RootUrl = configuration[EventHubUrlOptions.GetWwwConfigKey()];
});
Configure<AbpRemoteServiceOptions>(options =>
{
options.RemoteServices.Default = new RemoteServiceConfiguration(
configuration[EventHubUrlOptions.GetApiInternalConfigKey()]
.EnsureEndsWith('/')
);
});
}
@ -187,6 +199,11 @@ namespace EventHub.Web
options.Contributors.Add(new EventHubToolbarContributor());
});
}
private void ConfigureCookies(ServiceConfigurationContext context)
{
context.Services.AddSameSiteCookiePolicy();
}
private void ConfigureSwaggerServices(IServiceCollection services)
{
@ -214,6 +231,12 @@ namespace EventHub.Web
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
if (env.IsDevelopment())
{
@ -227,6 +250,7 @@ namespace EventHub.Web
app.UseErrorPage();
}
app.UseCookiePolicy();
app.UseCorrelationId();
app.UseStaticFiles();
app.UseRouting();

2
src/EventHub.Web/Menus/EventHubMenuContributor.cs

@ -51,7 +51,7 @@ namespace EventHub.Web.Menus
if (currentUser.IsAuthenticated)
{
context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountStringLocalizer["ManageYourProfile"],
$"{identityServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", icon: "fa fa-cog", order: 1000, null, "_blank"));
$"{identityServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration[EventHubUrlOptions.GetWwwConfigKey()]}", icon: "fa fa-cog", order: 1000, null, "_blank"));
context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "~/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000));
}

6
src/EventHub.Web/Pages/Events/Detail.cshtml

@ -9,11 +9,13 @@
@using EventHub.Web.Pages.Events.Components.LocationArea
@using EventHub.Web.Pages.Events.Components.RegistrationArea
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
@using Volo.Abp.Timing
@using Volo.Abp.Users
@inject ICurrentUser CurrentUser
@inject IClock Clock
@model EventHub.Web.Pages.Events.DetailPageModel
@inject IOptions<EventHubUrlOptions> UrlOptions
@section scripts {
<abp-script src="/Pages/Events/Detail.js"/>
@ -27,11 +29,11 @@
if (Model.Event.CoverImageContent is null)
{
// TODO(berkansasmaz): Get a default image from the design team to be used in social media posts
coverImageUrl = EventHubExternalUrls.EhWww + "/assets/slide.jpg";
coverImageUrl = UrlOptions.Value.Www + "/assets/slide.jpg";
}
else
{
coverImageUrl = $"{EventHubExternalUrls.EhWww}/api/event/cover-picture-source/{Model.Event.Id}";
coverImageUrl = $"{UrlOptions.Value.Www}/api/event/cover-picture-source/{Model.Event.Id}";
}
ViewBag.Title = title;

4
src/EventHub.Web/Pages/Index.cshtml

@ -6,11 +6,13 @@
@using EventHub.Web
@using EventHub.Web.Helpers
@using EventHub.Web.Pages.Events.Components.EventsArea
@using Microsoft.Extensions.Options
@using Volo.Abp.Timing
@using Volo.Abp.Users
@inject ICurrentUser CurrentUser
@inject IClock Clock
@inject IHtmlLocalizer<EventHubResource> L
@inject IOptions<EventHubUrlOptions> UrlOptions
@section styles {
<abp-style-bundle>
@ -225,7 +227,7 @@
</p>
@if (!CurrentUser.IsAuthenticated)
{
<a href="@EventHubExternalUrls.EhAccount/Account/Register?returnUrl=@EventHubExternalUrls.EhWww" class="btn btn-link btn-lg">Join EventHub</a>
<a href="@UrlOptions.Value.Account/Account/Register?returnUrl=@UrlOptions.Value.Www" class="btn btn-link btn-lg">Join EventHub</a>
}
</div>
</div>

2
src/EventHub.Web/Program.cs

@ -20,9 +20,7 @@ namespace EventHub.Web
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Async(c => c.File("Logs/logs.txt"))
#if DEBUG
.WriteTo.Async(c => c.Console())
#endif
.CreateLogger();
try

71
src/EventHub.Web/Utils/SameSiteCookiesServiceCollectionExtensions.cs

@ -0,0 +1,71 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace EventHub.Web.Utils
{
public static class SameSiteCookiesServiceCollectionExtensions
{
public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
return services;
}
private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent))
{
// For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
options.SameSite = SameSiteMode.Unspecified;
}
}
}
private static bool DisallowsSameSiteNone(string userAgent)
{
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking stack
if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
}
}

3
src/EventHub.Web/appsettings.Development.json

@ -1,3 +0,0 @@
{
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save