diff --git a/api/actions/app.go b/api/actions/app.go
index 03eeb518..648ef805 100644
--- a/api/actions/app.go
+++ b/api/actions/app.go
@@ -44,13 +44,17 @@ func App() *buffalo.App {
apiPath := "/api"
auth := app.Group(apiPath + "/auth")
- auth.Middleware.Skip(SetContextMiddleware, AuthLogin)
+
+ auth.Middleware.Skip(SetContextMiddleware, AuthLogin, AuthLoginRefresh)
auth.POST("/login", AuthLogin)
- auth.POST("/refresh", AuthLoginRefresh)
auth.POST("/validate", AuthValidate)
auth.POST("/logout", AuthLogout)
auth.POST("/userinfo", AuthUserinfo)
+ refresh := auth.Group("/refresh")
+ refresh.Use(SetRefreshCtxMiddleware)
+ refresh.POST("", AuthLoginRefresh)
+
api := app.Group(apiPath)
api.POST("/disklookup", DiskLookup)
api.POST("/availabledisktypebyproviderregion", AvailableDiskTypeByProviderRegion)
diff --git a/api/actions/auth.go b/api/actions/auth.go
index d2864271..feecf2d8 100644
--- a/api/actions/auth.go
+++ b/api/actions/auth.go
@@ -8,6 +8,7 @@ import (
"log"
"github.com/gobuffalo/buffalo"
+ "github.com/gobuffalo/buffalo/render"
"github.com/gobuffalo/pop/v6"
)
@@ -54,16 +55,21 @@ func AuthLoginRefresh(c buffalo.Context) error {
return c.Render(commonResponse.Status.StatusCode, r.JSON(commonResponse))
}
+ refreshToken := c.Value("refreshToken").(string)
+ if refreshToken != sess.RefreshToken {
+ return c.Render(http.StatusForbidden, render.JSON(map[string]interface{}{"error": http.StatusText(http.StatusForbidden)}))
+ }
+
tokenSet, err := handler.RefreshAccessToken(sess.RefreshToken)
if err != nil {
app.Logger.Error(err.Error())
- commonResponse := handler.CommonResponseStatusBadRequest(err.Error())
+ commonResponse := handler.CommonResponseStatusForbidden(err.Error())
return c.Render(commonResponse.Status.StatusCode, r.JSON(commonResponse))
}
sess.AccessToken = tokenSet.Accesstoken
sess.ExpiresIn = float64(tokenSet.ExpiresIn)
- sess.RefreshToken = tokenSet.Accesstoken
+ sess.RefreshToken = tokenSet.RefreshToken
sess.RefreshExpiresIn = float64(tokenSet.RefreshExpiresIn)
_, err = handler.UpdateUserSess(tx, sess)
diff --git a/api/actions/middleware.go b/api/actions/middleware.go
index 327eaf5f..76677df5 100644
--- a/api/actions/middleware.go
+++ b/api/actions/middleware.go
@@ -37,3 +37,34 @@ func SetContextMiddleware(next buffalo.Handler) buffalo.Handler {
return next(c)
}
}
+
+func SetRefreshCtxMiddleware(next buffalo.Handler) buffalo.Handler {
+ return func(c buffalo.Context) error {
+ accessToken := strings.TrimPrefix(c.Request().Header.Get("Authorization"), "Bearer ")
+ _, err := handler.GetTokenClaims(accessToken)
+ if errMsg := err.Error(); err != nil && !strings.Contains(errMsg, "token is expired") {
+ app.Logger.Error(errMsg)
+ app.Logger.Error("error occured from token claim")
+ return c.Render(http.StatusUnauthorized, render.JSON(map[string]interface{}{"error": "Unauthorized"}))
+ }
+
+ commonRequest := &handler.CommonRequest{}
+ if err := c.Bind(commonRequest); err != nil {
+ app.Logger.Error(err.Error())
+ return c.Render(http.StatusBadRequest, render.JSON(map[string]interface{}{"error": http.StatusText(http.StatusBadRequest)}))
+ }
+
+ refreshToken := commonRequest.Request.(map[string]interface{})["refresh_token"].(string)
+
+ refreshTokenClaim, err := handler.GetRefreshTokenClaims(refreshToken)
+ if err != nil {
+ app.Logger.Error(err.Error())
+ return c.Render(http.StatusForbidden, render.JSON(map[string]interface{}{"error": http.StatusText(http.StatusForbidden)}))
+ }
+
+ c.Set("UserId", refreshTokenClaim.Upn)
+ c.Set("refreshToken", refreshToken)
+
+ return next(c)
+ }
+}
diff --git a/api/handler/auth.go b/api/handler/auth.go
index d6f64551..8e34c6d1 100644
--- a/api/handler/auth.go
+++ b/api/handler/auth.go
@@ -214,9 +214,10 @@ func generateJWT() (*CmigUserLoginResponse, error) {
refreshExp := time.Now().Add(refreshTokenExpired).Unix()
refreshClaims := CmigRefreshtokenClaims{
- Exp: exp,
+ Exp: refreshExp,
+ Upn: user.Id,
MapClaims: &jwt.MapClaims{
- "exp": exp,
+ "exp": refreshExp,
},
}
refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims)
@@ -242,7 +243,7 @@ func GetUserToken(id string, password string) (*CmigUserLoginResponse, error) {
}
func RefreshAccessToken(refreshToken string) (*CmigUserLoginResponse, error) {
- token, err := jwt.ParseWithClaims(refreshToken, &CmigAccesstokenClaims{}, func(token *jwt.Token) (interface{}, error) {
+ token, err := jwt.ParseWithClaims(refreshToken, &CmigRefreshtokenClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
@@ -251,7 +252,7 @@ func RefreshAccessToken(refreshToken string) (*CmigUserLoginResponse, error) {
if err != nil {
return nil, fmt.Errorf("token is invalid : %s", err.Error())
}
- if claims, ok := token.Claims.(*CmigAccesstokenClaims); ok && token.Valid {
+ if claims, ok := token.Claims.(*CmigRefreshtokenClaims); ok && token.Valid {
if time.Now().Unix() > claims.Exp {
return nil, fmt.Errorf("refresh token expired")
}
@@ -261,15 +262,32 @@ func RefreshAccessToken(refreshToken string) (*CmigUserLoginResponse, error) {
}
}
-func GetTokenClaims(tokenString string) (*CmigAccesstokenClaims, error) {
- token, err := jwt.ParseWithClaims(tokenString, &CmigAccesstokenClaims{}, func(token *jwt.Token) (interface{}, error) {
+func GetRefreshTokenClaims(tokenString string) (*CmigRefreshtokenClaims, error) {
+ token, err := jwt.ParseWithClaims(tokenString, &CmigRefreshtokenClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return encryptionKey, nil
})
if err != nil {
- return nil, fmt.Errorf("token is invalid : %s", err.Error())
+ return nil, err
+ }
+ if claims, ok := token.Claims.(*CmigRefreshtokenClaims); ok && token.Valid {
+ return claims, nil
+ } else {
+ return nil, fmt.Errorf("token is invalid")
+ }
+}
+
+func GetTokenClaims(tokenString string) (*CmigAccesstokenClaims, error) {
+ token, err := jwt.ParseWithClaims(tokenString, &CmigAccesstokenClaims{}, func(t *jwt.Token) (interface{}, error) {
+ if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
+ return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
+ }
+ return encryptionKey, nil
+ })
+ if err != nil {
+ return nil, err
}
if claims, ok := token.Claims.(*CmigAccesstokenClaims); ok && token.Valid {
return claims, nil
diff --git a/api/handler/http-util.go b/api/handler/http-util.go
index 1ec9849f..b9ac3c59 100644
--- a/api/handler/http-util.go
+++ b/api/handler/http-util.go
@@ -65,7 +65,7 @@ type ApiYaml struct {
// ////////////////////////////////////////////////////////////////
var (
- ApiYamlSet ApiYaml
+ ApiYamlSet ApiYaml
)
func init() {
@@ -359,6 +359,17 @@ func CommonResponseStatusBadRequest(responseData interface{}) *CommonResponse {
}
}
+func CommonResponseStatusForbidden(responseData interface{}) *CommonResponse {
+ webStatus := WebStatus{
+ StatusCode: http.StatusForbidden,
+ Message: http.StatusText(http.StatusForbidden),
+ }
+ return &CommonResponse{
+ ResponseData: responseData,
+ Status: webStatus,
+ }
+}
+
func CommonResponseStatusInternalServerError(responseData interface{}) *CommonResponse {
webStatus := WebStatus{
StatusCode: http.StatusInternalServerError,
diff --git a/front/.env.local b/front/.env.local
index 54258825..582e8b5a 100644
--- a/front/.env.local
+++ b/front/.env.local
@@ -1,4 +1,4 @@
VITE_BACKEND_ENDPOINT = '/api'
-VITE_BACKEND_URL = 'http://cm-butterfly-api:4000'
+VITE_BACKEND_URL = 'https://devmigapi.onecloudcon.com'
VITE_PROJECT_NAME = 'MIGRATOR'
VITE_LANGUAGE = 'en'
diff --git a/front/src/app/providers/router/index.ts b/front/src/app/providers/router/index.ts
index 3e869397..ba13c13a 100644
--- a/front/src/app/providers/router/index.ts
+++ b/front/src/app/providers/router/index.ts
@@ -13,10 +13,14 @@ import { AuthorizationType } from '../../../shared/libs/store/auth';
import { useAuthStore } from '../../../shared/libs/store/auth';
import { ROLE_TYPE } from '../../../shared/libs/accessControl/pageAccessHelper/constant';
import { RoleType } from '../../../shared/libs/accessControl/pageAccessHelper/types';
-import { getMinimalPageAccessPermissionList } from '../../../shared/libs';
+import {
+ axiosPost,
+ getMinimalPageAccessPermissionList,
+} from '../../../shared/libs';
import { toLower } from 'lodash';
import { tempRoutes } from './routes/temp.ts';
import NotFound from '@/pages/error/404/NotFound.vue';
+import { axiosInstance, createInstance } from '@/shared/libs/api/instance.ts';
//TODO admin부분 고려
const accessiblePagesWithRoles = [] as any[];
@@ -62,6 +66,7 @@ export class McmpRouter {
mode: 'history',
routes: McmpRouter.rootRoute,
});
+
McmpRouter.router.beforeEach((to: Route, from: Route, next) => {
const requiresAuth = to.matched.some(
record => record.meta?.requiresAuth,
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/editor/model/beetleTaskEditorModel.ts b/front/src/features/sequential/designer/editor/model/beetleTaskEditorModel.ts
similarity index 100%
rename from front/src/features/workflow/workflowEditor/sequential/designer/editor/model/beetleTaskEditorModel.ts
rename to front/src/features/sequential/designer/editor/model/beetleTaskEditorModel.ts
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/editor/model/editorProviders.ts b/front/src/features/sequential/designer/editor/model/editorProviders.ts
similarity index 88%
rename from front/src/features/workflow/workflowEditor/sequential/designer/editor/model/editorProviders.ts
rename to front/src/features/sequential/designer/editor/model/editorProviders.ts
index 06a066bd..0c9cb8f4 100644
--- a/front/src/features/workflow/workflowEditor/sequential/designer/editor/model/editorProviders.ts
+++ b/front/src/features/sequential/designer/editor/model/editorProviders.ts
@@ -1,6 +1,6 @@
import { insertDynamicComponent } from '@/shared/utils';
-import { getSequencePath } from '@/features/workflow/workflowEditor/sequential/designer/editor/model/utils.ts';
-import BeetleTaskEditor from '@/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue';
+import { getSequencePath } from '@/features/sequential/designer/editor/model/utils.ts';
+import BeetleTaskEditor from '@/features/sequential/designer/editor/ui/BeetleTaskEditor.vue';
export function editorProviders() {
const editor = document.createElement('div');
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/editor/model/utils.ts b/front/src/features/sequential/designer/editor/model/utils.ts
similarity index 100%
rename from front/src/features/workflow/workflowEditor/sequential/designer/editor/model/utils.ts
rename to front/src/features/sequential/designer/editor/model/utils.ts
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue b/front/src/features/sequential/designer/editor/ui/BeetleTaskEditor.vue
similarity index 97%
rename from front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue
rename to front/src/features/sequential/designer/editor/ui/BeetleTaskEditor.vue
index 3dcc89c9..1ab5d08e 100644
--- a/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/BeetleTaskEditor.vue
+++ b/front/src/features/sequential/designer/editor/ui/BeetleTaskEditor.vue
@@ -13,9 +13,9 @@ import Vue, {
watch,
} from 'vue';
import { useInputModel } from '@/shared/hooks/input/useInputModel.ts';
-import { useTaskEditorModel } from '@/features/workflow/workflowEditor/sequential/designer/editor/model/beetleTaskEditorModel.ts';
+import { useTaskEditorModel } from '@/features/sequential/designer/editor/model/beetleTaskEditorModel.ts';
import BAccordion from '@/shared/ui/Input/Accordian/BAccordion.vue';
-import SequentialShortCut from '@/features/workflow/workflowEditor/sequential/designer/shortcut/ui/SequentialShortCut.vue';
+import SequentialShortCut from '@/features/sequential/designer/shortcut/ui/SequentialShortCut.vue';
import { Step } from '@/features/workflow/workflowEditor/model/types.ts';
interface IProps {
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/TaskGroupEditor.vue b/front/src/features/sequential/designer/editor/ui/TaskGroupEditor.vue
similarity index 100%
rename from front/src/features/workflow/workflowEditor/sequential/designer/editor/ui/TaskGroupEditor.vue
rename to front/src/features/sequential/designer/editor/ui/TaskGroupEditor.vue
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/model/sequentialDesignerModel.ts b/front/src/features/sequential/designer/model/sequentialDesignerModel.ts
similarity index 95%
rename from front/src/features/workflow/workflowEditor/sequential/designer/model/sequentialDesignerModel.ts
rename to front/src/features/sequential/designer/model/sequentialDesignerModel.ts
index c63b750b..8b229db7 100644
--- a/front/src/features/workflow/workflowEditor/sequential/designer/model/sequentialDesignerModel.ts
+++ b/front/src/features/sequential/designer/model/sequentialDesignerModel.ts
@@ -5,8 +5,8 @@ import {
} from 'sequential-workflow-designer';
import { Definition, Step } from 'sequential-workflow-model';
import getRandomId from '@/shared/utils/uuid';
-import { toolboxSteps } from '@/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts';
-import { editorProviders } from '@/features/workflow/workflowEditor/sequential/designer/editor/model/editorProviders.ts';
+import { toolboxSteps } from '@/features/sequential/designer/toolbox/model/toolboxSteps.ts';
+import { editorProviders } from '@/features/sequential/designer/editor/model/editorProviders.ts';
import testSvg from '@/shared/asset/image/testSvg.svg';
export function useSequentialDesignerModel(refs: any) {
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/shortcut/ui/SequentialShortCut.vue b/front/src/features/sequential/designer/shortcut/ui/SequentialShortCut.vue
similarity index 100%
rename from front/src/features/workflow/workflowEditor/sequential/designer/shortcut/ui/SequentialShortCut.vue
rename to front/src/features/sequential/designer/shortcut/ui/SequentialShortCut.vue
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/api/index.ts b/front/src/features/sequential/designer/toolbox/model/api/index.ts
similarity index 100%
rename from front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/api/index.ts
rename to front/src/features/sequential/designer/toolbox/model/api/index.ts
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxModel.ts b/front/src/features/sequential/designer/toolbox/model/toolboxModel.ts
similarity index 92%
rename from front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxModel.ts
rename to front/src/features/sequential/designer/toolbox/model/toolboxModel.ts
index 27867f83..8b9f34ee 100644
--- a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxModel.ts
+++ b/front/src/features/sequential/designer/toolbox/model/toolboxModel.ts
@@ -1,14 +1,14 @@
import {
getTaskComponentList,
ITaskComponentInfoResponse,
-} from '@/features/workflow/workflowEditor/sequential/designer/toolbox/model/api';
+} from '@/features/sequential/designer/toolbox/model/api';
import { parseRequestBody } from '@/shared/utils/stringToObject';
import getRandomId from '@/shared/utils/uuid';
import {
fixedModel,
Step,
} from '@/features/workflow/workflowEditor/model/types.ts';
-import { toolboxSteps } from '@/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts';
+import { toolboxSteps } from '@/features/sequential/designer/toolbox/model/toolboxSteps.ts';
import { ITaskResponse } from '@/entities';
export function useSequentialToolboxModel() {
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts b/front/src/features/sequential/designer/toolbox/model/toolboxSteps.ts
similarity index 100%
rename from front/src/features/workflow/workflowEditor/sequential/designer/toolbox/model/toolboxSteps.ts
rename to front/src/features/sequential/designer/toolbox/model/toolboxSteps.ts
diff --git a/front/src/features/workflow/workflowEditor/sequential/designer/ui/SequentialDesigner.vue b/front/src/features/sequential/designer/ui/SequentialDesigner.vue
similarity index 78%
rename from front/src/features/workflow/workflowEditor/sequential/designer/ui/SequentialDesigner.vue
rename to front/src/features/sequential/designer/ui/SequentialDesigner.vue
index ee31ebe4..ea9e92b2 100644
--- a/front/src/features/workflow/workflowEditor/sequential/designer/ui/SequentialDesigner.vue
+++ b/front/src/features/sequential/designer/ui/SequentialDesigner.vue
@@ -1,11 +1,11 @@
-
-
-
-
{{ title }}
-
- {{ badgeTitle }}
-
-
-
-
-
-
+
+
+
+
{{ title }}
+
- {{ addButtonText }}
-
-
-
-
-
+
+
+
+
+ {{ addButtonText }}
+
+
+
+
+
+
+
-
+