存储参数修改

pull/10/head
youngS 4 years ago
parent d133d0ec7b
commit ac77e8b36a
  1. 77
      fir_admin/src/components/JsonEditor/index.vue
  2. 2
      fir_admin/src/views/authentication/Detail.vue
  3. 2
      fir_admin/src/views/authentication/list.vue
  4. 97
      fir_admin/src/views/storage/Detail.vue
  5. 70
      fir_admin/src/views/storage/list.vue
  6. 61
      fir_client/src/components/user/FirUserStorage.vue
  7. 13
      fir_ser/admin/views/app.py
  8. 22
      fir_ser/admin/views/storage.py
  9. 17
      fir_ser/admin/views/user.py
  10. 15
      fir_ser/api/models.py
  11. 9
      fir_ser/api/utils/baseutils.py
  12. 23
      fir_ser/api/utils/serializer.py
  13. 22
      fir_ser/api/utils/storage/storage.py
  14. 20
      fir_ser/api/utils/utils.py
  15. 12
      fir_ser/api/views/storage.py

@ -0,0 +1,77 @@
<template>
<div class="json-editor">
<textarea ref="textarea" />
</div>
</template>
<script>
import CodeMirror from 'codemirror'
import 'codemirror/addon/lint/lint.css'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/rubyblue.css'
require('script-loader!jsonlint')
import 'codemirror/mode/javascript/javascript'
import 'codemirror/addon/lint/lint'
import 'codemirror/addon/lint/json-lint'
export default {
name: 'JsonEditor',
/* eslint-disable vue/require-prop-types */
props: ['value'],
data() {
return {
jsonEditor: false
}
},
watch: {
value(value) {
const editorValue = this.jsonEditor.getValue()
if (value !== editorValue) {
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2))
}
}
},
mounted() {
this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
lineNumbers: true,
mode: 'application/json',
gutters: ['CodeMirror-lint-markers'],
theme: 'rubyblue',
lint: true
})
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2))
this.jsonEditor.on('change', cm => {
this.$emit('changed', cm.getValue())
this.$emit('input', cm.getValue())
})
},
methods: {
getValue() {
return this.jsonEditor.getValue()
}
}
}
</script>
<style lang="scss" scoped>
.json-editor {
height: 100%;
position: relative;
::v-deep {
.CodeMirror {
height: auto;
min-height: 300px;
}
.CodeMirror-scroll {
min-height: 300px;
}
.cm-s-rubyblue span.cm-string {
color: #F08047;
}
}
}
</style>

