Implemented Multiple API key deletion. Added Notification for API key deletion result. (#1298)
* Implemented Notification for API key deletion result. * Moved several API keys deletion to Service side.
This commit is contained in:
parent
3beaeebdb6
commit
ad95d881c7
@ -38,8 +38,8 @@ const (
|
||||
|
||||
// CreateAPIKeyMutation is a mutation name for api key creation
|
||||
CreateAPIKeyMutation = "createAPIKey"
|
||||
// DeleteAPIKeyMutation is a mutation name for api key deleting
|
||||
DeleteAPIKeyMutation = "deleteAPIKey"
|
||||
// DeleteAPIKeysMutation is a mutation name for api key deleting
|
||||
DeleteAPIKeysMutation = "deleteAPIKeys"
|
||||
|
||||
// InputArg is argument name for all input types
|
||||
InputArg = "input"
|
||||
@ -329,32 +329,39 @@ func rootMutation(service *console.Service, types Types) *graphql.Object {
|
||||
},
|
||||
},
|
||||
// deletes api key
|
||||
DeleteAPIKeyMutation: &graphql.Field{
|
||||
Type: types.APIKeyInfo(),
|
||||
DeleteAPIKeysMutation: &graphql.Field{
|
||||
Type: graphql.NewList(types.APIKeyInfo()),
|
||||
Args: graphql.FieldConfigArgument{
|
||||
FieldID: &graphql.ArgumentConfig{
|
||||
Type: graphql.NewNonNull(graphql.String),
|
||||
Type: graphql.NewNonNull(graphql.NewList(graphql.String)),
|
||||
},
|
||||
},
|
||||
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
|
||||
keyID, _ := p.Args[FieldID].(string)
|
||||
paramKeysID, _ := p.Args[FieldID].([]interface{})
|
||||
|
||||
id, err := uuid.Parse(keyID)
|
||||
var keyIds []uuid.UUID
|
||||
var keys []console.APIKeyInfo
|
||||
for _, id := range paramKeysID {
|
||||
keyID, err := uuid.Parse(id.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key, err := service.GetAPIKeyInfo(p.Context, *keyID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keyIds = append(keyIds, *keyID)
|
||||
keys = append(keys, *key)
|
||||
}
|
||||
|
||||
err := service.DeleteAPIKeys(p.Context, keyIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key, err := service.GetAPIKeyInfo(p.Context, *id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = service.DeleteAPIKey(p.Context, *id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return key, nil
|
||||
return keys, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -491,17 +491,20 @@ func TestGrapqhlMutation(t *testing.T) {
|
||||
}
|
||||
|
||||
query := fmt.Sprintf(
|
||||
"mutation {deleteAPIKey(id:\"%s\"){name,projectID}}",
|
||||
id.String(),
|
||||
"mutation {deleteAPIKeys(id:[\"%s\"]){name,projectID}}",
|
||||
keyID,
|
||||
)
|
||||
|
||||
result := testQuery(t, query)
|
||||
|
||||
data := result.(map[string]interface{})
|
||||
keyInfo := data[consoleql.DeleteAPIKeyMutation].(map[string]interface{})
|
||||
keyInfoList := data[consoleql.DeleteAPIKeysMutation].([]interface{})
|
||||
|
||||
assert.Equal(t, info.Name, keyInfo[consoleql.FieldName])
|
||||
assert.Equal(t, project.ID.String(), keyInfo[consoleql.FieldProjectID])
|
||||
for _, k := range keyInfoList {
|
||||
keyInfo := k.(map[string]interface{})
|
||||
|
||||
assert.Equal(t, info.Name, keyInfo[consoleql.FieldName])
|
||||
assert.Equal(t, project.ID.String(), keyInfo[consoleql.FieldProjectID])
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Delete project mutation", func(t *testing.T) {
|
||||
|
@ -547,25 +547,56 @@ func (s *Service) GetAPIKeyInfo(ctx context.Context, id uuid.UUID) (*APIKeyInfo,
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// DeleteAPIKey deletes api key by id
|
||||
func (s *Service) DeleteAPIKey(ctx context.Context, id uuid.UUID) (err error) {
|
||||
// DeleteAPIKeys deletes api key by id
|
||||
func (s *Service) DeleteAPIKeys(ctx context.Context, ids []uuid.UUID) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
auth, err := GetAuth(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key, err := s.store.APIKeys().Get(ctx, id)
|
||||
var keysErr errs.Group
|
||||
|
||||
for _, keyID := range ids {
|
||||
key, err := s.store.APIKeys().Get(ctx, keyID)
|
||||
if err != nil {
|
||||
keysErr.Add(err)
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = s.isProjectMember(ctx, auth.User.ID, key.ProjectID)
|
||||
if err != nil {
|
||||
keysErr.Add(ErrUnauthorized.Wrap(err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if err = keysErr.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx, err := s.store.BeginTx(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = s.isProjectMember(ctx, auth.User.ID, key.ProjectID)
|
||||
if err != nil {
|
||||
return ErrUnauthorized.Wrap(err)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
err = errs.Combine(err, tx.Rollback())
|
||||
return
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
}()
|
||||
|
||||
for _, keyToDeleteID := range ids {
|
||||
err = tx.APIKeys().Delete(ctx, keyToDeleteID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return s.store.APIKeys().Delete(ctx, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAPIKeysInfoByProjectID retrieves all api keys for a given project
|
||||
|
@ -72,7 +72,6 @@ export async function createAPIKey(projectID: string, name: string) {
|
||||
if (response.errors) {
|
||||
result.errorMessage = response.errors[0].message;
|
||||
} else {
|
||||
console.log('response', response)
|
||||
result.isSuccess = true;
|
||||
result.data = {
|
||||
key: response.data.createAPIKey.key,
|
||||
@ -86,7 +85,7 @@ export async function createAPIKey(projectID: string, name: string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function deleteAPIKey(id: string) {
|
||||
export async function deleteAPIKeys(ids: string[]) {
|
||||
let result: RequestResponse<any> = {
|
||||
errorMessage: '',
|
||||
isSuccess: false,
|
||||
@ -97,7 +96,7 @@ export async function deleteAPIKey(id: string) {
|
||||
let response: any = await apollo.mutate({
|
||||
mutation: gql(
|
||||
`mutation {
|
||||
deleteAPIKey(id: "${id}") {
|
||||
deleteAPIKeys(id: [${prepareIdList(ids)}]) {
|
||||
id
|
||||
}
|
||||
}`
|
||||
@ -109,11 +108,21 @@ export async function deleteAPIKey(id: string) {
|
||||
result.errorMessage = response.errors[0].message;
|
||||
} else {
|
||||
result.isSuccess = true;
|
||||
result.data = response.data.deleteAPIKey;
|
||||
result.data = response.data.deleteAPIKeys;
|
||||
}
|
||||
} catch (e) {
|
||||
result.errorMessage = e.message;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function prepareIdList(ids: string[]): string {
|
||||
let idString: string = '';
|
||||
|
||||
ids.forEach(id => {
|
||||
idString += `"${id}", `;
|
||||
});
|
||||
|
||||
return idString;
|
||||
}
|
||||
|
@ -30,17 +30,23 @@
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
import Button from '@/components/common/Button.vue';
|
||||
import { API_KEYS_ACTIONS } from "@/utils/constants/actionNames";
|
||||
import { API_KEYS_ACTIONS, NOTIFICATION_ACTIONS } from "@/utils/constants/actionNames";
|
||||
|
||||
@Component({
|
||||
methods: {
|
||||
onDelete: async function () {
|
||||
let selectedKeys: any[] = this.$store.getters.selectedAPIKeys;
|
||||
onDelete: async function () {
|
||||
let selectedKeys: any[] = this.$store.getters.selectedAPIKeys.map((key)=>{return key.id});
|
||||
|
||||
for (let i = 0; i < selectedKeys.length; i++) {
|
||||
this.$store.dispatch(API_KEYS_ACTIONS.DELETE, selectedKeys[i].id);
|
||||
}
|
||||
},
|
||||
const dispatchResult = await this.$store.dispatch(API_KEYS_ACTIONS.DELETE, selectedKeys);
|
||||
|
||||
let keySuffix = selectedKeys.length > 1 ? '\'s' : '';
|
||||
|
||||
if(dispatchResult.isSuccess){
|
||||
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, `API key${keySuffix} deleted successfully`);
|
||||
} else {
|
||||
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, `Error during deletion API key${keySuffix}`);
|
||||
}
|
||||
},
|
||||
onClearSelection: function (): void {
|
||||
this.$store.dispatch(API_KEYS_ACTIONS.CLEAR_SELECTION);
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
// See LICENSE for copying information.
|
||||
|
||||
import { API_KEYS_MUTATIONS } from '../mutationConstants';
|
||||
import { createAPIKey, deleteAPIKey, fetchAPIKeys } from "@/api/apiKeys";
|
||||
import { createAPIKey, deleteAPIKeys, fetchAPIKeys } from '@/api/apiKeys';
|
||||
import { API_KEYS_ACTIONS } from "@/utils/constants/actionNames";
|
||||
|
||||
export const apiKeysModule = {
|
||||
@ -16,8 +16,14 @@ export const apiKeysModule = {
|
||||
[API_KEYS_MUTATIONS.ADD](state: any, apiKey: any) {
|
||||
state.apiKeys.push(apiKey);
|
||||
},
|
||||
[API_KEYS_MUTATIONS.DELETE](state: any, id: string) {
|
||||
state.apiKeys = state.apiKeys.filter((key => key.id !== id))
|
||||
[API_KEYS_MUTATIONS.DELETE](state: any, ids: string[]) {
|
||||
const keysCount = ids.length;
|
||||
|
||||
for (let j = 0; j < keysCount; j++) {
|
||||
state.apiKeys = state.apiKeys.filter((element: any) => {
|
||||
return element.id !== ids[j];
|
||||
});
|
||||
}
|
||||
},
|
||||
[API_KEYS_MUTATIONS.TOGGLE_SELECTION](state: any, apiKeyID: string) {
|
||||
state.apiKeys = state.apiKeys.map((apiKey: any) => {
|
||||
@ -52,7 +58,6 @@ export const apiKeysModule = {
|
||||
const projectId = rootGetters.selectedProject.id;
|
||||
|
||||
let result = await createAPIKey(projectId, name);
|
||||
console.log(result);
|
||||
|
||||
if (result.isSuccess) {
|
||||
commit(API_KEYS_MUTATIONS.ADD, result.data.keyInfo);
|
||||
@ -60,15 +65,13 @@ export const apiKeysModule = {
|
||||
|
||||
return result;
|
||||
},
|
||||
[API_KEYS_ACTIONS.DELETE]: async function({commit}: any, id: string): Promise<RequestResponse<any>> {
|
||||
let result = await deleteAPIKey(id);
|
||||
[API_KEYS_ACTIONS.DELETE]: async function({commit}: any, ids: string[]): Promise<RequestResponse<any>> {
|
||||
let result = await deleteAPIKeys(ids);
|
||||
|
||||
if (result.isSuccess) {
|
||||
commit(API_KEYS_MUTATIONS.DELETE, result.data.id);
|
||||
commit(API_KEYS_MUTATIONS.DELETE, ids);
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
|
||||
return result;
|
||||
},
|
||||
[API_KEYS_ACTIONS.TOGGLE_SELECTION]: function({commit}, apiKeyID: string): void {
|
||||
|
Loading…
Reference in New Issue
Block a user