Skip to content

Profile on knowledge base visible on private #4913

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
POLICY_RULE_CALLOUT_CONTRIBUTE,
POLICY_RULE_COLLABORATION_CREATE,
} from '@common/constants';
import { IAuthorizationPolicyRuleCredential } from '@core/authorization/authorization.policy.rule.credential.interface';

@Injectable()
export class CalloutsSetAuthorizationService {
Expand All @@ -25,7 +26,8 @@ export class CalloutsSetAuthorizationService {
calloutsSetInput: ICalloutsSet,
parentAuthorization: IAuthorizationPolicy | undefined,
roleSet?: IRoleSet,
spaceSettings?: ISpaceSettings
spaceSettings?: ISpaceSettings,
credentialRulesFromParent: IAuthorizationPolicyRuleCredential[] = []
): Promise<IAuthorizationPolicy[]> {
const calloutsSet = await this.calloutsSetService.getCalloutsSetOrFail(
calloutsSetInput.id,
Expand All @@ -49,6 +51,9 @@ export class CalloutsSetAuthorizationService {
calloutsSet.authorization,
spaceSettings
);
calloutsSet.authorization.credentialRules.push(
...credentialRulesFromParent
);

if (calloutsSet.callouts) {
for (const callout of calloutsSet.callouts) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { UseGuards } from '@nestjs/common';
import { GraphqlGuard } from '@core/authorization';
import { IProfile } from '@domain/common/profile/profile.interface';
import { IKnowledgeBase } from './knowledge.base.interface';
import { AuthorizationAgentPrivilege, Profiling } from '@common/decorators';
import { AuthorizationAgentPrivilege } from '@common/decorators';
import { Loader } from '@core/dataloader/decorators';
import { KnowledgeBase } from './knowledge.base.entity';
import {
Expand All @@ -19,13 +19,12 @@ import { AuthorizationPrivilege } from '@common/enums/authorization.privilege';
export class KnowledgeBaseResolverFields {
constructor(private knowledgeBaseService: KnowledgeBaseService) {}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ)
@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@UseGuards(GraphqlGuard)
@ResolveField('profile', () => IProfile, {
nullable: false,
description: 'The Profile for describing this KnowledgeBase.',
})
@Profiling.api
async profile(
@Parent() knowledgeBase: IKnowledgeBase,
@Loader(ProfileLoaderCreator, { parentClassRef: KnowledgeBase })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { IKnowledgeBase } from './knowledge.base.interface';
import { RelationshipNotFoundException } from '@common/exceptions/relationship.not.found.exception';
import { LogContext } from '@common/enums/logging.context';
import { CalloutsSetAuthorizationService } from '@domain/collaboration/callouts-set/callouts.set.service.authorization';
import { AuthorizationPrivilege } from '@common/enums';

@Injectable()
export class KnowledgeBaseAuthorizationService {
Expand All @@ -19,7 +20,8 @@ export class KnowledgeBaseAuthorizationService {

public async applyAuthorizationPolicy(
knowledgeBaseInput: IKnowledgeBase,
parentAuthorization: IAuthorizationPolicy | undefined
parentAuthorization: IAuthorizationPolicy | undefined,
knowledgeBaseVisible: boolean
): Promise<IAuthorizationPolicy[]> {
const knowledgeBase =
await this.knowledgeBaseService.getKnowledgeBaseOrFail(
Expand All @@ -46,6 +48,14 @@ export class KnowledgeBaseAuthorizationService {
knowledgeBase.authorization,
parentAuthorization
);
if (knowledgeBaseVisible) {
knowledgeBase.authorization =
this.authorizationPolicyService.appendCredentialRuleAnonymousRegisteredAccess(
knowledgeBase.authorization,
AuthorizationPrivilege.READ,
true
);
}
updatedAuthorizations.push(knowledgeBase.authorization);

const profileAuthorizations =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { IProfile } from '@domain/common/profile';
import { AuthorizationAgentPrivilege, CurrentUser } from '@common/decorators';
import { IAgent } from '@domain/agent/agent';
import { AgentInfo } from '@core/authentication.agent.info/agent.info';
import { AuthorizationService } from '@core/authorization/authorization.service';
import { IAuthorizationPolicy } from '@domain/common/authorization-policy';
import { Loader } from '@core/dataloader/decorators';
import {
Expand All @@ -27,12 +26,9 @@ import { IKnowledgeBase } from '@domain/common/knowledge-base/knowledge.base.int

@Resolver(() => IVirtualContributor)
export class VirtualContributorResolverFields {
constructor(
private authorizationService: AuthorizationService,
private virtualContributorService: VirtualContributorService
) {}
constructor(private virtualContributorService: VirtualContributorService) {}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ)
@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@ResolveField('account', () => IAccount, {
nullable: true,
description: 'The Account of the Virtual Contributor.',
Expand All @@ -52,31 +48,17 @@ export class VirtualContributorResolverFields {
return account;
}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@UseGuards(GraphqlGuard)
@ResolveField('authorization', () => IAuthorizationPolicy, {
nullable: true,
description: 'The Authorization for this Virtual.',
})
async authorization(
@Parent() parent: VirtualContributor,
@CurrentUser() agentInfo: AgentInfo
) {
// Reload to ensure the authorization is loaded
const virtual =
await this.virtualContributorService.getVirtualContributorOrFail(
parent.id
);

this.authorizationService.grantAccessOrFail(
agentInfo,
virtual.authorization,
AuthorizationPrivilege.READ,
`virtual authorization access: ${virtual.id}`
);

return virtual.authorization;
async authorization(@Parent() parent: VirtualContributor) {
return parent.authorization;
}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@ResolveField('profile', () => IProfile, {
nullable: false,
description: 'The profile for this Virtual.',
Expand All @@ -89,18 +71,10 @@ export class VirtualContributorResolverFields {
loader: ILoader<IProfile>
) {
const profile = await loader.load(virtualContributor.id);
// Note: the Virtual profile is public.
// Check if the user can read the profile entity, not the actual Virtual entity
this.authorizationService.grantAccessOrFail(
agentInfo,
profile.authorization,
AuthorizationPrivilege.READ,
`read profile on Virtual: ${profile.displayName}`
);
return profile;
}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ)
@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@ResolveField('agent', () => IAgent, {
nullable: false,
description: 'The Agent representing this User.',
Expand All @@ -113,7 +87,7 @@ export class VirtualContributorResolverFields {
return loader.load(virtualContributor.id);
}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ)
@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@ResolveField('aiPersona', () => IAiPersona, {
nullable: true,
description: 'The AI persona being used by this virtual contributor',
Expand All @@ -127,7 +101,7 @@ export class VirtualContributorResolverFields {
);
}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ)
@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@ResolveField('knowledgeBase', () => IKnowledgeBase, {
nullable: true,
description: 'The KnowledgeBase being used by this virtual contributor',
Expand All @@ -141,7 +115,7 @@ export class VirtualContributorResolverFields {
);
}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ)
@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@ResolveField('provider', () => IContributor, {
nullable: false,
description: 'The Virtual Contributor provider.',
Expand All @@ -152,7 +126,7 @@ export class VirtualContributorResolverFields {
return await this.virtualContributorService.getProvider(virtualContributor);
}

@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ)
@AuthorizationAgentPrivilege(AuthorizationPrivilege.READ_ABOUT)
@ResolveField('status', () => VirtualContributorStatus, {
nullable: false,
description: 'The status of the virtual contributor',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { AiPersonaAuthorizationService } from '../ai-persona/ai.persona.service.
import { KnowledgeBaseAuthorizationService } from '@domain/common/knowledge-base/knowledge.base.service.authorization';
import { ICredentialDefinition } from '@domain/agent/credential/credential.definition.interface';
import { PlatformAuthorizationPolicyService } from '@platform/authorization/platform.authorization.policy.service';
import { SearchVisibility } from '@common/enums/search.visibility';

@Injectable()
export class VirtualContributorAuthorizationService {
Expand Down Expand Up @@ -69,13 +70,16 @@ export class VirtualContributorAuthorizationService {
virtual.authorization,
accountAdminCredential
);
// Allow everyone to see the VirtualContributor for now; note do not cascade to children
virtual.authorization =
this.authorizationPolicyService.appendCredentialRuleAnonymousRegisteredAccess(
virtual.authorization,
AuthorizationPrivilege.READ,
false
);

// Allow everyone to Read About the VirtualContributor that are not hidden;
if (virtual.searchVisibility !== SearchVisibility.HIDDEN) {
virtual.authorization =
this.authorizationPolicyService.appendCredentialRuleAnonymousRegisteredAccess(
virtual.authorization,
AuthorizationPrivilege.READ_ABOUT,
true
);
}

updatedAuthorizations.push(virtual.authorization);

Expand Down Expand Up @@ -122,7 +126,8 @@ export class VirtualContributorAuthorizationService {
const knowledgeBaseAuthorizations =
await this.knowledgeBaseAuthorizations.applyAuthorizationPolicy(
virtual.knowledgeBase,
knowledgeBaseParentAuthorization
knowledgeBaseParentAuthorization,
virtual.settings.privacy.knowledgeBaseContentVisible
);
updatedAuthorizations.push(...knowledgeBaseAuthorizations);

Expand Down Expand Up @@ -206,11 +211,6 @@ export class VirtualContributorAuthorizationService {
);
newRules.push(globalSupportManage);

const globalCommunityRead =
this.createCredentialRuleAnonymousRegisteredUserRead();
globalCommunityRead.cascade = false;
newRules.push(globalCommunityRead);

return this.authorizationPolicyService.appendCredentialAuthorizationRules(
updatedAuthorization,
newRules
Expand Down
10 changes: 10 additions & 0 deletions src/services/api/lookup-by-name/lookup.by.name.resolver.fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export class LookupByNameResolverFields {
return user.id;
}

@UseGuards(GraphqlGuard)
@ResolveField(() => String, {
nullable: true,
description: 'Lookup the ID of the specified Organization using a NameID',
Expand All @@ -127,19 +128,28 @@ export class LookupByNameResolverFields {
return organization.id;
}

@UseGuards(GraphqlGuard)
@ResolveField(() => String, {
nullable: true,
description:
'Lookup the ID of the specified Virtual Contributor using a NameID',
})
async virtualContributor(
@CurrentUser() agentInfo: AgentInfo,
@Args('NAMEID', { type: () => NameID }) nameid: string
): Promise<string> {
const virtualContributor =
await this.virtualContributorLookupService.getVirtualContributorByNameIdOrFail(
nameid
);

this.authorizationService.grantAccessOrFail(
agentInfo,
virtualContributor.authorization,
AuthorizationPrivilege.READ_ABOUT,
`lookup virtual contributor by NameID: ${virtualContributor.id}`
);

return virtualContributor.id;
}

Expand Down
2 changes: 1 addition & 1 deletion src/services/api/lookup/lookup.resolver.fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export class LookupResolverFields {
this.authorizationService.grantAccessOrFail(
agentInfo,
virtualContributor.authorization,
AuthorizationPrivilege.READ,
AuthorizationPrivilege.READ_ABOUT,
`lookup VirtualContributor: ${virtualContributor.id}`
);
return virtualContributor;
Expand Down