@ -100,7 +100,7 @@ const defaultForm = {
}
export default {
name: 'AppReleaseDetail',
name: 'CertificationDetail',
components: { }, filters: {
},
data() {

@ -110,7 +110,7 @@ const sortOptions = [
]
export default {
name: 'AppInfo',
name: 'CertificationInfo',
components: { Pagination },
directives: { waves },
filters: {

@ -10,67 +10,76 @@
</el-col>
</el-row>
</el-form-item>
<el-form-item label="真实姓名">
<el-form-item label="存储名称">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.name" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="身份证号码">
<el-form-item label="存储类型">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.card" />
<el-select v-model="postForm.storage_type" class="filter-item" placeholder="Please select">
<el-option v-for="item in postForm.storage_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="居住地址">
<el-form-item label="存储额外参数">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.addr" />
</el-col>
</el-row>
</el-form-item>
<el-col :span="21">
<el-form-item label="实名认证">
<el-row :gutter="12">
<el-col :span="16">
<el-select v-model="postForm.status" class="filter-item" placeholder="Please select">
<el-option v-for="item in postForm.certification_status_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<div class="editor-container">
<json-editor ref="jsonEditor" v-model="postForm.additionalparameters" />
</div>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="提交时间" prop="timestamp">
</el-col>
<el-col :span="12">
<el-form-item label="创建时间" prop="timestamp" label-width="160px">
<el-row :gutter="20">
<el-col :span="8">
<el-date-picker :value="postForm.created_time" type="datetime" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="审核时间" prop="timestamp">
<el-form-item label="更新时间" prop="timestamp" label-width="160px">
<el-row :gutter="20">
<el-col :span="8">
<el-date-picker :value="postForm.reviewed_time" type="datetime" disabled />
<el-date-picker :value="postForm.updated_time" type="datetime" disabled />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="审核备注">
<el-form-item label="存储访问access_key" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.msg" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" placeholder="Please input" />
<el-input v-model="postForm.access_key" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="存储访问secret_key" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.secret_key" />
</el-col>
<el-col :span="12">
<el-form-item label="实名认证照片">
<div v-for="info in postForm.certification_infos" :key="info.name" style="width: 320px; height: 340px;float: left;border: #409EFF 1px solid;text-align: center;margin-left: 20px;margin-bottom: 20px">
<el-image :src="info.certification_url" :preview-src-list="[info.certification_url]" fit="contain" style="width: 260px; height: 260px" />
<el-link :underline="false"> {{ info.name }}</el-link>
</div>
</el-row>
</el-form-item>
<el-form-item label="存储空间bucket_name" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.bucket_name" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label="存储描述信息" label-width="160px">
<el-row :gutter="12">
<el-col :span="16">
<el-input v-model="postForm.description" :autosize="{ minRows: 4, maxRows: 6}" type="textarea" placeholder="Please input" />
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
</el-form>
@ -85,29 +94,31 @@
</template>
<script>
import { getCertificationInfo, updateCertificationInfo } from '@/api/user'
import { getStorageInfo, updateStorageInfo } from '@/api/storage'
import JsonEditor from '@/components/JsonEditor'
const defaultForm = {
user_id: undefined,
name: undefined,
card: undefined,
addr: undefined,
mobile: undefined,
status: undefined,
msg: undefined,
storage_type: undefined,
access_key: undefined,
secret_key: undefined,
bucket_name: undefined,
domain_name: undefined,
created_time: undefined,
reviewed_time: undefined
description: undefined,
updated_time: undefined
}
export default {
name: 'AppReleaseDetail',
components: { }, filters: {
name: 'StorageDetail',
components: { JsonEditor }, filters: {
},
data() {
return {
postForm: Object.assign({}, defaultForm),
loading: false,
is_edit: false
is_edit: false,
}
},
computed: {
@ -118,18 +129,20 @@ export default {
},
methods: {
fetchData(id) {
getCertificationInfo({ id: id }).then(response => {
getStorageInfo({ id: id }).then(response => {
if (response.data.length === 1) {
this.postForm = response.data[0]
this.postForm.additionalparameters = this.postForm.additionalparameter
}
}).catch(err => {
console.log(err)
})
},
updateData() {
updateCertificationInfo(this.postForm).then(response => {
updateStorageInfo(this.postForm).then(response => {
this.$message.success('更新成功')
this.postForm = response.data
this.postForm.additionalparameters = this.postForm.additionalparameter
}).catch(err => {
console.log(err)
})
@ -138,3 +151,9 @@ export default {
}
</script>
<style scoped>
.editor-container{
position: relative;
height: 100%;
}
</style>

@ -2,11 +2,12 @@
<div class="app-container">
<div class="filter-container">
<el-input v-model="listQuery.user_id" placeholder="用户ID" style="width: 140px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.card" placeholder="身份证" style="width: 300px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.name" placeholder="姓名" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.mobile" placeholder="手机号码" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.status" placeholder="实名认证状态" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in certification_status_choices" :key="item.id" :label="item.name" :value="item.id" />
<el-input v-model="listQuery.bucket_name" placeholder="bucket_name" style="width: 300px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.access_key" placeholder="access_key" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.name" placeholder="存储名称" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-input v-model="listQuery.domain_name" placeholder="下载域名" style="width: 200px;" class="filter-item" clearable @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.storage_type" placeholder="存储类型" clearable class="filter-item" style="width: 140px" @change="handleFilter">
<el-option v-for="item in storage_choices" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter">
<el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key" />
@ -36,32 +37,32 @@
</router-link>
</template>
</el-table-column>
<el-table-column label="真实姓名">
<el-table-column label="存储名称">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column label="身份证号码" align="center">
<el-table-column label="存储访问access_key" align="center">
<template slot-scope="scope">
<span>{{ scope.row.card }}</span>
<span>{{ scope.row.access_key }}</span>
</template>
</el-table-column>
<el-table-column label="居住地" align="center">
<el-table-column label="存储空间bucket_name" align="center">
<template slot-scope="scope">
{{ scope.row.addr }}
{{ scope.row.bucket_name }}
</template>
</el-table-column>
<el-table-column label="手机号码" align="center">
<el-table-column label="下载域名" align="center">
<template slot-scope="scope">
{{ scope.row.mobile }}
{{ scope.row.domain_name }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="实名认证" width="95" align="center">
<el-table-column class-name="status-col" label="存储类型" width="95" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status | certStatusFilter">{{ scope.row| certLableFilter }}</el-tag>
<el-tag :type="scope.row.storage_type | certStatusFilter">{{ scope.row| certLableFilter }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="created_time" label="提交时间" width="120">
<el-table-column align="center" prop="created_time" label="创建时间" width="120">
<template slot-scope="scope">
<i class="el-icon-time" />
<el-tooltip :content="scope.row.created_time">
@ -69,17 +70,17 @@
</el-tooltip>
</template>
</el-table-column>
<el-table-column align="center" prop="created_time" label="审核时间" width="120">
<el-table-column align="center" prop="created_time" label="更新时间" width="120">
<template slot-scope="scope">
<i class="el-icon-time" />
<el-tooltip :content="scope.row.reviewed_time">
<span>{{ scope.row.reviewed_time|formatTime }}</span>
<el-tooltip :content="scope.row.updated_time">
<span>{{ scope.row.updated_time|formatTime }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template slot-scope="scope">
<router-link :to="{name: 'user_authentication_info_edit',params:{id:scope.row.id}}">
<router-link :to="{name: 'storage_info_edit',params:{id:scope.row.id}}">
<el-button type="primary" size="mini">
查看编辑
</el-button>
@ -101,14 +102,14 @@ import Pagination from '@/components/Pagination' // secondary package based on e
import waves from '@/directive/waves' // waves directive
const sortOptions = [
{ label: '审核时间 Ascending', key: 'reviewed_time' },
{ label: '审核时间 Descending', key: '-reviewed_time' },
{ label: '提交时间 Ascending', key: 'created_time' },
{ label: '提交时间 Descending', key: '-created_time' }
{ label: '创建时间 Ascending', key: 'reviewed_time' },
{ label: '创建时间 Descending', key: '-reviewed_time' },
{ label: '更新时间 Ascending', key: 'created_time' },
{ label: '更新时间 Descending', key: '-created_time' }
]
export default {
name: 'AppInfo',
name: 'StorageInfo',
components: { Pagination },
directives: { waves },
filters: {
@ -117,16 +118,16 @@ export default {
},
certStatusFilter(status) {
const statusMap = {
'-1': 'info',
'0': 'danger',
'1': 'success',
'0': 'gray',
'2': 'danger'
'2': 'gray',
'3': 'info'
}
return statusMap[status]
},
certLableFilter(row) {
for (const v of row.certification_status_choices) {
if (v.id === row.status) {
for (const v of row.storage_choices) {
if (v.id === row.storage_type) {
return v.name
}
}
@ -164,13 +165,14 @@ export default {
limit: 10,
name: undefined,
sort: '-created_time',
card: undefined,
mobile: undefined,
status: undefined,
bucket_name: undefined,
access_key: undefined,
storage_type: undefined,
domain_name: undefined,
user_id: undefined
},
sortOptions,
certification_status_choices: []
storage_choices: []
}
},
created() {
@ -186,7 +188,7 @@ export default {
getStorageInfo(this.listQuery).then(response => {
this.list = response.data
if (this.list && this.list.length > 0) {
this.certification_status_choices = this.list[0].certification_status_choices
this.storage_choices = this.list[0].storage_choices
}
this.total = response.total
this.listLoading = false

@ -35,27 +35,28 @@
<div v-if="editstorageinfo.storage_type === 2">
<el-form-item label-width="110px" label="sts_role_arn">
<el-input :disabled='disabled'
v-model="editstorageinfo.additionalparameter.sts_role_arn"></el-input>
v-model="editstorageinfo.sts_role_arn"></el-input>
</el-form-item>
<el-form-item label-width="110px" label="endpoint">
<el-input :disabled='disabled'
v-model="editstorageinfo.additionalparameter.endpoint"></el-input>
v-model="editstorageinfo.endpoint"></el-input>
</el-form-item>
<el-form-item label-width="110px" label="下载授权方式">
<el-select v-model="editstorageinfo.additionalparameter.download_auth_type"
<el-select v-model="editstorageinfo.download_auth_type"
placeholder="下载授权方式"
style="width: 80%" :disabled="disabled">
<el-option v-for="st in download_auth_type_list" :key="st.id" :label="st.name"
<el-option v-for="st in editstorageinfo.download_auth_type_choices" :key="st.id"
:label="st.name"
:value="st.id"></el-option>
</el-select>
<el-form-item label-width="120px" style="margin-top: 10px;margin-left: 70px;width: 60%"
label="CDN鉴权主KEY"
v-if="editstorageinfo.additionalparameter.download_auth_type === 2">
v-if="editstorageinfo.download_auth_type === 2">
<el-input :disabled='disabled' placeholder="CDN鉴权主KEY"
v-model="editstorageinfo.additionalparameter.cnd_auth_key"/>
v-model="editstorageinfo.cnd_auth_key"/>
</el-form-item>
</el-form-item>
@ -137,26 +138,27 @@
<div v-if="storageinfo.storage_type === 2">
<el-form-item label-width="110px" label="sts_role_arn">
<el-input :disabled='Sdisabled'
v-model="storageinfo.additionalparameter.sts_role_arn"></el-input>
v-model="storageinfo.sts_role_arn"></el-input>
</el-form-item>
<el-form-item label-width="110px" label="endpoint">
<el-input :disabled='Sdisabled'
v-model="storageinfo.additionalparameter.endpoint"></el-input>
v-model="storageinfo.endpoint"></el-input>
</el-form-item>
<el-form-item label-width="110px" label="下载授权方式">
<el-select v-model="storageinfo.additionalparameter.download_auth_type"
<el-select v-model="storageinfo.download_auth_type"
placeholder="下载授权方式"
style="width: 100%" :disabled="disabled">
<el-option v-for="st in download_auth_type_list" :key="st.id" :label="st.name"
<el-option v-for="st in storageinfo.download_auth_type_choices" :key="st.id"
:label="st.name"
:value="st.id"></el-option>
</el-select>
<el-form-item label-width="120px" style="margin-top: 10px;width: 100%" label="CDN鉴权主KEY"
v-if="storageinfo.additionalparameter.download_auth_type === 2">
v-if="storageinfo.download_auth_type === 2">
<el-input :disabled='disabled' placeholder="CDN鉴权主KEY"
v-model="storageinfo.additionalparameter.cnd_auth_key"/>
v-model="storageinfo.cnd_auth_key"/>
</el-form-item>
</el-form-item>
@ -265,27 +267,28 @@
<div v-if="editstorageinfo.storage_type === 2">
<el-form-item label-width="110px" label="sts_role_arn">
<el-input
v-model="editstorageinfo.additionalparameter.sts_role_arn"></el-input>
v-model="editstorageinfo.sts_role_arn"></el-input>
</el-form-item>
<el-form-item label-width="110px" label="endpoint">
<el-input
v-model="editstorageinfo.additionalparameter.endpoint"></el-input>
v-model="editstorageinfo.endpoint"></el-input>
</el-form-item>
<el-form-item label-width="110px" label="下载授权方式">
<el-select v-model="editstorageinfo.additionalparameter.download_auth_type"
<el-select v-model="editstorageinfo.download_auth_type"
placeholder="下载授权方式"
style="width: 80%">
<el-option v-for="st in download_auth_type_list" :key="st.id" :label="st.name"
<el-option v-for="st in editstorageinfo.download_auth_type_choices" :key="st.id"
:label="st.name"
:value="st.id"></el-option>
</el-select>
<el-form-item label-width="120px" style="margin-top: 10px;margin-left: 70px;width: 60%"
label="CDN鉴权主KEY"
v-if="editstorageinfo.additionalparameter.download_auth_type === 2">
v-if="editstorageinfo.download_auth_type === 2">
<el-input placeholder="CDN鉴权主KEY"
v-model="editstorageinfo.additionalparameter.cnd_auth_key"/>
v-model="editstorageinfo.cnd_auth_key"/>
</el-form-item>
</el-form-item>
@ -308,7 +311,7 @@
<script>
import {getStorageinfo} from "@/restful";
import {deepCopy} from "@/utils";
import {deepCopy, getUserInfoFun} from "@/utils";
export default {
name: "FirUserStorage",
@ -320,19 +323,15 @@
org_storage_id: 0,
title: '',
dialogstorageVisible: false,
editstorageinfo: {'additionalparameter': {}},
editstorageinfo: {},
selectlabel: "",
storageinfo: {'additionalparameter': {}},
storageinfo: {},
storage_list: [],
disabled: true,
isaddflag: false,
activeName: 'change',
storage_info_lists: [],
is_admin_storage: false,
download_auth_type_list: [{id: 1, name: 'OSS模式: 需要把OSS权限开启私有模式'}, {
id: 2,
name: 'CDN模式: 请先配置好阿里云CDN,开启阿里云OSS私有Bucket回源,将使用鉴权A方式'
},],
loading: false,
}
}, methods: {
@ -348,12 +347,6 @@
this.dialogstorageVisible = true;
this.editstorageinfo = deepCopy(editstorageinfo);
this.isaddflag = false;
}, add_storage_click() {
this.title = '新增存储';
this.disabled = false;
this.dialogstorageVisible = true;
this.editstorageinfo = {'additionalparameter': {download_auth_type: 1}};
this.isaddflag = true;
},
// eslint-disable-next-line no-unused-vars
handleClick(tab, event) {
@ -520,8 +513,9 @@
if (data.code === 1000) {
this.storage_list = data.storage_list;
this.editstorageinfo = {
'additionalparameter': {download_auth_type: 1},
storage_type: this.storage_list[0].id
download_auth_type: 1,
storage_type: this.storage_list[0].id,
download_auth_type_choices: data.download_auth_type_choices
};
this.isaddflag = true;
} else {
@ -531,6 +525,7 @@
}
},
}, mounted() {
getUserInfoFun(this);
if (this.$route.params.act) {
let activeName = this.$route.params.act;
let activeName_list = ["change", "edit", "add"];

@ -20,6 +20,7 @@ from api.utils.storage.caches import login_auth_failed, del_cache_response_by_sh
import logging
from api.utils.throttle import VisitRegister1Throttle, VisitRegister2Throttle
from rest_framework.pagination import PageNumberPagination
from api.utils.baseutils import get_dict_from_filter_fields
from api.base_views import app_delete
logger = logging.getLogger(__name__)
@ -37,12 +38,8 @@ class AppInfoView(APIView):
def get(self, request):
res = BaseResponse()
filter_data = {}
filter_fields = ["id", "type", "name", "short", "bundle_id", "domain_name", "user_id", "status"]
for filed in filter_fields:
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
sort = request.query_params.get("sort", "-updated_time")
page_obj = AppsPageNumber()
obj_list = Apps.objects.filter(**filter_data).order_by(sort)
@ -91,12 +88,8 @@ class AppReleaseInfoView(APIView):
def get(self, request):
res = BaseResponse()
filter_data = {}
filter_fields = ["id", "release_id", "app_id"]
for filed in filter_fields:
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
sort = request.query_params.get("sort", "-created_time")
if not filter_data.get('app_id', None):
res.code = 1003

@ -8,6 +8,7 @@ from django.contrib import auth
from api.models import Token, UserInfo, AppStorage
from rest_framework.response import Response
from api.utils.auth import AdminTokenAuthentication
from api.utils.baseutils import get_dict_from_filter_fields
from api.utils.serializer import AdminStorageSerializer, AdminUserCertificationSerializer
from django.core.cache import cache
from rest_framework.views import APIView
@ -36,12 +37,8 @@ class StorageInfoView(APIView):
def get(self, request):
res = BaseResponse()
filter_data = {}
filter_fileds = ["id", "user_id", "name", "storage_type", "access_key", "bucket_name"]
for filed in filter_fileds:
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
filter_fields = ["id", "user_id", "name", "storage_type", "access_key", "bucket_name"]
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
sort = request.query_params.get("sort", "-created_time")
page_obj = AppsPageNumber()
obj_list = AppStorage.objects.filter(**filter_data).order_by(sort)
@ -60,14 +57,15 @@ class StorageInfoView(APIView):
res.code = 1003
res.msg = "参数错误"
return Response(res.dict)
user_obj = UserInfo.objects.filter(pk=pk).first()
if user_obj:
obj = AppStorage.objects.filter(pk=pk).first()
if obj:
data['pk'] = pk
users_serializer = AdminStorageSerializer(user_obj, data=data, partial=True)
if users_serializer.is_valid():
users_serializer.save()
res.data = users_serializer.data
serializer = AdminStorageSerializer(obj, data=data, partial=True)
if serializer.is_valid():
serializer.save()
res.data = serializer.data
return Response(res.dict)
print(serializer.errors)
res.code = 1004
res.msg = "数据校验失败"
return Response(res.dict)

@ -8,6 +8,7 @@ from django.contrib import auth
from api.models import Token, UserInfo, UserCertificationInfo
from rest_framework.response import Response
from api.utils.auth import AdminTokenAuthentication
from api.utils.baseutils import get_dict_from_filter_fields
from api.utils.serializer import AdminUserInfoSerializer, AdminUserCertificationSerializer
from django.core.cache import cache
from rest_framework.views import APIView
@ -36,12 +37,8 @@ class UserInfoView(APIView):
def get(self, request):
res = BaseResponse()
filter_data = {}
filter_fileds = ["id", "mobile", "username", "email", "first_name"]
for filed in filter_fileds:
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
filter_fields = ["id", "mobile", "username", "email", "first_name"]
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
sort = request.query_params.get("sort", "-date_joined")
certification = request.query_params.get("certification", None)
if certification:
@ -87,12 +84,8 @@ class UserCertificationInfoView(APIView):
def get(self, request):
res = BaseResponse()
filter_data = {}
filter_fileds = ["id", "card", "name", "status"]
for filed in filter_fileds:
f_value = request.query_params.get(filed, None)
if f_value:
filter_data[filed] = f_value
filter_fields = ["id", "card", "name", "status"]
filter_data = get_dict_from_filter_fields(filter_fields, request.query_params)
sort = request.query_params.get("sort", "-created_time")
page_obj = AppsPageNumber()
obj_list = UserCertificationInfo.objects.filter(**filter_data).order_by(sort)

@ -185,8 +185,14 @@ class AppStorage(models.Model):
domain_name = models.CharField(max_length=128, blank=True, null=True, verbose_name="下载域名",
help_text='fly-storage.dvcloud.xin,可以自定义端口')
is_https = models.BooleanField(default=True, verbose_name="是否支持https")
additionalparameters = models.TextField(blank=True, null=True, verbose_name="额外参数",
help_text='阿里云:{"sts_role_arn":"arn信息","endpoint":""} ', default=None)
sts_role_arn = models.CharField(max_length=128, blank=True, null=True, verbose_name="阿里云sts_role_arn")
endpoint = models.CharField(max_length=128, blank=True, null=True, verbose_name="阿里云endpoint")
download_auth_type_choices = ((1, 'OSS模式: 需要把OSS权限开启私有模式'), (2, 'CDN模式: 请先配置好阿里云CDN,开启阿里云OSS私有Bucket回源,将使用鉴权A方式'))
download_auth_type = models.SmallIntegerField(choices=download_auth_type_choices, default=1,
verbose_name="阿里云下载授权方式")
cnd_auth_key = models.CharField(max_length=128, blank=True, null=True, verbose_name="阿里云cnd_auth_key")
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
description = models.TextField('备注', blank=True, null=True, default='')
@ -198,6 +204,11 @@ class AppStorage(models.Model):
def save(self, *args, **kwargs):
if self.storage_type in (1, 2):
if self.bucket_name and self.secret_key and self.access_key:
if self.storage_type == 2:
if not self.sts_role_arn or not self.endpoint:
return
if self.download_auth_type == 2 and not self.cnd_auth_key:
return
return super(AppStorage, self).save(*args, **kwargs)
else:
return

@ -79,3 +79,12 @@ def is_valid_email(email):
return True
except ValidationError:
return False
def get_dict_from_filter_fields(filter_fields, data):
filter_data = {}
for filed in filter_fields:
f_value = data.get(filed, None)
if f_value:
filter_data[filed] = f_value
return filter_data

@ -341,16 +341,11 @@ class StorageSerializer(serializers.ModelSerializer):
exclude = ["user_id"]
storage_type_display = serializers.CharField(source="get_storage_type_display", read_only=True)
additionalparameters = serializers.CharField(write_only=True)
additionalparameter = serializers.SerializerMethodField(read_only=True)
def get_additionalparameter(self, obj):
infos = {}
try:
infos = json.loads(obj.additionalparameters)
except Exception as e:
logger.error("%s additionalparameter loads failed Exception:%s" % (obj.additionalparameters, e))
return infos
download_auth_type_choices = serializers.SerializerMethodField()
def get_download_auth_type_choices(self, obj):
return get_choices_dict(obj.download_auth_type_choices)
def create(self, validated_data):
if self.context.get("user_obj", None) and self.context.get("user_obj") != "undefined":
@ -367,6 +362,16 @@ class AdminStorageSerializer(StorageSerializer):
fields = "__all__"
read_only_fields = ["id", "user_id", "updated_time", "created_time"]
additionalparameters = serializers.CharField()
storage_choices = serializers.SerializerMethodField()
def validate_additionalparameters(self, additionalparameters):
print(additionalparameters)
return json.dumps(additionalparameters)
def get_storage_choices(self, obj):
return get_choices_dict(obj.storage_choices)
class DeveloperSerializer(serializers.ModelSerializer):
class Meta:

@ -9,6 +9,7 @@ from .aliyunApi import AliYunOss, AliYunCdn
from .qiniuApi import QiNiuOss
from .localApi import LocalStorage
import json, time, base64
from api.utils.baseutils import get_dict_from_filter_fields
from fir_ser.settings import THIRD_PART_CONFIG, CACHE_KEY_TEMPLATE
from django.core.cache import cache
import logging
@ -80,7 +81,7 @@ class Storage(object):
self.storage_obj = None
if self.storage_obj:
auth = self.get_storage_auth(self.storage_obj)
auth = self.get_storage_auth()
storage_key = "_".join([CACHE_KEY_TEMPLATE.get('user_storage_key'), user.uid,
base64.b64encode(json.dumps(auth).encode("utf-8")).decode("utf-8")[0:64]])
storage_type = self.storage_obj.storage_type
@ -141,21 +142,10 @@ class Storage(object):
if self.storage:
return self.storage.storage_type
def get_storage_auth(self, storage_obj):
auth_dict = {
'access_key': storage_obj.access_key,
'secret_key': storage_obj.secret_key,
'bucket_name': storage_obj.bucket_name,
'domain_name': storage_obj.domain_name,
'is_https': storage_obj.is_https
}
try:
additionalparameters = json.loads(storage_obj.additionalparameters)
except Exception as e:
logger.error("%s get_storage_auth additionalparameters %s loads failed Exception:%s" % (
storage_obj.user_id, storage_obj.additionalparameters, e))
additionalparameters = {}
return {**auth_dict, **additionalparameters}
def get_storage_auth(self):
filter_fields = ['access_key', 'secret_key', 'bucket_name', 'domain_name', 'is_https', 'endpoint',
'sts_role_arn', 'cnd_auth_key', 'download_auth_type']
return get_dict_from_filter_fields(filter_fields, self.storage_obj.__dict__)
def get_local_storage(clean_cache=False):

@ -172,26 +172,6 @@ def delete_app_screenshots_files(storage_obj, app_obj):
screenshot_obj.delete()
def check_storage_additionalparameter(request, res):
data = request.data
try:
extra_parameters = data.get('additionalparameter', '')
if extra_parameters:
if not extra_parameters.get("download_auth_type", None):
extra_parameters['download_auth_type'] = 1
if extra_parameters.get("download_auth_type", None) == 2:
if not extra_parameters.get("cnd_auth_key", None):
logger.error("user %s add new storage failed" % (request.user))
res.msg = "cdn 鉴权KEY 缺失"
res.code = 1006
return False, res
data['additionalparameters'] = json.dumps(extra_parameters)
except Exception as e:
logger.error("user:%s additionalparameters %s dumps failed Exception:%s" % (
request.user, data.get('additionalparameter', ''), e))
return True, data
def change_storage_and_change_head_img(user_obj, new_storage_obj):
migrating_storage_file_data(user_obj, user_obj.head_img, new_storage_obj)

@ -10,8 +10,8 @@ from api.utils.auth import ExpiringTokenAuthentication, StoragePermission
from rest_framework.response import Response
from api.utils.storage.caches import del_cache_storage
from api.models import AppStorage, UserInfo
from api.utils.utils import upload_oss_default_head_img, check_storage_additionalparameter, \
change_storage_and_change_head_img, migrating_storage_data, clean_storage_data
from api.utils.utils import upload_oss_default_head_img, \
change_storage_and_change_head_img, migrating_storage_data, clean_storage_data, get_choices_dict
from api.utils.serializer import StorageSerializer
import logging
@ -32,6 +32,7 @@ class StorageView(APIView):
act = request.query_params.get("act", None)
if act == 'storage_type':
res.download_auth_type_choices = get_choices_dict(AppStorage.download_auth_type_choices)
return Response(res.dict)
# [1,2] 表示七牛存储和阿里云存储
@ -63,9 +64,6 @@ class StorageView(APIView):
res = BaseResponse()
data = request.data
logger.info("user %s add new storage data:%s" % (request.user, data))
status, data = check_storage_additionalparameter(request, res)
if not status:
return Response(data.dict)
serializer = StorageSerializer(data=data, context={'user_obj': request.user})
if serializer.is_valid():
storage_obj = serializer.save()
@ -92,7 +90,6 @@ class StorageView(APIView):
res = BaseResponse()
data = request.data
logger.info("user %s update storage data:%s" % (request.user, data))
use_storage_id = data.get("use_storage_id", None)
force = data.get("force", None)
if use_storage_id:
@ -135,9 +132,6 @@ class StorageView(APIView):
res.msg = '存储正在使用中,无法修改'
res.code = 1007
return Response(res.dict)
status, data = check_storage_additionalparameter(request, res)
if not status:
return Response(data.dict)
storage_obj = AppStorage.objects.filter(id=storage_id, user_id=request.user).first()
storage_obj_bak = AppStorage.objects.filter(id=storage_id, user_id=request.user).first()
serializer = StorageSerializer(instance=storage_obj, data=data, context={'user_obj': request.user},

Loading…
Cancel
Save