Skip to content

Commit 8beae9e

Browse files
committed
feat(organization): add oauth2 login support
1 parent cefaa2c commit 8beae9e

64 files changed

Lines changed: 5390 additions & 2733 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
^backup$
2+
^catalog$
3+
^cert-manager$
4+
^default$
5+
^drycc(?:-[\w-]+)?$
6+
^istio(?:-[\w-]+)?$
7+
^kube(?:-[\w-]+)?$
8+
^longhorn-system$
9+
^metallb$
10+
^mount-s3$
11+
^topolvm$
12+
^rook-ceph$
13+
^personal$

charts/passport/templates/passport-configmap.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ metadata:
55
labels:
66
heritage: drycc
77
data:
8-
reserved-usernames.txt: |-
9-
{{- if .Values.reservedUsernames }}
10-
{{- (tpl .Values.reservedUsernames $) | nindent 4 }}
11-
{{- else}}
12-
{{- include "passport.defaultReservedUsernames" . | nindent 4 }}
13-
{{- end }}
148
init-applications.json: |-
159
{{ toPrettyJson .Values.initApplications | indent 4 }}
10+
reserved-name-patterns.txt: |-
11+
{{- if .Values.config.reservedNames }}
12+
{{- (tpl .Values.config.reservedNames $) | nindent 4 }}
13+
{{- else}}
14+
{{- .Files.Get "files/reserved-name-patterns.txt" | nindent 4 }}
15+
{{- end }}

rootfs/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ FROM registry.drycc.cc/drycc/base:${CODENAME} as build-app
44
ADD web /web
55
WORKDIR /web
66

7-
ENV NODE_VERSION="22"
7+
ENV NODE_VERSION="24"
88

99
RUN install-stack node $NODE_VERSION && . init-stack \
1010
&& npm install --global yarn \
@@ -16,7 +16,7 @@ FROM registry.drycc.cc/drycc/base:${CODENAME}
1616
ARG DRYCC_UID=1001 \
1717
DRYCC_GID=1001 \
1818
DRYCC_HOME_DIR=/workspace \
19-
PYTHON_VERSION="3.13"
19+
PYTHON_VERSION="3.14"
2020

2121
RUN groupadd drycc --gid ${DRYCC_GID} \
2222
&& useradd drycc -u ${DRYCC_UID} -g ${DRYCC_GID} -s /bin/bash -m -d ${DRYCC_HOME_DIR}

rootfs/Dockerfile.test

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1+
ARG CODENAME
2+
FROM registry.drycc.cc/drycc/base:${CODENAME} as build-app
3+
4+
ADD web /web
5+
WORKDIR /web
6+
7+
ENV NODE_VERSION="24"
8+
9+
RUN install-stack node $NODE_VERSION && . init-stack \
10+
&& npm install --global yarn \
11+
&& yarn install \
12+
&& yarn build
13+
14+
115
ARG CODENAME
216
FROM registry.drycc.cc/drycc/base:${CODENAME}
317

4-
ARG DRYCC_HOME_DIR=/workspace \
5-
PYTHON_VERSION="3.13" \
6-
POSTGRES_VERSION="17.6" \
7-
GOSU_VERSION="1.18"
18+
ARG DRYCC_UID=1001 \
19+
DRYCC_GID=1001 \
20+
DRYCC_HOME_DIR=/workspace \
21+
PYTHON_VERSION="3.14" \
22+
VALKEY_VERSION="9.0.1" \
23+
POSTGRES_VERSION="18.1" \
24+
GOSU_VERSION="1.19"
25+
26+
27+
RUN groupadd drycc --gid ${DRYCC_GID} \
28+
&& useradd drycc -u ${DRYCC_UID} -g ${DRYCC_GID} -s /bin/bash -m -d ${DRYCC_HOME_DIR}
829

930
ENV PGDATA="/var/lib/postgresql/data"
1031

@@ -16,6 +37,7 @@ RUN buildDeps='gcc rustc cargo libffi-dev musl-dev libldap2-dev libsasl2-dev'; \
1637
&& curl -SsL https://cli.codecov.io/latest/$([ $(dpkg --print-architecture) == "arm64" ] && echo linux-arm64 || echo linux)/codecov -o /usr/local/bin/codecov \
1738
&& chmod +x /usr/local/bin/codecov \
1839
&& install-stack python $PYTHON_VERSION \
40+
&& install-stack valkey $VALKEY_VERSION \
1941
&& install-stack postgresql $POSTGRES_VERSION \
2042
&& install-stack gosu $GOSU_VERSION && . init-stack \
2143
&& python3 -m venv ${DRYCC_HOME_DIR}/.venv \
@@ -50,6 +72,9 @@ RUN buildDeps='gcc rustc cargo libffi-dev musl-dev libldap2-dev libsasl2-dev'; \
5072
&& gosu postgres initdb -D $PGDATA
5173

