Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ to get a new pair of tokens.
fairpost: help
fairpost: @userid get-user
fairpost: @userid get-feed
fairpost: @userid get-fields --model=user|feed|platform|source|post [--platform=xxx]
fairpost: @userid get-platform --platform=xxx
fairpost: @userid put-platform --platform=xxx << payload
fairpost: @userid edit-platform --platform=xxx (cli only)
Expand Down
2 changes: 2 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const COMMAND = process.argv[2]?.includes("@")
const DRY_RUN = !!getOption("dry-run");
const OPERATOR = (getOption("operator") as string) ?? "admin";
const PASSWORD = (getOption("password") as string) ?? undefined;
const MODEL = (getOption("model") as string) ?? undefined;
const PLATFORMS =
((getOption("platforms") as string)?.split(",") as PlatformId[]) ?? undefined;
const SOURCES = (getOption("sources") as string)?.split(",") ?? undefined;
Expand Down Expand Up @@ -94,6 +95,7 @@ async function execute(command: string): Promise<string> {
dryrun: DRY_RUN,
user: USER,
password: PASSWORD,
model: MODEL,
platforms: PLATFORMS,
platform: PLATFORM,
sources: SOURCES,
Expand Down
3 changes: 2 additions & 1 deletion src/mappers/FeedMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Feed from "../models/Feed.ts";

export default class FeedMapper extends AbstractMapper<FeedDto> {
private feed: Feed;
mapping: FieldMapping = {
static feedMapping: FieldMapping = {
model: {
type: "string",
label: "Model",
Expand Down Expand Up @@ -38,6 +38,7 @@ export default class FeedMapper extends AbstractMapper<FeedDto> {
required: false,
},
};
mapping = FeedMapper.feedMapping;

constructor(feed: Feed) {
super(feed.user);
Expand Down
6 changes: 4 additions & 2 deletions src/mappers/PlatformMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Platform from "../models/Platform.ts";

export default class PlatformMapper extends AbstractMapper<PlatformDto> {
private platform: Platform;
mapping: FieldMapping = {
private static platformMapping: FieldMapping = {
model: {
type: "string",
label: "Model",
Expand All @@ -31,9 +31,11 @@ export default class PlatformMapper extends AbstractMapper<PlatformDto> {
set: ["managePlatforms"],
},
// more fields from platform.settings
// added in constructor
// added in mapper constructor
};

mapping = structuredClone(PlatformMapper.platformMapping);

constructor(platform: Platform) {
super(platform.user);
this.platform = platform;
Expand Down
5 changes: 3 additions & 2 deletions src/mappers/PostMapper.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import AbstractMapper from "./AbstractMapper.ts";
import { PostDto, FieldMapping, FileInfo } from "../types/index.ts";
import { PostDto, FileInfo, FieldMapping } from "../types/index.ts";
import Operator from "../models/Operator.ts";
import Post from "../models/Post.ts";

export default class PostMapper extends AbstractMapper<PostDto> {
private post: Post;
mapping: FieldMapping = {
static postMapping: FieldMapping = {
model: {
type: "string",
label: "Model",
Expand Down Expand Up @@ -121,6 +121,7 @@ export default class PostMapper extends AbstractMapper<PostDto> {
set: ["none"],
},
};
mapping = PostMapper.postMapping;

constructor(post: Post) {
super(post.platform.user);
Expand Down
5 changes: 3 additions & 2 deletions src/mappers/SourceMapper.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import AbstractMapper from "./AbstractMapper.ts";
import { SourceDto, FieldMapping, FileInfo } from "../types/index.ts";
import { SourceDto, FileInfo, FieldMapping } from "../types/index.ts";
import Operator from "../models/Operator.ts";
import Source from "../models/Source.ts";

export default class SourceMapper extends AbstractMapper<SourceDto> {
private source: Source;
mapping: FieldMapping = {
static sourceMapping: FieldMapping = {
model: {
type: "string",
label: "Model",
Expand Down Expand Up @@ -49,6 +49,7 @@ export default class SourceMapper extends AbstractMapper<SourceDto> {
set: ["manageSources"],
},
};
mapping = SourceMapper.sourceMapping;

constructor(source: Source) {
super(source.feed.user);
Expand Down
3 changes: 2 additions & 1 deletion src/mappers/UserMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { UserDto, FieldMapping } from "../types/index.ts";
import Operator from "../models/Operator.ts";

export default class UserMapper extends AbstractMapper<UserDto> {
mapping: FieldMapping = {
static userMapping: FieldMapping = {
model: {
type: "string",
label: "Model",
Expand Down Expand Up @@ -39,6 +39,7 @@ export default class UserMapper extends AbstractMapper<UserDto> {
required: false,
},
};
mapping = UserMapper.userMapping;

/**
* Return a dto based on the operator and operation
Expand Down
69 changes: 69 additions & 0 deletions src/models/Operator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import User from "./User.ts";
import { FieldMapping, ProcessedFieldMapping } from "../types/index.ts";
import Platform from "../models/Platform.ts";
import UserMapper from "../mappers/UserMapper.ts";
import FeedMapper from "../mappers/FeedMapper.ts";
import SourceMapper from "../mappers/SourceMapper.ts";
import PostMapper from "../mappers/PostMapper.ts";

/**
* Operator - represents the user executing an operation or command.
Expand Down Expand Up @@ -79,4 +85,67 @@ export default class Operator {
//user?.log.info(permissions);
return permissions;
}

public getFieldMapping(
user: User,
model: string,
instance?: object,
): ProcessedFieldMapping {
let rawFieldMapping: FieldMapping | undefined = undefined;
let processedFieldMapping: ProcessedFieldMapping = {};
switch (model) {
case "user":
rawFieldMapping = UserMapper.userMapping;
break;

case "feed":
rawFieldMapping = FeedMapper.feedMapping;
break;

case "source":
rawFieldMapping = SourceMapper.sourceMapping;
break;

case "platform":
if (!instance || !(instance instanceof Platform)) {
throw user.log.error(
"Operator.getFieldMapping",
"Platform is required",
);
}
const platform = instance as Platform;
rawFieldMapping = platform.mapper.mapping;
break;

case "post":
rawFieldMapping = PostMapper.postMapping;
break;
}
if (!rawFieldMapping) {
throw user.log.error("Operator.getFieldMapping: no such mapping", model);
}
const permissions = this.getPermissions(user);
for (const fieldName of Object.keys(rawFieldMapping)) {
const rawField = rawFieldMapping[fieldName];
const processedField = { ...rawField, get: true, set: true };
for (const operation of ["get", "set"] as const) {
if (rawField[operation].includes("any"))
processedField[operation] = true;
else if (rawField[operation].includes("none"))
processedField[operation] = false;
else if (
rawField[operation].some(
(permission) =>
permission in permissions &&
permissions[permission as keyof typeof permissions],
)
)
processedField[operation] = true;
}
if (processedField["get"]) {
processedFieldMapping[fieldName] = processedField;
}
}
return processedFieldMapping;
}
}
3 changes: 1 addition & 2 deletions src/models/Platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class Platform {
defaultBody: string = "Fairpost feed";
assetsFolder: string = "_fairpost";
postFileName: string = "post.json";
mapper: PlatformMapper;
mapper!: PlatformMapper; // child *must* set this
settings: FieldMapping = {};
interval: number;
constructor(user: User) {
Expand All @@ -32,7 +32,6 @@ export default class Platform {
this.interval = Number(
this.user.data.get("settings", "FEED_INTERVAL", "7"),
);
this.mapper = new PlatformMapper(this);
}

/**
Expand Down
36 changes: 35 additions & 1 deletion src/services/Fairpost.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import log4js from "log4js";
import log4jsConfig from "../config/log4js.json" with { type: "json" };

import { CommandArguments, CombinedResult } from "../types/index.ts";
import {
CommandArguments,
CombinedResult,
ProcessedFieldMapping,
} from "../types/index.ts";
import { PlatformId } from "../platforms/index.ts";
import {
FeedDto,
Expand All @@ -20,6 +24,7 @@ import Operator from "../models/Operator.ts";
import User from "../models/User.ts";

type FairpostOutput =
| ProcessedFieldMapping
| FeedDto
| PlatformDto
| PostDto
Expand Down Expand Up @@ -188,6 +193,34 @@ class Fairpost {
}
*/

case "get-fields": {
if (!permissions.manageAccount) {
throw new Error("Missing permissions for command " + command);
}
if (!user) {
throw new Error("user is required for command " + command);
}
if (!args.model) {
throw user.log.error(
"CommandHandler " + command,
"Missing argument: model",
);
}
let instance: object | undefined = undefined;
if (args.model === "platform") {
if (!args.platform) {
throw user.log.error(
"CommandHandler " + command,
"Missing argument: platform",
);
}
instance = user.getPlatform(args.platform);
}

output = operator.getFieldMapping(user, args.model, instance);
break;
}

case "refresh-token": {
if (!permissions.manageAccount) {
throw new Error("Missing permissions for command " + command);
Expand Down Expand Up @@ -972,6 +1005,7 @@ class Fairpost {
`${cmd} help`,
`${cmd} @userid get-user`,
`${cmd} @userid get-feed`,
`${cmd} @userid get-fields --model=user|feed|platform|source|post [--platform=xxx]`,
`${cmd} @userid get-platform --platform=xxx`,
`${cmd} @userid put-platform --platform=xxx << payload`,
`${cmd} @userid edit-platform --platform=xxx (cli only)`,
Expand Down
2 changes: 2 additions & 0 deletions src/services/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export default class Server {

// read other params from query
const password = parsed.searchParams.get("password") || undefined;
const model = parsed.searchParams.get("model") || undefined;
const dryrun = parsed.searchParams.get("dry-run") === "true";
const date = parsed.searchParams.get("date");
const post = parsed.searchParams.get("post");
Expand Down Expand Up @@ -112,6 +113,7 @@ export default class Server {
const args = {
password: password,
dryrun: dryrun || undefined,
model: model,
platforms: platforms,
platform: platform,
sources: sources,
Expand Down
1 change: 1 addition & 0 deletions src/types/CommandArguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default interface CommandArguments {
dryrun?: boolean;
user?: string;
password?: string;
model?: string;
platforms?: PlatformId[];
platform?: PlatformId;
sources?: string[];
Expand Down
9 changes: 9 additions & 0 deletions src/types/FieldMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,12 @@ export default interface FieldMapping {
default?: string | string[] | number | boolean | Date | object;
};
}

// after applying operator and user, get and set
// can be represented by simple booleans:
export interface ProcessedFieldMapping {
[field: string]: Omit<FieldMapping[string], "get" | "set"> & {
get: boolean;
set: boolean;
};
}
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type { default as CommandArguments } from "./CommandArguments.ts";
export type { default as CombinedResult } from "./CombinedResult.ts";
export type { default as FieldMapping } from "./FieldMapping.ts";
export type { ProcessedFieldMapping } from "./FieldMapping.ts";
export type { default as Dto } from "./Dto.ts";
export type { default as FeedDto } from "./FeedDto.ts";
export { default as FileGroup } from "./FileGroup.ts";
Expand Down