1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-25 10:11:24 +00:00
seahub/seahub/work_weixin/views.py
2019-10-28 12:23:29 +08:00

230 lines
8.8 KiB
Python

# Copyright (c) 2012-2019 Seafile Ltd.
# encoding: utf-8
import uuid
import logging
import requests
import urllib.request, urllib.parse, urllib.error
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext as _
from seahub.auth.decorators import login_required
from seahub.utils import get_site_scheme_and_netloc
from seahub.api2.utils import get_api_token
from seahub import auth
from seahub.utils import render_error
from seahub.base.accounts import User
from seahub.work_weixin.settings import WORK_WEIXIN_AUTHORIZATION_URL, WORK_WEIXIN_CORP_ID, \
WORK_WEIXIN_AGENT_ID, WORK_WEIXIN_PROVIDER, \
WORK_WEIXIN_GET_USER_INFO_URL, WORK_WEIXIN_GET_USER_PROFILE_URL, WORK_WEIXIN_UID_PREFIX, \
WORK_WEIXIN_USER_INFO_AUTO_UPDATE
from seahub.work_weixin.utils import work_weixin_oauth_check, get_work_weixin_access_token, \
handler_work_weixin_api_response, update_work_weixin_user_info
from seahub.utils.auth import gen_user_virtual_id, VIRTUAL_ID_EMAIL_DOMAIN
from seahub.auth.models import SocialAuthUser
from django.core.urlresolvers import reverse
logger = logging.getLogger(__name__)
# # uid = corpid + '_' + userid
def work_weixin_oauth_login(request):
if not work_weixin_oauth_check():
return render_error(request, _('Feature is not enabled.'))
state = str(uuid.uuid4())
request.session['work_weixin_oauth_state'] = state
request.session['work_weixin_oauth_redirect'] = request.GET.get(auth.REDIRECT_FIELD_NAME, '/')
data = {
'appid': WORK_WEIXIN_CORP_ID,
'agentid': WORK_WEIXIN_AGENT_ID,
'redirect_uri': get_site_scheme_and_netloc() + reverse('work_weixin_oauth_callback'),
'state': state,
}
authorization_url = WORK_WEIXIN_AUTHORIZATION_URL + '?' + urllib.parse.urlencode(data)
return HttpResponseRedirect(authorization_url)
def work_weixin_oauth_callback(request):
if not work_weixin_oauth_check():
return render_error(request, _('Feature is not enabled.'))
code = request.GET.get('code', None)
state = request.GET.get('state', None)
if state != request.session.get('work_weixin_oauth_state', None) or not code:
logger.error('can not get right code or state from work weixin request')
return render_error(request, _('Error, please contact administrator.'))
access_token = get_work_weixin_access_token()
if not access_token:
logger.error('can not get work weixin access_token')
return render_error(request, _('Error, please contact administrator.'))
data = {
'access_token': access_token,
'code': code,
}
api_response = requests.get(WORK_WEIXIN_GET_USER_INFO_URL, params=data)
api_response_dic = handler_work_weixin_api_response(api_response)
if not api_response_dic:
logger.error('can not get work weixin user info')
return render_error(request, _('Error, please contact administrator.'))
if not api_response_dic.get('UserId', None):
logger.error('can not get UserId in work weixin user info response')
return render_error(request, _('Error, please contact administrator.'))
user_id = api_response_dic.get('UserId')
uid = WORK_WEIXIN_UID_PREFIX + user_id
work_weixin_user = SocialAuthUser.objects.get_by_provider_and_uid(WORK_WEIXIN_PROVIDER, uid)
if work_weixin_user:
email = work_weixin_user.username
is_new_user = False
else:
email = gen_user_virtual_id()
is_new_user = True
try:
user = auth.authenticate(remote_user=email)
except User.DoesNotExist:
user = None
if not user:
return render_error(
request, _('Error, new user registration is not allowed, please contact administrator.'))
if is_new_user:
SocialAuthUser.objects.add(email, WORK_WEIXIN_PROVIDER, uid)
# update user info
if is_new_user or WORK_WEIXIN_USER_INFO_AUTO_UPDATE:
user_info_data = {
'access_token': access_token,
'userid': user_id,
}
user_info_api_response = requests.get(WORK_WEIXIN_GET_USER_PROFILE_URL, params=user_info_data)
user_info_api_response_dic = handler_work_weixin_api_response(user_info_api_response)
if user_info_api_response_dic:
api_user = user_info_api_response_dic
api_user['username'] = email
api_user['contact_email'] = api_user['email']
update_work_weixin_user_info(api_user)
if not user.is_active:
return render_error(
request, _('Your account is created successfully, please wait for administrator to activate your account.'))
# User is valid. Set request.user and persist user in the session
# by logging the user in.
request.user = user
auth.login(request, user)
# generate auth token for Seafile client
api_token = get_api_token(request)
# redirect user to page
response = HttpResponseRedirect(request.session.get('work_weixin_oauth_redirect', '/'))
response.set_cookie('seahub_auth', user.username + '@' + api_token.key)
return response
@login_required
def work_weixin_oauth_connect(request):
if not work_weixin_oauth_check():
return render_error(request, _('Feature is not enabled.'))
state = str(uuid.uuid4())
request.session['work_weixin_oauth_connect_state'] = state
request.session['work_weixin_oauth_connect_redirect'] = request.GET.get(auth.REDIRECT_FIELD_NAME, '/')
data = {
'appid': WORK_WEIXIN_CORP_ID,
'agentid': WORK_WEIXIN_AGENT_ID,
'redirect_uri': get_site_scheme_and_netloc() + reverse('work_weixin_oauth_connect_callback'),
'state': state,
}
authorization_url = WORK_WEIXIN_AUTHORIZATION_URL + '?' + urllib.parse.urlencode(data)
return HttpResponseRedirect(authorization_url)
@login_required
def work_weixin_oauth_connect_callback(request):
if not work_weixin_oauth_check():
return render_error(request, _('Feature is not enabled.'))
code = request.GET.get('code', None)
state = request.GET.get('state', None)
if state != request.session.get('work_weixin_oauth_connect_state', None) or not code:
logger.error('can not get right code or state from work weixin request')
return render_error(request, _('Error, please contact administrator.'))
access_token = get_work_weixin_access_token()
if not access_token:
logger.error('can not get work weixin access_token')
return render_error(request, _('Error, please contact administrator.'))
data = {
'access_token': access_token,
'code': code,
}
api_response = requests.get(WORK_WEIXIN_GET_USER_INFO_URL, params=data)
api_response_dic = handler_work_weixin_api_response(api_response)
if not api_response_dic:
logger.error('can not get work weixin user info')
return render_error(request, _('Error, please contact administrator.'))
if not api_response_dic.get('UserId', None):
logger.error('can not get UserId in work weixin user info response')
return render_error(request, _('Error, please contact administrator.'))
user_id = api_response_dic.get('UserId')
uid = WORK_WEIXIN_UID_PREFIX + user_id
email = request.user.username
work_weixin_user = SocialAuthUser.objects.get_by_provider_and_uid(WORK_WEIXIN_PROVIDER, uid)
if work_weixin_user:
logger.error('work weixin account already exists %s' % user_id)
return render_error(request, '出错了,此企业微信账号已被绑定')
SocialAuthUser.objects.add(email, WORK_WEIXIN_PROVIDER, uid)
# update user info
if WORK_WEIXIN_USER_INFO_AUTO_UPDATE:
user_info_data = {
'access_token': access_token,
'userid': user_id,
}
user_info_api_response = requests.get(WORK_WEIXIN_GET_USER_PROFILE_URL, params=user_info_data)
user_info_api_response_dic = handler_work_weixin_api_response(user_info_api_response)
if user_info_api_response_dic:
api_user = user_info_api_response_dic
api_user['username'] = email
api_user['contact_email'] = api_user['email']
update_work_weixin_user_info(api_user)
# redirect user to page
response = HttpResponseRedirect(request.session.get('work_weixin_oauth_connect_redirect', '/'))
return response
@login_required
def work_weixin_oauth_disconnect(request):
if not work_weixin_oauth_check():
return render_error(request, _('Feature is not enabled.'))
username = request.user.username
if username[-(len(VIRTUAL_ID_EMAIL_DOMAIN)):] == VIRTUAL_ID_EMAIL_DOMAIN:
return render_error(request, '出错了,此账号不能解绑企业微信')
SocialAuthUser.objects.delete_by_username_and_provider(username, WORK_WEIXIN_PROVIDER)
# redirect user to page
response = HttpResponseRedirect(request.GET.get(auth.REDIRECT_FIELD_NAME, '/'))
return response