5274
COPY . ${DRYCC_HOME_DIR}
75+
COPY --chown=${DRYCC_UID}:${DRYCC_GID} . ${DRYCC_HOME_DIR}
76+
COPY --chown=${DRYCC_UID}:${DRYCC_GID} --from=build-app /web/dist ${DRYCC_HOME_DIR}/web/dist
77+
5378
WORKDIR ${DRYCC_HOME_DIR}
5479
CMD ["bin/boot"]
5580
EXPOSE 8000

rootfs/api/apps.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django import apps
2+
3+
4+
class AppConfig(apps.AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
6+
name = 'api'
7+
8+
def ready(self):
9+
super(AppConfig, self).ready()
10+
__import__("api.signals")

rootfs/api/apps_extra/__init__.py

Whitespace-only changes.

rootfs/api/apps_extra/social_core/__init__.py

Whitespace-only changes.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import json
2+
from os.path import join, dirname
3+
from pathlib import Path
4+
from social_core.backends.oauth import BaseOAuth2
5+
from social_core.backends.github import GithubOAuth2 as BaseGithubOAuth2
6+
from social_core.backends.google import GoogleOAuth2 as BaseGoogleOAuth2
7+
from social_core.backends.weixin import WeixinOAuth2 as BaseWeixinOAuth2
8+
9+
10+
def icon_path(name):
11+
return Path(join(dirname(__file__), "icons", f"{name}.svg"))
12+
13+
14+
class GithubOAuth2(BaseGithubOAuth2):
15+
icon = icon_path("github").read_text(encoding="utf-8")
16+
17+
18+
class GoogleOAuth2(BaseGoogleOAuth2):
19+
name = "google"
20+
icon = icon_path("google").read_text(encoding="utf-8")
21+
22+
23+
class WeixinOAuth2(BaseWeixinOAuth2):
24+
icon = icon_path("weixin").read_text(encoding="utf-8")
25+
26+
27+
class FeiShuOAuth2(BaseOAuth2):
28+
"""FeiShu OAuth2 authentication backend"""
29+
name = 'feishu'
30+
icon = icon_path("feishu").read_text(encoding="utf-8")
31+
32+
AUTHORIZATION_URL = 'https://accounts.feishu.cn/open-apis/authen/v1/authorize'
33+
ACCESS_TOKEN_URL = 'https://open.feishu.cn/open-apis/authen/v2/oauth/token'
34+
USER_INFO_URL = 'https://open.feishu.cn/open-apis/authen/v1/user_info'
35+
36+
DEFAULT_SCOPE = ['']
37+
REDIRECT_STATE = False
38+
ACCESS_TOKEN_METHOD = 'POST'
39+
EXTRA_DATA = [
40+
('refresh_token', 'refresh_token'),
41+
('expires_in', 'expires'),
42+
('union_id', 'union_id'),
43+
('access_token', 'access_token'),
44+
]
45+
46+
def request_access_token(self, *args, **kwargs):
47+
"""Override to send JSON request provided by FeiShu"""
48+
if 'data' in kwargs:
49+
kwargs['data']['app_id'] = self.setting('KEY')
50+
kwargs['data']['app_secret'] = self.setting('SECRET')
51+
kwargs['data'] = json.dumps(kwargs['data'])
52+
if 'headers' not in kwargs:
53+
kwargs['headers'] = {}
54+
kwargs['headers']['Content-Type'] = 'application/json; charset=utf-8'
55+
return super().request_access_token(*args, **kwargs)
56+
57+
def get_user_details(self, response):
58+
"""Return user details from FeiShu account"""
59+
return {
60+
'username': response.get('name', ''),
61+
'email': response.get('email', ''),
62+
}
63+
64+
def user_data(self, access_token, *args, **kwargs):
65+
"""Loads user data from service"""
66+
headers = {
67+
'Authorization': f'Bearer {access_token}',
68+
'Content-Type': 'application/json; charset=utf-8'
69+
}
70+
response = self.get_json(
71+
self.USER_INFO_URL,
72+
headers=headers
73+
)
74+
# FeiShu returns data wrapped in 'data' field
75+
if 'data' in response:
76+
response.update(response['data'])
77+
78+
response['union_id'] = response.get('union_id', '')
79+
return response
80+
81+
82+
__all__ = [GithubOAuth2, GoogleOAuth2, WeixinOAuth2, FeiShuOAuth2]
Lines changed: 12 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)