2021SC@SDUSC
在seahub-extra-setting中我们了解到extra相比原seahub多了什么内容。对于krb5_auth和cas等和身份认证以及单点登录有关的内容,前两次已经分析。这次主要接上一次源码分析,对seahub-extra剩下的几个文件夹下的代码进行分析。
EXTRA_INSTALLED_APPS = [
"seahub_extra.search",
"seahub_extra.sysadmin_extra",
'seahub_extra.organizations',
'seahub_extra.krb5_auth',
'seahub_extra.django_cas_ng',
]
EXTRA_MIDDLEWARE = [
'seahub_extra.organizations.middleware.RedirectMiddleware',
]
EXTRA_AUTHENTICATION_BACKENDS = (
'seahub_extra.django_cas_ng.backends.CASBackend',
)
首先对setting文件中指明的EXTRA_MIDDLEWARE文件夹里的Middleware内容进行分析。
文档给的描述是:将非“www”子域请求重定向到指定URL或业务的中间件类。例如:http://xyzsite.com到http://www.xyzsite.com,之所以要将非"www"的域转到“www”的域,这是便于SEO优化,因为带www与不带www搜索引擎看来,是两个不同的站,如果不跳转,即搜索引擎会视为两个内容完成相同的网站,权重将会分散甚至降低或降权。所以需要把其中一个301重定向,这样有利于收录和搜索引擎排名。
示意图:
主要进行处理的代码:
process_request()函数为包括非“www”子域的请求返回HTTP重定向响应。
def process_request(self, request):
if getattr(settings, 'MULTI_TENANCY', False) is False:
return None
if ORG_REDIRECT is False:
return None
path = request.get_full_path()
domain = request.META.get('HTTP_HOST') or request.META.get('SERVER_NAME')
if request.user.is_anonymous:
return None
if request.user.org is None: # 个体用户的请求
sub_domain = get_subdomain(domain)
if sub_domain is not None:
return HttpResponseRedirect(get_site_scheme_and_netloc() + path)
else:
return None
else: # 组织机构的请求
url_prefix = request.user.org.url_prefix
sub_domain = get_subdomain(domain)
if sub_domain is None or sub_domain != url_prefix:
return HttpResponseRedirect(construct_org_url(url_prefix,path))
else:
return None
子域是创建测试或登台站点的好方法,以便在不创建其他域的情况下进行某些测试。
下面是获取子域的代码:
def get_subdomain(domain):
service_url_netloc = urlparse(get_service_url()).netloc
domain_remaining = domain.replace(service_url_netloc, '')
if domain_remaining == '':
return None
elif domain_remaining[-1] == '.':
return domain_remaining[:-1]
else:
logger.warn('Invalid domain: %s, service_url: %s' % (domain, service_url_netloc))
return None
最后是构建新的URL然后传给客户端重定向到www域:
def construct_org_url(url_prefix, path):
service_url = get_service_url()
p = urlparse(service_url)
scheme = p.scheme
netloc = p.netloc
return "%s://%s.%s%s" % (scheme, url_prefix, netloc, path)
form.py主要是一个用于组织用户注册的表单。
包括限制字段长度,判断邮箱是否valid,是否有人占用,还有URL prefix can only be letters(a-z), numbers, and the underscore character,即必须是小写字母,数字,下划线。还有两次密码判断是否一致。代码过于简单,这里不用再展示。
search文件夹
对于search文件夹来说,这里面是用Elasticsearch框架,对整个库建立了索引,从而更快速的得到搜索结果。
示意图:
主要方法:
通过username获取拥有的私有仓库列表
def get_owned_repos(username, org_id=None)
通过username获取共享仓库列表
def get_shared_repos(username, org_id=None):
通过username获取群组仓库列表
def get_group_repos(username, org_id=None):
通过username获取公共仓库列表
def get_public_repos(username, org_id=None):
通过上面获取的仓库列表调用es search的方法接口进行搜索,结果以数组形式返回。
def search_files(repos_map, search_path, keyword, obj_desc, start, size, org_id=None):
# search file
if len(repos_map) > 1:
search_path = None
files_found, total = es_search(repos_map, search_path, keyword, obj_desc, start, size)
result = []
for f in files_found:
repo = repos_map.get(f['repo_id'], None)
if not repo:
continue
if repo.origin_path:
if not f['fullpath'].startswith(repo.origin_path):
# this operation will reduce the result items, but it will not happen now
continue
else:
f['repo_id'] = repo.repo_id
f['fullpath'] = f['fullpath'].split(repo.origin_path)[-1]
if not repo.owner:
if org_id:
repo.owner = seafile_api.get_org_repo_owner(repo.id)
else:
repo.owner = seafile_api.get_repo_owner(repo.id)
# if match multiple files, keep the lookup only once.
if not hasattr(repo, 'owner_nickname') or not repo.owner_nickname:
repo.owner_nickname = email2nickname(repo.owner)
if not hasattr(repo, 'owner_contact_email') or not repo.owner_contact_email:
repo.owner_contact_email = email2contact_email(repo.owner)
if f['fullpath'] == '/':
f['last_modified_by'] = repo.last_modifier
f['last_modified'] = repo.last_modify
f['size'] = repo.size
else:
try:
dirent = seafile_api.get_dirent_by_path(f['repo_id'], f['fullpath'])
except Exception as e:
logger.error(e)
continue
if not dirent:
continue
f['last_modified_by'] = dirent.modifier
f['last_modified'] = dirent.mtime
f['size'] = dirent.size
f['repo'] = repo
f['repo_name'] = repo.name
f['repo_owner_email'] = repo.owner
f['repo_owner_name'] = repo.owner_nickname
f['repo_owner_contact_email'] = repo.owner_contact_email
result.append(f)
return result, total