diff --git a/.gitignore b/.gitignore index 8a8b253..de8d400 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ backend/pyvenv.cfg backend/Include/ backend/Scripts/ +log/api.log diff --git a/backend/app/api/api_v1/routers/kintone.py b/backend/app/api/api_v1/routers/kintone.py index 5f91e21..b56f2c5 100644 --- a/backend/app/api/api_v1/routers/kintone.py +++ b/backend/app/api/api_v1/routers/kintone.py @@ -3,6 +3,7 @@ from io import BytesIO import typing as t import pandas as pd import json +import base64 import httpx import deepdiff import app.core.config as config @@ -493,6 +494,17 @@ async def test(file:UploadFile= File(...),app:str=None): return test +@r.get("/group") +async def group(request:Request,kintoneurl:str,kintoneuser:str,kintonepwd:str): + try: + auth_value = base64.b64encode(bytes(f"{kintoneuser}:{kintonepwd}","utf-8")) + headers={config.API_V1_AUTH_KEY:auth_value} + url = f"{kintoneurl}/v1/user/groups.json?code={kintoneuser}" + r = httpx.get(url,headers=headers) + return r.json() + except Exception as e: + raise APIException('kintone:group',request.url._url, f"Error occurred while get group(url:{kintoneurl} user:{kintoneuser}):",e) + @r.post("/download",) async def download(request:Request,key,c:config.KINTONE_ENV=Depends(getkintoneenv)): try: @@ -502,7 +514,7 @@ async def download(request:Request,key,c:config.KINTONE_ENV=Depends(getkintoneen r = httpx.get(url,headers=headers,params=params) return r.json() except Exception as e: - raise APIException('kintone:upload',request.url._url,f"Error occurred while download file.json:",e) + raise APIException('kintone:download',request.url._url,f"Error occurred while download file.json:",e) @r.post("/upload") async def upload(request:Request,files:t.List[UploadFile] = File(...)): @@ -625,7 +637,17 @@ async def createapp(request:Request,name:str,env:config.KINTONE_ENV=Depends(getk except Exception as e: raise APIException('kintone:createapp',request.url._url, f"Error occurred while create app({env.DOMAIN_NAME}->{name}):",e) - +@r.get("/defaultgroup") +async def currentgroup(request:Request,env:config.KINTONE_ENV=Depends(getkintoneenv)): + try: + auth_value = env.API_V1_AUTH_VALUE + headers={config.API_V1_AUTH_KEY:auth_value} + url = f"{env.BASE_URL}/v1/user/groups.json?code={env.KINTONE_USER}" + r = httpx.get(url,headers=headers) + return r.json() + except Exception as e: + raise APIException('kintone:currentgroup',request.url._url, f"Error occurred while get default domain group(domain:{env.DOMAIN_NAME} url:{env.BASE_URL} user:{env.KINTONE_USER}):",e) + @r.post("/createappfromexcel",) async def createappfromexcel(request:Request,files:t.List[UploadFile] = File(...),format:int = 0,env = Depends(getkintoneenv),db = Depends(get_db)): try: diff --git a/backend/app/core/operation.py b/backend/app/core/operation.py index 36eab3a..9bdfe87 100644 --- a/backend/app/core/operation.py +++ b/backend/app/core/operation.py @@ -13,10 +13,14 @@ import json class LoggingMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): if request.method in ("POST", "PUT", "PATCH","DELETE"): - try: - request.state.body = await request.json() - except json.JSONDecodeError: - request.state.body = await request.body() + content_type = request.headers.get('content-type', '') + if content_type.startswith('multipart/form-data'): + request.state.body = None + else: + try: + request.state.body = await request.json() + except json.JSONDecodeError: + request.state.body = await request.body() else: request.state.body = None diff --git a/backend/app/db/cruddb/dbapp.py b/backend/app/db/cruddb/dbapp.py index d741886..3712096 100644 --- a/backend/app/db/cruddb/dbapp.py +++ b/backend/app/db/cruddb/dbapp.py @@ -1,6 +1,7 @@ from datetime import datetime from fastapi import HTTPException, status from sqlalchemy.orm import Session +from sqlalchemy.orm.attributes import flag_modified from sqlalchemy import select,and_ import typing as t @@ -202,6 +203,8 @@ class dbapp(crudbase): db_app = self.get_app(db, domainurl, flow.appid) if db_app and db_app.version > 0: db_app.is_saved = True + flag_modified(db_app, 'is_saved') + db_app.updateuserid = userid db.add(db_app) db.commit() db.refresh(db_flow) diff --git a/backend/app/db/models.py b/backend/app/db/models.py index 39a3323..caa54b3 100644 --- a/backend/app/db/models.py +++ b/backend/app/db/models.py @@ -8,7 +8,7 @@ from app.core.security import chacha20Decrypt class Base: id = Column(Integer, primary_key=True, index=True) create_time = Column(DateTime, default=datetime.now(timezone.utc)) - update_time = Column(DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc)) + update_time = Column(DateTime, default=datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) userrole = Table( @@ -234,7 +234,7 @@ class OperationLog(Base): userid = mapped_column(Integer,ForeignKey("user.id")) operation = mapped_column(String(200)) function = mapped_column(String(200)) - parameters = mapped_column(String(200)) + parameters = mapped_column(String) response = mapped_column(String(200)) user = relationship('User') diff --git a/document/ナレッジ構成.drawio b/document/ナレッジ構成.drawio deleted file mode 100644 index 29b0e0b..0000000 --- a/document/ナレッジ構成.drawio +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/components/ActionSelect.vue b/frontend/src/components/ActionSelect.vue index f9ea992..bab51f7 100644 --- a/frontend/src/components/ActionSelect.vue +++ b/frontend/src/components/ActionSelect.vue @@ -18,6 +18,7 @@ indicator-color="primary" active-bg-color="primary" class="bg-grey-2 text-grey-8" + @update:model-value="() => selected = []" dense > { }); return; } + + deployLoading.value = true; + try { + const { data }: {data: {code: string, groups: {code: string}[]}} = await api.get('api/v1/defaultgroup'); + if (data.code === 'CB_WA01') { + $q.notify({ + type: 'negative', + caption: 'エラー', + message: 'ユーザーのパスワード認証に失敗しました。' + }); + deployLoading.value = false; + return; + } else if (!data.groups || !data.groups.some((group: {code: string}) => group.code === 'Administrators')){ + $q.notify({ + type: 'negative', + caption: 'エラー', + message: 'この操作には管理者権限が必要です。' + }); + deployLoading.value = false; + return; + } + } catch (e) { + $q.notify({ + type: 'negative', + caption: 'エラー', + message: 'サーバーに接続できませんでした。' + }); + deployLoading.value = false; + return; + } + try { - deployLoading.value = true; await store.deploy(); deployLoading.value = false; $q.notify({ diff --git a/frontend/src/pages/TenantDomain.vue b/frontend/src/pages/TenantDomain.vue index fb6228f..3e801e4 100644 --- a/frontend/src/pages/TenantDomain.vue +++ b/frontend/src/pages/TenantDomain.vue @@ -53,21 +53,21 @@
Kintone Account
- +
- - + hint="Kintoneのパスワードを入力してください" label="パスワード" :disable="!isCreate" lazy-rules + :rules="[val => val && val.length > 0 || 'Kintoneのパスワードを入力してください']" autocomplete="new-password">