def make_profile(self, user, shib_meta): """ Extrat nickname(givenname surname), contact_email, institution from Shib attributs, and add those to user profile. """ # use `display_name` as nickname in shib_meta first nickname = shib_meta.get('display_name', None) if nickname is None: # otherwise, fallback to givenname plus surname in shib_meta givenname = shib_meta.get('givenname', '') surname = shib_meta.get('surname', '') nickname = "%s %s" % (givenname, surname) institution = shib_meta.get('institution', None) contact_email = shib_meta.get('contact_email', None) p = Profile.objects.get_profile_by_user(user.username) if not p: p = Profile(user=user.username) if nickname.strip(): # set nickname when it's not empty p.nickname = nickname if institution: p.institution = institution if contact_email: p.contact_email = contact_email p.save()
def update_user_profile(self, user_info): email = user_info.get('email', '') if not email: return name = user_info.get('name', '') institution = user_info.get('institution', '') contact_email = user_info.get('contact_email', '') profile = Profile.objects.get_profile_by_user(email) if not profile: profile = Profile(user=email) if name.strip(): # if have 'HTTP_DISPLAYNAME' header, # then use its value as user's name profile.nickname = name else: # or use values of "HTTP_GIVENNAME" and "HTTP_SN" headers # for shibboleth givenname = user_info.get('givenname', '') surname = user_info.get('surname', '') if givenname.strip() and surname.strip(): name = "%s %s" % (givenname, surname) profile.nickname = name if institution: profile.institution = institution if contact_email: profile.contact_email = contact_email profile.save()
def make_profile(self, user, shib_meta): """ Extrat nickname(givenname surname), contact_email, institution from Shib attributs, and add those to user profile. """ givenname = shib_meta.get("givenname", "") surname = shib_meta.get("surname", "") nickname = "%s %s" % (givenname, surname) institution = shib_meta.get("institution", None) contact_email = shib_meta.get("contact_email", None) p = Profile.objects.get_profile_by_user(user.username) if not p: p = Profile(user=user.username) p.nickname = nickname if institution: p.institution = institution if contact_email: p.contact_email = contact_email p.save()
def oauth_callback(request): """ Step 3: Retrieving an access token. The user has been redirected back from the provider to your registered callback URL. With this redirection comes an authorization code included in the redirect URL. We will use that to obtain an access token. """ session = OAuth2Session(client_id=CLIENT_ID, scope=SCOPE, state=request.session.get('oauth_state', None), redirect_uri=REDIRECT_URL) try: token = session.fetch_token( TOKEN_URL, client_secret=CLIENT_SECRET, authorization_response=request.get_full_path()) if session._client.__dict__['token'].has_key('user_id'): # used for sjtu.edu.cn # https://xjq12311.gitbooks.io/sjtu-engtc/content/ user_id = session._client.__dict__['token']['user_id'] user_info_resp = session.get(USER_INFO_URL + '?user_id=%s' % user_id) else: user_info_url = USER_INFO_URL if ACCESS_TOKEN_IN_URI: code = request.GET.get('code') user_info_url = USER_INFO_URL + '?access_token=%s&code=%s' % ( token['access_token'], code) user_info_resp = session.get(user_info_url) except Exception as e: logger.error(e) return render_error(request, _('Error, please contact administrator.')) def format_user_info(user_info_resp): logger.info('user info resp: %s' % user_info_resp.text) error = False user_info = {} user_info_json = user_info_resp.json() for item, attr in ATTRIBUTE_MAP.items(): required, user_attr = attr value = user_info_json.get(item, '') if value: # ccnet email if user_attr == 'email': user_info[user_attr] = value if is_valid_email(str(value)) else \ '%s@%s' % (str(value), PROVIDER_DOMAIN) else: user_info[user_attr] = value elif required: error = True return user_info, error user_info, error = format_user_info(user_info_resp) if error: logger.error('Required user info not found.') logger.error(user_info) return render_error(request, _('Error, please contact administrator.')) # seahub authenticate user email = user_info['email'] try: user = auth.authenticate(remote_user=email) except User.DoesNotExist: user = None if not user or not user.is_active: logger.error('User %s not found or inactive.' % email) # a page for authenticate user failed return render_error(request, _(u'User %s not found.') % email) # User is valid. Set request.user and persist user in the session # by logging the user in. request.user = user auth.login(request, user) # update user's profile name = user_info['name'] if user_info.has_key('name') else '' contact_email = user_info['contact_email'] if \ user_info.has_key('contact_email') else '' profile = Profile.objects.get_profile_by_user(email) if not profile: profile = Profile(user=email) if name: profile.nickname = name.strip() profile.save() if contact_email: profile.contact_email = contact_email.strip() profile.save() # generate auth token for Seafile client api_token = get_api_token(request) # redirect user to home page response = HttpResponseRedirect(request.session['oauth_redirect']) response.set_cookie('seahub_auth', email + '@' + api_token.key) return response
def oauth_callback(request): """ Step 3: Retrieving an access token. The user has been redirected back from the provider to your registered callback URL. With this redirection comes an authorization code included in the redirect URL. We will use that to obtain an access token. """ try: session.fetch_token(TOKEN_URL, client_secret=CLIENT_SECRET, authorization_response=request.get_full_path()) user_info_resp = session.get(USER_INFO_URL) except Exception as e: logger.error(e) return render_to_response( 'error.html', { 'error_msg': _('Error, please contact administrator.'), }, context_instance=RequestContext(request)) def format_user_info(user_info_resp): error = False user_info = {} user_info_json = user_info_resp.json() for item, attr in ATTRIBUTE_MAP.items(): required, user_attr = attr value = user_info_json.get(item, '') if value: # ccnet email if user_attr == 'email': user_info[user_attr] = value if is_valid_email(str(value)) else \ '%s@%s' % (str(value), PROVIDER_DOMAIN) else: user_info[user_attr] = value elif required: error = True return user_info, error user_info, error = format_user_info(user_info_resp) if error: logger.error('Required user info not found.') logger.error(user_info) return render_to_response( 'error.html', { 'error_msg': _('Error, please contact administrator.'), }, context_instance=RequestContext(request)) # seahub authenticate user email = user_info['email'] try: User.objects.get(email=email) except User.DoesNotExist: if not config.ENABLE_SIGNUP: logger.error('%s not found but user registration is disabled.' % email) return render_to_response( 'error.html', { 'error_msg': _('Error, please contact administrator.'), }, context_instance=RequestContext(request)) try: user = auth.authenticate(remote_user=email) except User.DoesNotExist: user = None if not user or not user.is_active: logger.error('User %s not found or inactive.' % email) # a page for authenticate user failed return render_to_response( 'error.html', {'error_msg': _(u'User %s not found.') % email}, context_instance=RequestContext(request)) # User is valid. Set request.user and persist user in the session # by logging the user in. request.user = user auth.login(request, user) user.set_unusable_password() user.save() # update user's profile name = user_info['name'] if user_info.has_key('name') else '' contact_email = user_info['contact_email'] if \ user_info.has_key('contact_email') else '' profile = Profile.objects.get_profile_by_user(email) if not profile: profile = Profile(user=email) if name: profile.nickname = name.strip() profile.save() if contact_email: profile.contact_email = contact_email.strip() profile.save() # redirect user to home page return HttpResponseRedirect(reverse('libraries'))
def oauth_callback(request): """ Step 3: Retrieving an access token. The user has been redirected back from the provider to your registered callback URL. With this redirection comes an authorization code included in the redirect URL. We will use that to obtain an access token. """ session = OAuth2Session(client_id=CLIENT_ID, scope=SCOPE, state=request.session.get('oauth_state', None), redirect_uri=REDIRECT_URL) try: session.fetch_token(TOKEN_URL, client_secret=CLIENT_SECRET, authorization_response=request.get_full_path()) if session._client.__dict__['token'].has_key('user_id'): # used for sjtu.edu.cn # https://xjq12311.gitbooks.io/sjtu-engtc/content/ user_id = session._client.__dict__['token']['user_id'] user_info_resp = session.get(USER_INFO_URL + '?user_id=%s' % user_id) else: user_info_resp = session.get(USER_INFO_URL) except Exception as e: logger.error(e) return render(request, 'error.html', { 'error_msg': _('Error, please contact administrator.'), }) def format_user_info(user_info_resp): error = False user_info = {} user_info_json = user_info_resp.json() for item, attr in ATTRIBUTE_MAP.items(): required, user_attr = attr value = user_info_json.get(item, '') if value: # ccnet email if user_attr == 'email': user_info[user_attr] = value if is_valid_email(str(value)) else \ '%s@%s' % (str(value), PROVIDER_DOMAIN) else: user_info[user_attr] = value elif required: error = True return user_info, error user_info, error = format_user_info(user_info_resp) if error: logger.error('Required user info not found.') logger.error(user_info) return render(request, 'error.html', { 'error_msg': _('Error, please contact administrator.'), }) # seahub authenticate user email = user_info['email'] try: User.objects.get(email=email) except User.DoesNotExist: if not config.ENABLE_SIGNUP: logger.error('%s not found but user registration is disabled.' % email) return render( request, 'error.html', { 'error_msg': _('Error, please contact administrator.'), }) try: user = auth.authenticate(remote_user=email) except User.DoesNotExist: user = None if not user or not user.is_active: logger.error('User %s not found or inactive.' % email) # a page for authenticate user failed return render(request, 'error.html', {'error_msg': _(u'User %s not found.') % email}) # User is valid. Set request.user and persist user in the session # by logging the user in. request.user = user auth.login(request, user) user.set_unusable_password() user.save() # update user's profile name = user_info['name'] if user_info.has_key('name') else '' contact_email = user_info['contact_email'] if \ user_info.has_key('contact_email') else '' profile = Profile.objects.get_profile_by_user(email) if not profile: profile = Profile(user=email) if name: profile.nickname = name.strip() profile.save() if contact_email: profile.contact_email = contact_email.strip() profile.save() # generate auth token for Seafile client keys = ( 'platform', 'device_id', 'device_name', 'client_version', 'platform_version', ) if all([key in request.GET for key in keys]): platform = request.GET['platform'] device_id = request.GET['device_id'] device_name = request.GET['device_name'] client_version = request.GET['client_version'] platform_version = request.GET['platform_version'] token = get_token_v2(request, request.user.username, platform, device_id, device_name, client_version, platform_version) else: token = get_token_v1(request.user.username) # redirect user to home page response = HttpResponseRedirect(reverse('libraries')) response.set_cookie('seahub_auth', email + '@' + token.key) return response
def put(self, request, org_id, email): """ update base info of a org user Permission checking: 1. only admin can perform this action. """ try: user = User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) # update active active = request.data.get('active', None) if active: active = active.lower() if active not in ('true', 'false'): error_msg = "active invalid, should be 'true' or 'false'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if active == 'true': user.is_active = True else: user.is_active = False try: # update user status result_code = user.save() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if result_code == -1: error_msg = 'Fail to update user %s.' % email return api_error(status.HTTP_403_FORBIDDEN, error_msg) # update name name = request.data.get('name', None) if name: profile = Profile.objects.get_profile_by_user(email) if profile is None: profile = Profile(user=email) profile.nickname = name profile.save() # update contact_email contact_email = request.data.get('contact_email', None) if contact_email: profile = Profile.objects.get_profile_by_user(email) if profile is None: profile = Profile(user=email) profile.contact_email = contact_email profile.save() # update user quota user_quota_mb = request.data.get("quota_total", None) if user_quota_mb: try: user_quota_mb = int(user_quota_mb) except Exception as e: logger.error(e) error_msg = "quota_total invalid." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) user_quota = int(user_quota_mb) * get_file_size_unit('MB') org_quota = seafile_api.get_org_quota(org_id) # -1 means org has unlimited quota if org_quota > 0: org_quota_mb = org_quota / get_file_size_unit('MB') if user_quota_mb > org_quota_mb: error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb return api_error(status.HTTP_400_BAD_REQUEST, error_msg) seafile_api.set_org_user_quota(org_id, email, user_quota) user_info = get_org_user_info(org_id, email) user_info['active'] = user.is_active return Response(user_info)
def dingtalk_callback(request): if not ENABLE_DINGTALK: return render_error(request, _('Error, please contact administrator.')) state = request.GET.get('state', '') if not state or state != request.session.get('dingtalk_login_state', ''): logger.error('invalid state') return render_error(request, _('Error, please contact administrator.')) timestamp = str(int(time.time() * 1000)).encode('utf-8') appsecret = DINGTALK_QR_CONNECT_APP_SECRET.encode('utf-8') signature = base64.b64encode( hmac.new(appsecret, timestamp, digestmod=sha256).digest()) parameters = { 'accessKey': DINGTALK_QR_CONNECT_APP_ID, 'timestamp': timestamp, 'signature': signature, } code = request.GET.get('code') data = {"tmp_auth_code": code} full_user_info_url = DINGTALK_QR_CONNECT_USER_INFO_URL + '?' + urllib.parse.urlencode( parameters) user_info_resp = requests.post(full_user_info_url, data=json.dumps(data)) user_info = user_info_resp.json()['user_info'] # seahub authenticate user if 'unionid' not in user_info: logger.error('Required user info not found.') logger.error(user_info) return render_error(request, _('Error, please contact administrator.')) auth_user = SocialAuthUser.objects.get_by_provider_and_uid( 'dingtalk', user_info['unionid']) if auth_user: email = auth_user.username else: email = gen_user_virtual_id() SocialAuthUser.objects.add(email, 'dingtalk', user_info['unionid']) try: user = auth.authenticate(remote_user=email) except User.DoesNotExist: user = None except Exception as e: logger.error(e) return render_error(request, _('Error, please contact administrator.')) if not user or not user.is_active: return render_error(request, _('User %s not found or inactive.') % email) # User is valid. Set request.user and persist user in the session # by logging the user in. request.user = user request.session['remember_me'] = DINGTALK_QR_CONNECT_LOGIN_REMEMBER_ME auth.login(request, user) # update user's profile name = user_info['nick'] if 'nick' in user_info else '' if name: profile = Profile.objects.get_profile_by_user(email) if not profile: profile = Profile(user=email) profile.nickname = name.strip() profile.save() user_detail_info = dingtalk_get_detailed_user_info(user_info['unionid']) contact_email = user_detail_info.get('email', '') if contact_email: profile.contact_email = contact_email profile.save() # generate auth token for Seafile client api_token = get_api_token(request) # redirect user to home page response = HttpResponseRedirect( request.session.get('dingtalk_login_redirect', '/')) response.set_cookie('seahub_auth', email + '@' + api_token.key) return response
def dingtalk_connect_callback(request): if not ENABLE_DINGTALK: return render_error(request, _('Error, please contact administrator.')) state = request.GET.get('state', '') if not state or state != request.session.get('dingtalk_connect_state', ''): logger.error('invalid state') return render_error(request, _('Error, please contact administrator.')) timestamp = str(int(time.time() * 1000)).encode('utf-8') appsecret = DINGTALK_QR_CONNECT_APP_SECRET.encode('utf-8') signature = base64.b64encode( hmac.new(appsecret, timestamp, digestmod=sha256).digest()) parameters = { 'accessKey': DINGTALK_QR_CONNECT_APP_ID, 'timestamp': timestamp, 'signature': signature, } code = request.GET.get('code') data = {"tmp_auth_code": code} full_user_info_url = DINGTALK_QR_CONNECT_USER_INFO_URL + '?' + urllib.parse.urlencode( parameters) user_info_resp = requests.post(full_user_info_url, data=json.dumps(data)) user_info = user_info_resp.json()['user_info'] # seahub authenticate user if 'unionid' not in user_info: logger.error('Required user info not found.') logger.error(user_info) return render_error(request, _('Error, please contact administrator.')) username = request.user.username dingtalk_union_id = user_info['unionid'] auth_user = SocialAuthUser.objects.get_by_provider_and_uid( 'dingtalk', dingtalk_union_id) if auth_user: logger.error('dingtalk account already exists %s' % dingtalk_union_id) return render_error(request, '出错了,此钉钉账号已被绑定') SocialAuthUser.objects.add(username, 'dingtalk', dingtalk_union_id) # update user's profile name = user_info['nick'] if 'nick' in user_info else '' if name: profile = Profile.objects.get_profile_by_user(username) if not profile: profile = Profile(user=username) profile.nickname = name.strip() profile.save() user_detail_info = dingtalk_get_detailed_user_info(user_info['unionid']) contact_email = user_detail_info.get('email', '') if contact_email: profile.contact_email = contact_email profile.save() response = HttpResponseRedirect( request.session['dingtalk_connect_redirect']) return response
def put(self, request, org_id, email): """ update base info of a org user Permission checking: 1. only admin can perform this action. """ if not request.user.admin_permissions.other_permission(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') try: user = User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) # update active active = request.data.get('active', None) if active: active = active.lower() if active not in ('true', 'false'): error_msg = "active invalid, should be 'true' or 'false'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if active == 'true': user.is_active = True else: user.is_active = False try: # update user status result_code = user.save() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if result_code == -1: error_msg = 'Fail to update user %s.' % email return api_error(status.HTTP_403_FORBIDDEN, error_msg) # update name name = request.data.get('name', None) if name: profile = Profile.objects.get_profile_by_user(email) if profile is None: profile = Profile(user=email) profile.nickname = name profile.save() # update contact_email contact_email = request.data.get('contact_email', None) if contact_email: profile = Profile.objects.get_profile_by_user(email) if profile is None: profile = Profile(user=email) profile.contact_email = contact_email profile.save() # update user quota user_quota_mb = request.data.get("quota_total", None) if user_quota_mb: try: user_quota_mb = int(user_quota_mb) except Exception as e: logger.error(e) error_msg = "quota_total invalid." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) user_quota = int(user_quota_mb) * get_file_size_unit('MB') org_quota = seafile_api.get_org_quota(org_id) # -1 means org has unlimited quota if org_quota > 0: org_quota_mb = org_quota / get_file_size_unit('MB') if user_quota_mb > org_quota_mb: error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb return api_error(status.HTTP_400_BAD_REQUEST, error_msg) seafile_api.set_org_user_quota(org_id, email, user_quota) user_info = get_org_user_info(org_id, user) user_info['active'] = user.is_active return Response(user_info)