mirror of
https://github.com/haiwen/seahub.git
synced 2025-07-17 00:32:37 +00:00
parent
13c9525df1
commit
f6fb7ce715
45
frontend/src/components/dialog/confirm-disconnect-weixin.js
Normal file
45
frontend/src/components/dialog/confirm-disconnect-weixin.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
|
||||||
|
import { gettext } from '../../utils/constants';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
formActionURL: PropTypes.string.isRequired,
|
||||||
|
csrfToken: PropTypes.string.isRequired,
|
||||||
|
toggle: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConfirmDisconnectWeixin extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.form = React.createRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect = () => {
|
||||||
|
this.form.current.submit();
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { formActionURL, csrfToken, toggle } = this.props;
|
||||||
|
return (
|
||||||
|
<Modal centered={true} isOpen={true} toggle={toggle}>
|
||||||
|
<ModalHeader toggle={toggle}>{gettext('Disconnect')}</ModalHeader>
|
||||||
|
<ModalBody>
|
||||||
|
<p>{gettext('Are you sure you want to disconnect?')}</p>
|
||||||
|
<form ref={this.form} className="d-none" method="post" action={formActionURL}>
|
||||||
|
<input type="hidden" name="csrfmiddlewaretoken" value={csrfToken} />
|
||||||
|
</form>
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button color="secondary" onClick={toggle}>{gettext('Cancel')}</Button>
|
||||||
|
<Button color="primary" onClick={this.disconnect}>{gettext('Disconnect')}</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfirmDisconnectWeixin.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default ConfirmDisconnectWeixin;
|
59
frontend/src/components/user-settings/social-login-weixin.js
Normal file
59
frontend/src/components/user-settings/social-login-weixin.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { gettext, siteRoot } from '../../utils/constants';
|
||||||
|
import ModalPortal from '../modal-portal';
|
||||||
|
import ConfirmDisconnectWeixin from '../dialog/confirm-disconnect-weixin';
|
||||||
|
|
||||||
|
const {
|
||||||
|
csrfToken,
|
||||||
|
langCode,
|
||||||
|
socialConnectedWeixin,
|
||||||
|
socialNextPage
|
||||||
|
} = window.app.pageOptions;
|
||||||
|
|
||||||
|
class SocialLoginWeixin extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isConfirmDialogOpen: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmDisconnect = () => {
|
||||||
|
this.setState({
|
||||||
|
isConfirmDialogOpen: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
toggleDialog = () => {
|
||||||
|
this.setState({
|
||||||
|
isConfirmDialogOpen: !this.state.isConfirmDialogOpen
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div className="setting-item" id="social-auth">
|
||||||
|
<h3 className="setting-item-heading">{gettext('Social Login')}</h3>
|
||||||
|
<p className="mb-2">{langCode == 'zh-cn' ? '微信' : 'Weixin'}</p>
|
||||||
|
{socialConnectedWeixin ?
|
||||||
|
<button className="btn btn-outline-primary" onClick={this.confirmDisconnect}>{gettext('Disconnect')}</button> :
|
||||||
|
<a href={`${siteRoot}weixin/oauth-connect/?next=${encodeURIComponent(socialNextPage)}`} className="btn btn-outline-primary">{gettext('Connect')}</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
{this.state.isConfirmDialogOpen && (
|
||||||
|
<ModalPortal>
|
||||||
|
<ConfirmDisconnectWeixin
|
||||||
|
formActionURL={`${siteRoot}weixin/oauth-disconnect/?next=${encodeURIComponent(socialNextPage)}`}
|
||||||
|
csrfToken={csrfToken}
|
||||||
|
toggle={this.toggleDialog}
|
||||||
|
/>
|
||||||
|
</ModalPortal>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SocialLoginWeixin;
|
@ -19,6 +19,7 @@ import EmailNotice from './components/user-settings/email-notice';
|
|||||||
import TwoFactorAuthentication from './components/user-settings/two-factor-auth';
|
import TwoFactorAuthentication from './components/user-settings/two-factor-auth';
|
||||||
import SocialLogin from './components/user-settings/social-login';
|
import SocialLogin from './components/user-settings/social-login';
|
||||||
import SocialLoginDingtalk from './components/user-settings/social-login-dingtalk';
|
import SocialLoginDingtalk from './components/user-settings/social-login-dingtalk';
|
||||||
|
import SocialLoginWeixin from './components/user-settings/social-login-weixin';
|
||||||
import SocialLoginSAML from './components/user-settings/social-login-saml';
|
import SocialLoginSAML from './components/user-settings/social-login-saml';
|
||||||
import LinkedDevices from './components/user-settings/linked-devices';
|
import LinkedDevices from './components/user-settings/linked-devices';
|
||||||
import DeleteAccount from './components/user-settings/delete-account';
|
import DeleteAccount from './components/user-settings/delete-account';
|
||||||
@ -39,6 +40,7 @@ const {
|
|||||||
twoFactorAuthEnabled,
|
twoFactorAuthEnabled,
|
||||||
enableWechatWork,
|
enableWechatWork,
|
||||||
enableDingtalk,
|
enableDingtalk,
|
||||||
|
enableWeixin,
|
||||||
isOrgContext,
|
isOrgContext,
|
||||||
enableADFS,
|
enableADFS,
|
||||||
enableMultiADFS,
|
enableMultiADFS,
|
||||||
@ -59,7 +61,7 @@ class Settings extends React.Component {
|
|||||||
{ show: true, href: '#lang-setting', text: gettext('Language') },
|
{ show: true, href: '#lang-setting', text: gettext('Language') },
|
||||||
{ show: isPro, href: '#email-notice', text: gettext('Email Notification') },
|
{ show: isPro, href: '#email-notice', text: gettext('Email Notification') },
|
||||||
{ show: twoFactorAuthEnabled, href: '#two-factor-auth', text: gettext('Two-Factor Authentication') },
|
{ show: twoFactorAuthEnabled, href: '#two-factor-auth', text: gettext('Two-Factor Authentication') },
|
||||||
{ show: (enableWechatWork || enableDingtalk || enableADFS || (enableMultiADFS || isOrgContext)), href: '#social-auth', text: gettext('Social Login') },
|
{ show: (enableWechatWork || enableDingtalk || enableWeixin || enableADFS || (enableMultiADFS || isOrgContext)), href: '#social-auth', text: gettext('Social Login') },
|
||||||
{ show: true, href: '#linked-devices', text: gettext('Linked Devices') },
|
{ show: true, href: '#linked-devices', text: gettext('Linked Devices') },
|
||||||
{ show: enableDeleteAccount, href: '#del-account', text: gettext('Delete Account') },
|
{ show: enableDeleteAccount, href: '#del-account', text: gettext('Delete Account') },
|
||||||
];
|
];
|
||||||
@ -180,6 +182,7 @@ class Settings extends React.Component {
|
|||||||
{twoFactorAuthEnabled && <TwoFactorAuthentication />}
|
{twoFactorAuthEnabled && <TwoFactorAuthentication />}
|
||||||
{enableWechatWork && <SocialLogin />}
|
{enableWechatWork && <SocialLogin />}
|
||||||
{enableDingtalk && <SocialLoginDingtalk />}
|
{enableDingtalk && <SocialLoginDingtalk />}
|
||||||
|
{enableWeixin && <SocialLoginWeixin />}
|
||||||
{(enableADFS || (enableMultiADFS && isOrgContext)) && <SocialLoginSAML />}
|
{(enableADFS || (enableMultiADFS && isOrgContext)) && <SocialLoginSAML />}
|
||||||
<LinkedDevices />
|
<LinkedDevices />
|
||||||
{enableDeleteAccount && <DeleteAccount />}
|
{enableDeleteAccount && <DeleteAccount />}
|
||||||
|
@ -78,6 +78,12 @@ window.app.pageOptions = {
|
|||||||
socialNextPage: "{{ social_next_page|escapejs }}",
|
socialNextPage: "{{ social_next_page|escapejs }}",
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
enableWeixin: {% if enable_weixin %} true {% else %} false {% endif %},
|
||||||
|
{% if enable_weixin %}
|
||||||
|
socialConnectedWeixin: {% if social_connected_weixin %} true {% else %} false {% endif %},
|
||||||
|
socialNextPage: "{{ social_next_page|escapejs }}",
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
enableADFS: {% if enable_adfs %} true {% else %} false {% endif %},
|
enableADFS: {% if enable_adfs %} true {% else %} false {% endif %},
|
||||||
{% if enable_adfs %}
|
{% if enable_adfs %}
|
||||||
samlConnected: {% if saml_connected %} true {% else %} false {% endif %},
|
samlConnected: {% if saml_connected %} true {% else %} false {% endif %},
|
||||||
|
@ -26,10 +26,11 @@ from seahub.views import get_owned_repo_list
|
|||||||
from seahub.work_weixin.utils import work_weixin_oauth_check
|
from seahub.work_weixin.utils import work_weixin_oauth_check
|
||||||
from seahub.settings import ENABLE_DELETE_ACCOUNT, ENABLE_UPDATE_USER_INFO, ENABLE_ADFS_LOGIN, ENABLE_MULTI_ADFS
|
from seahub.settings import ENABLE_DELETE_ACCOUNT, ENABLE_UPDATE_USER_INFO, ENABLE_ADFS_LOGIN, ENABLE_MULTI_ADFS
|
||||||
from seahub.dingtalk.settings import ENABLE_DINGTALK
|
from seahub.dingtalk.settings import ENABLE_DINGTALK
|
||||||
|
from seahub.weixin.settings import ENABLE_WEIXIN
|
||||||
from constance import config
|
from constance import config
|
||||||
try:
|
try:
|
||||||
from seahub.settings import SAML_PROVIDER_IDENTIFIER
|
from seahub.settings import SAML_PROVIDER_IDENTIFIER
|
||||||
except ImportError as e:
|
except ImportError:
|
||||||
SAML_PROVIDER_IDENTIFIER = 'saml'
|
SAML_PROVIDER_IDENTIFIER = 'saml'
|
||||||
|
|
||||||
|
|
||||||
@ -107,6 +108,14 @@ def edit_profile(request):
|
|||||||
enable_dingtalk = False
|
enable_dingtalk = False
|
||||||
social_connected_dingtalk = False
|
social_connected_dingtalk = False
|
||||||
|
|
||||||
|
if ENABLE_WEIXIN:
|
||||||
|
enable_weixin = True
|
||||||
|
social_connected_weixin = SocialAuthUser.objects.filter(
|
||||||
|
username=request.user.username, provider='weixin').count() > 0
|
||||||
|
else:
|
||||||
|
enable_weixin = False
|
||||||
|
social_connected_weixin = False
|
||||||
|
|
||||||
if ENABLE_ADFS_LOGIN:
|
if ENABLE_ADFS_LOGIN:
|
||||||
enable_adfs = True
|
enable_adfs = True
|
||||||
saml_connected = SocialAuthUser.objects.filter(
|
saml_connected = SocialAuthUser.objects.filter(
|
||||||
@ -164,6 +173,8 @@ def edit_profile(request):
|
|||||||
'social_connected': social_connected,
|
'social_connected': social_connected,
|
||||||
'enable_dingtalk': enable_dingtalk,
|
'enable_dingtalk': enable_dingtalk,
|
||||||
'social_connected_dingtalk': social_connected_dingtalk,
|
'social_connected_dingtalk': social_connected_dingtalk,
|
||||||
|
'enable_weixin': enable_weixin,
|
||||||
|
'social_connected_weixin': social_connected_weixin,
|
||||||
'ENABLE_USER_SET_CONTACT_EMAIL': settings.ENABLE_USER_SET_CONTACT_EMAIL,
|
'ENABLE_USER_SET_CONTACT_EMAIL': settings.ENABLE_USER_SET_CONTACT_EMAIL,
|
||||||
'ENABLE_USER_SET_NAME': settings.ENABLE_USER_SET_NAME,
|
'ENABLE_USER_SET_NAME': settings.ENABLE_USER_SET_NAME,
|
||||||
'user_unusable_password': request.user.enc_password == UNUSABLE_PASSWORD,
|
'user_unusable_password': request.user.enc_password == UNUSABLE_PASSWORD,
|
||||||
|
@ -271,6 +271,7 @@ INSTALLED_APPS = [
|
|||||||
'seahub.file_tags',
|
'seahub.file_tags',
|
||||||
'seahub.related_files',
|
'seahub.related_files',
|
||||||
'seahub.work_weixin',
|
'seahub.work_weixin',
|
||||||
|
'seahub.weixin',
|
||||||
'seahub.dingtalk',
|
'seahub.dingtalk',
|
||||||
'seahub.file_participants',
|
'seahub.file_participants',
|
||||||
'seahub.repo_api_tokens',
|
'seahub.repo_api_tokens',
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block main_content %}
|
||||||
|
<div class="text-panel">
|
||||||
|
<p class="error">没找到对应的账号,请先用邮箱注册一个团队账号,然后在个人设置页绑定微信后再扫码登录。</p>
|
||||||
|
<p class="error"><a href="{% url 'org_register' %}">[注册团队账号]</a></p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -2,9 +2,13 @@
|
|||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from seahub.weixin.views import weixin_oauth_login, weixin_oauth_callback
|
from seahub.weixin.views import weixin_oauth_login, weixin_oauth_callback, \
|
||||||
|
weixin_oauth_disconnect, weixin_oauth_connect, weixin_oauth_connect_callback
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('oauth-login/', weixin_oauth_login, name='weixin_oauth_login'),
|
path('oauth-login/', weixin_oauth_login, name='weixin_oauth_login'),
|
||||||
path('oauth-callback/', weixin_oauth_callback, name='weixin_oauth_callback'),
|
path('oauth-callback/', weixin_oauth_callback, name='weixin_oauth_callback'),
|
||||||
|
path('oauth-connect/', weixin_oauth_connect, name='weixin_oauth_connect'),
|
||||||
|
path('oauth-connect-callback/', weixin_oauth_connect_callback, name='weixin_oauth_connect_callback'),
|
||||||
|
path('oauth-disconnect/', weixin_oauth_disconnect, name='weixin_oauth_disconnect'),
|
||||||
]
|
]
|
||||||
|
@ -9,6 +9,7 @@ from django.http import HttpResponseRedirect
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
from seahub.api2.utils import get_api_token
|
from seahub.api2.utils import get_api_token
|
||||||
|
|
||||||
@ -18,13 +19,15 @@ from seahub.avatar.models import Avatar
|
|||||||
from seahub.profile.models import Profile
|
from seahub.profile.models import Profile
|
||||||
from seahub.utils import render_error, get_site_scheme_and_netloc
|
from seahub.utils import render_error, get_site_scheme_and_netloc
|
||||||
from seahub.auth.models import SocialAuthUser
|
from seahub.auth.models import SocialAuthUser
|
||||||
|
from seahub.utils.auth import VIRTUAL_ID_EMAIL_DOMAIN
|
||||||
|
from seahub.auth.decorators import login_required
|
||||||
from seahub.settings import SITE_ROOT
|
from seahub.settings import SITE_ROOT
|
||||||
|
|
||||||
from seahub.weixin.settings import ENABLE_WEIXIN, \
|
from seahub.weixin.settings import ENABLE_WEIXIN, \
|
||||||
WEIXIN_OAUTH_APP_ID, WEIXIN_OAUTH_APP_SECRET, \
|
WEIXIN_OAUTH_APP_ID, WEIXIN_OAUTH_APP_SECRET, \
|
||||||
WEIXIN_OAUTH_SCOPE, WEIXIN_OAUTH_RESPONSE_TYPE, WEIXIN_OAUTH_QR_CONNECT_URL, \
|
WEIXIN_OAUTH_SCOPE, WEIXIN_OAUTH_RESPONSE_TYPE, WEIXIN_OAUTH_QR_CONNECT_URL, \
|
||||||
WEIXIN_OAUTH_GRANT_TYPE, WEIXIN_OAUTH_ACCESS_TOKEN_URL, \
|
WEIXIN_OAUTH_GRANT_TYPE, WEIXIN_OAUTH_ACCESS_TOKEN_URL, \
|
||||||
WEIXIN_OAUTH_USER_INFO_URL
|
WEIXIN_OAUTH_USER_INFO_URL, WEIXIN_OAUTH_CREATE_UNKNOWN_USER
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -34,15 +37,17 @@ logger = logging.getLogger(__name__)
|
|||||||
def weixin_oauth_login(request):
|
def weixin_oauth_login(request):
|
||||||
|
|
||||||
if not ENABLE_WEIXIN:
|
if not ENABLE_WEIXIN:
|
||||||
return render_error(request, _('Error, please contact administrator.'))
|
return render_error(request, _('Feature is not enabled.'))
|
||||||
|
|
||||||
state = str(uuid.uuid4())
|
state = str(uuid.uuid4())
|
||||||
request.session['weixin_oauth_login_state'] = state
|
request.session['weixin_oauth_login_state'] = state
|
||||||
request.session['weixin_oauth_login_redirect'] = request.GET.get(auth.REDIRECT_FIELD_NAME, '/')
|
redirect_to = request.GET.get(auth.REDIRECT_FIELD_NAME, SITE_ROOT)
|
||||||
|
request.session['weixin_oauth_login_redirect'] = redirect_to
|
||||||
|
|
||||||
|
redirect_uri = get_site_scheme_and_netloc() + reverse('weixin_oauth_callback')
|
||||||
data = {
|
data = {
|
||||||
'appid': WEIXIN_OAUTH_APP_ID,
|
'appid': WEIXIN_OAUTH_APP_ID,
|
||||||
'redirect_uri': get_site_scheme_and_netloc() + reverse('weixin_oauth_callback'),
|
'redirect_uri': redirect_uri,
|
||||||
'response_type': WEIXIN_OAUTH_RESPONSE_TYPE,
|
'response_type': WEIXIN_OAUTH_RESPONSE_TYPE,
|
||||||
'scope': WEIXIN_OAUTH_SCOPE,
|
'scope': WEIXIN_OAUTH_SCOPE,
|
||||||
'state': state,
|
'state': state,
|
||||||
@ -54,7 +59,7 @@ def weixin_oauth_login(request):
|
|||||||
def weixin_oauth_callback(request):
|
def weixin_oauth_callback(request):
|
||||||
|
|
||||||
if not ENABLE_WEIXIN:
|
if not ENABLE_WEIXIN:
|
||||||
return render_error(request, _('Error, please contact administrator.'))
|
return render_error(request, _('Feature is not enabled.'))
|
||||||
|
|
||||||
state = request.GET.get('state', '')
|
state = request.GET.get('state', '')
|
||||||
if not state or state != request.session.get('weixin_oauth_login_state', ''):
|
if not state or state != request.session.get('weixin_oauth_login_state', ''):
|
||||||
@ -89,6 +94,9 @@ def weixin_oauth_callback(request):
|
|||||||
email = None
|
email = None
|
||||||
is_new_user = True
|
is_new_user = True
|
||||||
|
|
||||||
|
if is_new_user and not WEIXIN_OAUTH_CREATE_UNKNOWN_USER:
|
||||||
|
return render(request, 'weixin/weixin_user_not_found_error.html')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user = auth.authenticate(remote_user=email)
|
user = auth.authenticate(remote_user=email)
|
||||||
email = user.username
|
email = user.username
|
||||||
@ -147,3 +155,88 @@ def weixin_oauth_callback(request):
|
|||||||
SITE_ROOT))
|
SITE_ROOT))
|
||||||
response.set_cookie('seahub_auth', email + '@' + api_token.key)
|
response.set_cookie('seahub_auth', email + '@' + api_token.key)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def weixin_oauth_connect(request):
|
||||||
|
|
||||||
|
if not ENABLE_WEIXIN:
|
||||||
|
return render_error(request, _('Feature is not enabled.'))
|
||||||
|
|
||||||
|
state = str(uuid.uuid4())
|
||||||
|
request.session['weixin_oauth_connect_state'] = state
|
||||||
|
redirect_to = request.GET.get(auth.REDIRECT_FIELD_NAME, SITE_ROOT)
|
||||||
|
request.session['weixin_oauth_connect_redirect'] = redirect_to
|
||||||
|
|
||||||
|
redirect_uri = get_site_scheme_and_netloc() + reverse('weixin_oauth_connect_callback')
|
||||||
|
data = {
|
||||||
|
'appid': WEIXIN_OAUTH_APP_ID,
|
||||||
|
'redirect_uri': redirect_uri,
|
||||||
|
'response_type': WEIXIN_OAUTH_RESPONSE_TYPE,
|
||||||
|
'scope': WEIXIN_OAUTH_SCOPE,
|
||||||
|
'state': state,
|
||||||
|
}
|
||||||
|
url = WEIXIN_OAUTH_QR_CONNECT_URL + '?' + urllib.parse.urlencode(data)
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def weixin_oauth_connect_callback(request):
|
||||||
|
|
||||||
|
if not ENABLE_WEIXIN:
|
||||||
|
return render_error(request, _('Feature is not enabled.'))
|
||||||
|
|
||||||
|
state = request.GET.get('state', '')
|
||||||
|
if not state or state != request.session.get('weixin_oauth_connect_state', ''):
|
||||||
|
logger.error('invalid state')
|
||||||
|
return render_error(request, _('Error, please contact administrator.'))
|
||||||
|
|
||||||
|
# get access_token and user openid
|
||||||
|
parameters = {
|
||||||
|
'appid': WEIXIN_OAUTH_APP_ID,
|
||||||
|
'secret': WEIXIN_OAUTH_APP_SECRET,
|
||||||
|
'code': request.GET.get('code'),
|
||||||
|
'grant_type': WEIXIN_OAUTH_GRANT_TYPE,
|
||||||
|
}
|
||||||
|
|
||||||
|
access_token_url = WEIXIN_OAUTH_ACCESS_TOKEN_URL + '?' + urllib.parse.urlencode(parameters)
|
||||||
|
access_token_json = requests.get(access_token_url).json()
|
||||||
|
|
||||||
|
openid = access_token_json.get('openid', '')
|
||||||
|
access_token = access_token_json.get('access_token', '')
|
||||||
|
if not access_token or not openid:
|
||||||
|
logger.error('invalid access_token or openid')
|
||||||
|
logger.error(access_token_url)
|
||||||
|
logger.error(access_token_json)
|
||||||
|
return render_error(request, _('Error, please contact administrator.'))
|
||||||
|
|
||||||
|
auth_user = SocialAuthUser.objects.get_by_provider_and_uid('weixin', openid)
|
||||||
|
if auth_user:
|
||||||
|
logger.warning('weixin account already exists %s' % openid)
|
||||||
|
return render_error(request, '出错了,此微信账号已被绑定')
|
||||||
|
|
||||||
|
username = request.user.username
|
||||||
|
SocialAuthUser.objects.add(username, 'weixin', openid)
|
||||||
|
|
||||||
|
weixin_oauth_connect_redirect = request.session['weixin_oauth_connect_redirect']
|
||||||
|
response = HttpResponseRedirect(weixin_oauth_connect_redirect)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def weixin_oauth_disconnect(request):
|
||||||
|
|
||||||
|
if not ENABLE_WEIXIN:
|
||||||
|
return render_error(request, _('Feature is not enabled.'))
|
||||||
|
|
||||||
|
username = request.user.username
|
||||||
|
if username[-(len(VIRTUAL_ID_EMAIL_DOMAIN)):] == VIRTUAL_ID_EMAIL_DOMAIN:
|
||||||
|
profile = Profile.objects.get_profile_by_user(username)
|
||||||
|
if not profile:
|
||||||
|
return render_error(request, '出错了,当前账号不能解绑微信')
|
||||||
|
|
||||||
|
SocialAuthUser.objects.delete_by_username_and_provider(username, 'weixin')
|
||||||
|
|
||||||
|
# redirect user to page
|
||||||
|
response = HttpResponseRedirect(request.GET.get(auth.REDIRECT_FIELD_NAME, SITE_ROOT))
|
||||||
|
return response
|
||||||
|
Loading…
Reference in New Issue
Block a user