mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
Merge remote-tracking branch 'origin/3264-feature-gms-publish-user-backend-gradido-communities-dialog' into admin_update_community_list
This commit is contained in:
commit
3867cfe75b
@ -1,3 +1,9 @@
|
||||
import { RIGHTS } from './RIGHTS'
|
||||
|
||||
export const ADMIN_RIGHTS = [RIGHTS.SET_USER_ROLE, RIGHTS.DELETE_USER, RIGHTS.UNDELETE_USER]
|
||||
export const ADMIN_RIGHTS = [
|
||||
RIGHTS.SET_USER_ROLE,
|
||||
RIGHTS.DELETE_USER,
|
||||
RIGHTS.UNDELETE_USER,
|
||||
RIGHTS.COMMUNITY_UPDATE,
|
||||
RIGHTS.COMMUNITY_BY_UUID,
|
||||
]
|
||||
|
||||
@ -58,4 +58,6 @@ export enum RIGHTS {
|
||||
SET_USER_ROLE = 'SET_USER_ROLE',
|
||||
DELETE_USER = 'DELETE_USER',
|
||||
UNDELETE_USER = 'UNDELETE_USER',
|
||||
COMMUNITY_BY_UUID = 'COMMUNITY_BY_UUID',
|
||||
COMMUNITY_UPDATE = 'COMMUNITY_UPDATE',
|
||||
}
|
||||
|
||||
14
backend/src/graphql/arg/CommunityArgs.ts
Normal file
14
backend/src/graphql/arg/CommunityArgs.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { IsString } from 'class-validator'
|
||||
import { Field, ArgsType, InputType } from 'type-graphql'
|
||||
|
||||
@InputType()
|
||||
@ArgsType()
|
||||
export class CommunityArgs {
|
||||
@Field(() => String)
|
||||
@IsString()
|
||||
uuid: string
|
||||
|
||||
@Field(() => String)
|
||||
@IsString()
|
||||
gmsApiKey: string
|
||||
}
|
||||
@ -2,8 +2,6 @@ import { Community as DbCommunity } from '@entity/Community'
|
||||
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
|
||||
import { ObjectType, Field, Int } from 'type-graphql'
|
||||
|
||||
import { backendLogger as logger } from '@/server/logger'
|
||||
|
||||
import { FederatedCommunity } from './FederatedCommunity'
|
||||
|
||||
@ObjectType()
|
||||
@ -39,6 +37,7 @@ export class Community {
|
||||
this.updatedAt = dbCom.updatedAt
|
||||
this.uuid = dbCom.communityUuid
|
||||
this.authenticatedAt = dbCom.authenticatedAt
|
||||
this.gmsApiKey = dbCom.gmsApiKey
|
||||
}
|
||||
|
||||
@Field(() => Int)
|
||||
|
||||
@ -9,21 +9,38 @@ import { Connection } from '@dbTools/typeorm'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
|
||||
import { ApolloServerTestClient } from 'apollo-server-testing'
|
||||
import { GraphQLError } from 'graphql/error/GraphQLError'
|
||||
|
||||
import { cleanDB, testEnvironment } from '@test/helpers'
|
||||
import { logger, i18n as localization } from '@test/testSetup'
|
||||
|
||||
import { getCommunities, communities } from '@/seeds/graphql/queries'
|
||||
import { userFactory } from '@/seeds/factory/user'
|
||||
import { login, updateHomeCommunityQuery } from '@/seeds/graphql/mutations'
|
||||
import { getCommunities, communitiesQuery, getCommunityByUuidQuery } from '@/seeds/graphql/queries'
|
||||
import { peterLustig } from '@/seeds/users/peter-lustig'
|
||||
|
||||
import { getCommunityByUuid } from './util/communities'
|
||||
|
||||
// to do: We need a setup for the tests that closes the connection
|
||||
let query: ApolloServerTestClient['query'], con: Connection
|
||||
let mutate: ApolloServerTestClient['mutate'],
|
||||
query: ApolloServerTestClient['query'],
|
||||
con: Connection
|
||||
|
||||
let testEnv: {
|
||||
mutate: ApolloServerTestClient['mutate']
|
||||
query: ApolloServerTestClient['query']
|
||||
con: Connection
|
||||
}
|
||||
|
||||
const peterLoginData = {
|
||||
email: 'peter@lustig.de',
|
||||
password: 'Aa12345_',
|
||||
publisherId: 1234,
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
testEnv = await testEnvironment()
|
||||
testEnv = await testEnvironment(logger, localization)
|
||||
mutate = testEnv.mutate
|
||||
query = testEnv.query
|
||||
con = testEnv.con
|
||||
await DbFederatedCommunity.clear()
|
||||
@ -248,7 +265,7 @@ describe('CommunityResolver', () => {
|
||||
it('returns no community entry', async () => {
|
||||
// const result: Community[] = await query({ query: getCommunities })
|
||||
// expect(result.length).toEqual(0)
|
||||
await expect(query({ query: communities })).resolves.toMatchObject({
|
||||
await expect(query({ query: communitiesQuery })).resolves.toMatchObject({
|
||||
data: {
|
||||
communities: [],
|
||||
},
|
||||
@ -275,7 +292,7 @@ describe('CommunityResolver', () => {
|
||||
})
|
||||
|
||||
it('returns 1 home-community entry', async () => {
|
||||
await expect(query({ query: communities })).resolves.toMatchObject({
|
||||
await expect(query({ query: communitiesQuery })).resolves.toMatchObject({
|
||||
data: {
|
||||
communities: [
|
||||
{
|
||||
@ -337,7 +354,7 @@ describe('CommunityResolver', () => {
|
||||
})
|
||||
|
||||
it('returns 2 community entries', async () => {
|
||||
await expect(query({ query: communities })).resolves.toMatchObject({
|
||||
await expect(query({ query: communitiesQuery })).resolves.toMatchObject({
|
||||
data: {
|
||||
communities: [
|
||||
{
|
||||
@ -377,5 +394,129 @@ describe('CommunityResolver', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('search community by uuid', () => {
|
||||
let homeCom: DbCommunity | null
|
||||
beforeEach(async () => {
|
||||
await cleanDB()
|
||||
jest.clearAllMocks()
|
||||
const admin = await userFactory(testEnv, peterLustig)
|
||||
// login as admin
|
||||
await mutate({ mutation: login, variables: peterLoginData })
|
||||
|
||||
// HomeCommunity is still created in userFactory
|
||||
homeCom = await getCommunityByUuid(admin.communityUuid)
|
||||
|
||||
foreignCom1 = DbCommunity.create()
|
||||
foreignCom1.foreign = true
|
||||
foreignCom1.url = 'http://stage-2.gradido.net/api'
|
||||
foreignCom1.publicKey = Buffer.from('publicKey-stage-2_Community')
|
||||
foreignCom1.privateKey = Buffer.from('privateKey-stage-2_Community')
|
||||
// foreignCom1.communityUuid = 'Stage2-Com-UUID'
|
||||
// foreignCom1.authenticatedAt = new Date()
|
||||
foreignCom1.name = 'Stage-2_Community-name'
|
||||
foreignCom1.description = 'Stage-2_Community-description'
|
||||
foreignCom1.creationDate = new Date()
|
||||
await DbCommunity.insert(foreignCom1)
|
||||
|
||||
foreignCom2 = DbCommunity.create()
|
||||
foreignCom2.foreign = true
|
||||
foreignCom2.url = 'http://stage-3.gradido.net/api'
|
||||
foreignCom2.publicKey = Buffer.from('publicKey-stage-3_Community')
|
||||
foreignCom2.privateKey = Buffer.from('privateKey-stage-3_Community')
|
||||
foreignCom2.communityUuid = 'Stage3-Com-UUID'
|
||||
foreignCom2.authenticatedAt = new Date()
|
||||
foreignCom2.name = 'Stage-3_Community-name'
|
||||
foreignCom2.description = 'Stage-3_Community-description'
|
||||
foreignCom2.creationDate = new Date()
|
||||
await DbCommunity.insert(foreignCom2)
|
||||
})
|
||||
|
||||
it('finds the home-community', async () => {
|
||||
await expect(
|
||||
query({
|
||||
query: getCommunityByUuidQuery,
|
||||
variables: { communityUuid: homeCom?.communityUuid },
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
getCommunityByUuid: {
|
||||
id: homeCom?.id,
|
||||
foreign: homeCom?.foreign,
|
||||
name: homeCom?.name,
|
||||
description: homeCom?.description,
|
||||
url: homeCom?.url,
|
||||
creationDate: homeCom?.creationDate?.toISOString(),
|
||||
uuid: homeCom?.communityUuid,
|
||||
authenticatedAt: homeCom?.authenticatedAt,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('updates the home-community gmsApiKey', async () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: updateHomeCommunityQuery,
|
||||
variables: { uuid: homeCom?.communityUuid, gmsApiKey: 'gmsApiKey' },
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
updateHomeCommunity: {
|
||||
id: expect.any(Number),
|
||||
foreign: homeCom?.foreign,
|
||||
name: homeCom?.name,
|
||||
description: homeCom?.description,
|
||||
url: homeCom?.url,
|
||||
creationDate: homeCom?.creationDate?.toISOString(),
|
||||
uuid: homeCom?.communityUuid,
|
||||
authenticatedAt: homeCom?.authenticatedAt,
|
||||
gmsApiKey: 'gmsApiKey',
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('throws error on updating a foreign-community', async () => {
|
||||
expect(
|
||||
await mutate({
|
||||
mutation: updateHomeCommunityQuery,
|
||||
variables: { uuid: foreignCom2.communityUuid, gmsApiKey: 'gmsApiKey' },
|
||||
}),
|
||||
).toEqual(
|
||||
expect.objectContaining({
|
||||
errors: [new GraphQLError('Error: Only the HomeCommunity could be modified!')],
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('throws error on updating a community without uuid', async () => {
|
||||
expect(
|
||||
await mutate({
|
||||
mutation: updateHomeCommunityQuery,
|
||||
variables: { uuid: null, gmsApiKey: 'gmsApiKey' },
|
||||
}),
|
||||
).toEqual(
|
||||
expect.objectContaining({
|
||||
errors: [
|
||||
new GraphQLError(`Variable "$uuid" of non-null type "String!" must not be null.`),
|
||||
],
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('throws error on updating a community with not existing uuid', async () => {
|
||||
expect(
|
||||
await mutate({
|
||||
mutation: updateHomeCommunityQuery,
|
||||
variables: { uuid: 'unknownUuid', gmsApiKey: 'gmsApiKey' },
|
||||
}),
|
||||
).toEqual(
|
||||
expect.objectContaining({
|
||||
errors: [new GraphQLError('HomeCommunity with uuid not found: ')],
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { IsNull, Not } from '@dbTools/typeorm'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
|
||||
import { Resolver, Query, Authorized, Arg, Args } from 'type-graphql'
|
||||
import { Resolver, Query, Authorized, Arg, Mutation, Args } from 'type-graphql'
|
||||
|
||||
import { CommunityArgs } from '@arg//CommunityArgs'
|
||||
import { Paginated } from '@arg/Paginated'
|
||||
import { Community } from '@model/Community'
|
||||
import { FederatedCommunity } from '@model/FederatedCommunity'
|
||||
@ -10,7 +11,7 @@ import { FederatedCommunity } from '@model/FederatedCommunity'
|
||||
import { RIGHTS } from '@/auth/RIGHTS'
|
||||
import { LogError } from '@/server/LogError'
|
||||
|
||||
import { getAllCommunities, getCommunity } from './util/communities'
|
||||
import { getAllCommunities, getCommunityByUuid } from './util/communities'
|
||||
|
||||
@Resolver()
|
||||
export class CommunityResolver {
|
||||
@ -47,13 +48,41 @@ export class CommunityResolver {
|
||||
return dbCommunities.map((dbCom: DbCommunity) => new Community(dbCom))
|
||||
}
|
||||
|
||||
@Authorized([RIGHTS.COMMUNITIES])
|
||||
@Authorized([RIGHTS.COMMUNITY_BY_UUID])
|
||||
@Query(() => Community)
|
||||
async community(@Arg('communityUuid') communityUuid: string): Promise<Community> {
|
||||
const community = await getCommunity(communityUuid)
|
||||
if (!community) {
|
||||
async getCommunityByUuid(@Arg('communityUuid') communityUuid: string): Promise<Community> {
|
||||
const com: DbCommunity | null = await getCommunityByUuid(communityUuid)
|
||||
if (!com) {
|
||||
throw new LogError('community not found', communityUuid)
|
||||
}
|
||||
return new Community(community)
|
||||
return new Community(com)
|
||||
}
|
||||
|
||||
@Authorized([RIGHTS.COMMUNITY_UPDATE])
|
||||
@Mutation(() => Community)
|
||||
async updateHomeCommunity(@Args() { uuid, gmsApiKey }: CommunityArgs): Promise<Community> {
|
||||
let homeCom: DbCommunity | null
|
||||
let com: Community
|
||||
if (uuid) {
|
||||
let toUpdate = false
|
||||
homeCom = await getCommunityByUuid(uuid)
|
||||
if (!homeCom) {
|
||||
throw new LogError('HomeCommunity with uuid not found: ', uuid)
|
||||
}
|
||||
if (homeCom.foreign) {
|
||||
throw new LogError('Error: Only the HomeCommunity could be modified!')
|
||||
}
|
||||
if (homeCom.gmsApiKey !== gmsApiKey) {
|
||||
homeCom.gmsApiKey = gmsApiKey
|
||||
toUpdate = true
|
||||
}
|
||||
if (toUpdate) {
|
||||
await DbCommunity.save(homeCom)
|
||||
}
|
||||
com = new Community(homeCom)
|
||||
} else {
|
||||
throw new LogError(`HomeCommunity without an uuid can't be modified!`)
|
||||
}
|
||||
return com
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ import { calculateBalance } from '@/util/validate'
|
||||
import { virtualLinkTransaction, virtualDecayTransaction } from '@/util/virtualTransactions'
|
||||
|
||||
import { BalanceResolver } from './BalanceResolver'
|
||||
import { getCommunity, getCommunityName, isHomeCommunity } from './util/communities'
|
||||
import { getCommunityByUuid, getCommunityName, isHomeCommunity } from './util/communities'
|
||||
import { findUserByIdentifier } from './util/findUserByIdentifier'
|
||||
import { getLastTransaction } from './util/getLastTransaction'
|
||||
import { getTransactionList } from './util/getTransactionList'
|
||||
@ -452,7 +452,7 @@ export class TransactionResolver {
|
||||
if (!CONFIG.FEDERATION_XCOM_SENDCOINS_ENABLED) {
|
||||
throw new LogError('X-Community sendCoins disabled per configuration!')
|
||||
}
|
||||
const recipCom = await getCommunity(recipientCommunityIdentifier)
|
||||
const recipCom = await getCommunityByUuid(recipientCommunityIdentifier)
|
||||
logger.debug('recipient commuity: ', recipCom)
|
||||
if (recipCom === null) {
|
||||
throw new LogError(
|
||||
|
||||
@ -65,7 +65,7 @@ export async function getCommunityName(communityIdentifier: string): Promise<str
|
||||
}
|
||||
}
|
||||
|
||||
export async function getCommunity(communityUuid: string): Promise<DbCommunity | null> {
|
||||
export async function getCommunityByUuid(communityUuid: string): Promise<DbCommunity | null> {
|
||||
return await DbCommunity.findOne({
|
||||
where: [{ communityUuid }],
|
||||
})
|
||||
|
||||
@ -354,3 +354,19 @@ export const logout = gql`
|
||||
logout
|
||||
}
|
||||
`
|
||||
|
||||
export const updateHomeCommunityQuery = gql`
|
||||
mutation ($uuid: String!, $gmsApiKey: String!) {
|
||||
updateHomeCommunity(uuid: $uuid, gmsApiKey: $gmsApiKey) {
|
||||
id
|
||||
foreign
|
||||
name
|
||||
description
|
||||
url
|
||||
creationDate
|
||||
uuid
|
||||
authenticatedAt
|
||||
gmsApiKey
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@ -118,7 +118,7 @@ export const listGDTEntriesQuery = gql`
|
||||
}
|
||||
`
|
||||
|
||||
export const communities = gql`
|
||||
export const communitiesQuery = gql`
|
||||
query {
|
||||
communities {
|
||||
id
|
||||
@ -129,6 +129,23 @@ export const communities = gql`
|
||||
creationDate
|
||||
uuid
|
||||
authenticatedAt
|
||||
gmsApiKey
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const getCommunityByUuidQuery = gql`
|
||||
query ($communityUuid: String!) {
|
||||
getCommunityByUuid(communityUuid: $communityUuid) {
|
||||
id
|
||||
foreign
|
||||
name
|
||||
description
|
||||
url
|
||||
creationDate
|
||||
uuid
|
||||
authenticatedAt
|
||||
gmsApiKey
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user