HM-111. Автор api присваивается исходя из токена и наличия метки у пользователя is_admin

This commit is contained in:
vigdorov
2020-08-08 19:21:05 +03:00
parent b1ffc9a8a5
commit 64d81e9894
6 changed files with 152 additions and 17 deletions

View File

@ -80,7 +80,7 @@ export class StoreController {
})
async create(@Req() request: Request<null, StoreRequest>): Promise<StoreRequest> {
const api = makeApiHeader(request);
const store = await this.storeService.create(api, request.body);
const store = await this.storeService.create(api, request.body, request.headers.authorization);
return prepareStoreToStoreRequest(store);
}

View File

@ -1,8 +1,16 @@
import {Model, Connection} from 'mongoose';
import {Injectable, NotFoundException, BadGatewayException, ConflictException, BadRequestException} from '@nestjs/common';
import {Injectable, NotFoundException, BadGatewayException, ConflictException, BadRequestException, HttpException, HttpService} from '@nestjs/common';
import {InjectConnection} from '@nestjs/mongoose';
import {Store, StoreRequest, StoreSchema} from './store.schema';
import {DB_TEST_NAME, DB_NAME, COLLECTION_STORE} from 'src/consts';
import * as jwt from 'jsonwebtoken';
interface Token {
login: string;
agent: string;
iat: number;
exp: number;
}
const validateModel = async (store: Store) => {
try {
@ -17,6 +25,7 @@ export class StoreService {
constructor(
@InjectConnection(DB_NAME) private dbConnection: Connection,
@InjectConnection(DB_TEST_NAME) private dbTestConnection: Connection,
private http: HttpService,
) {}
storeModel(api: string): Model<Store> {
@ -30,30 +39,51 @@ export class StoreService {
return this.storeModel(api).find().exec();
}
async create(api: string, store: StoreRequest): Promise<Store> {
async create(api: string, store: StoreRequest, access_token: string): Promise<Store> {
const searchStore = await this.storeModel(api).findOne({key: store.key});
if (searchStore) {
throw new ConflictException(`Api key "${store.key}" is already taken`);
}
const createdStore = new (this.storeModel(api))(store);
const {login, agent} = jwt.decode(access_token) as Token;
const apiPath = 'http://api.auth.vigdorov.ru/users/search/';
const headers = {
Authorization: access_token,
'user-agent': agent
};
try {
await validateModel(createdStore);
} catch (e) {
if (e?.message?.includes('validation failed')) {
throw new BadRequestException(e.message);
const {data: currentUser} = await this.http.get(`${apiPath}${login}`, {headers}).toPromise();
await this.http.get(`${apiPath}${store.author}`, {headers}).toPromise();
const author = currentUser.is_admin ? store.author : login;
const createdStore = new (this.storeModel(api))({
...store,
author,
});
try {
await validateModel(createdStore);
} catch (e) {
if (e?.message?.includes('validation failed')) {
throw new BadRequestException(e.message);
}
throw e;
}
throw e;
}
const savedStore = await createdStore.save();
if (!Object.keys(savedStore.value).length) {
await savedStore.updateOne(store);
const savedStore = await createdStore.save();
if (!Object.keys(savedStore.value).length) {
await savedStore.updateOne({value: {}});
}
return savedStore;
} catch (e) {
if (e?.response?.data?.statusCode === 404) {
throw new NotFoundException(e.response.data.message);
}
throw new BadRequestException(e.message);
}
return savedStore;
}
async update(api: string, {author, ...omitProps}: StoreRequest): Promise<Store> {