123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- import async from "async";
- import config from "config";
- // eslint-disable-next-line
- import moduleManager from "../../index";
- const permissions = {};
- permissions.dj = {
- "stations.autofill": true,
- "stations.blacklist": true,
- "stations.index": true,
- "stations.playback.toggle": true,
- "stations.queue.remove": true,
- "stations.queue.reposition": true,
- "stations.queue.reset": true,
- "stations.request": true,
- "stations.skip": true,
- "stations.view": true,
- "stations.view.manage": true
- };
- permissions.owner = {
- ...permissions.dj,
- "stations.djs.add": true,
- "stations.djs.remove": true,
- "stations.remove": true,
- "stations.update": true
- };
- permissions.moderator = {
- ...permissions.owner,
- "admin.view": true,
- "admin.view.import": true,
- "admin.view.news": true,
- "admin.view.playlists": true,
- "admin.view.punishments": true,
- "admin.view.reports": true,
- "admin.view.songs": true,
- "admin.view.stations": true,
- "admin.view.users": true,
- "admin.view.youtubeVideos": true,
- "apis.searchDiscogs": config.get("apis.discogs.enabled"),
- "news.create": true,
- "news.update": true,
- "playlists.create.admin": true,
- "playlists.get": true,
- "playlists.update.displayName": true,
- "playlists.update.privacy": true,
- "playlists.songs.add": true,
- "playlists.songs.remove": true,
- "playlists.songs.reposition": true,
- "playlists.view.others": true,
- "punishments.banIP": true,
- "punishments.get": true,
- "reports.get": true,
- "reports.update": true,
- "songs.create": true,
- "songs.get": true,
- "songs.update": true,
- "songs.verify": true,
- "stations.create.official": true,
- "stations.index": false,
- "stations.index.other": true,
- "stations.remove": false,
- "users.get": true,
- "users.ban": true,
- "users.requestPasswordReset": config.get("mail.enabled"),
- "users.resendVerifyEmail": config.get("mail.enabled"),
- "users.update": true,
- "youtube.requestSetAdmin": true,
- ...(config.get("experimental.soundcloud")
- ? {
- "admin.view.soundcloudTracks": true,
- "admin.view.soundcloud": true,
- "soundcloud.getArtist": true
- }
- : {}),
- ...(config.get("experimental.spotify")
- ? {
- "admin.view.spotify": true,
- "spotify.getTracksFromMediaSources": true,
- "spotify.getAlbumsFromIds": true,
- "spotify.getArtistsFromIds": true,
- "spotify.getAlternativeArtistSourcesForArtists": true,
- "spotify.getAlternativeAlbumSourcesForAlbums": true,
- "spotify.getAlternativeMediaSourcesForTracks": true,
- "admin.view.youtubeChannels": true,
- "youtube.getChannel": true
- }
- : {})
- };
- permissions.admin = {
- ...permissions.moderator,
- "admin.view.dataRequests": true,
- "admin.view.statistics": true,
- "admin.view.youtube": true,
- "dataRequests.resolve": true,
- "media.recalculateAllRatings": true,
- "media.removeImportJobs": true,
- "news.remove": true,
- "playlists.clearAndRefill": true,
- "playlists.clearAndRefillAll": true,
- "playlists.createMissing": true,
- "playlists.deleteOrphaned": true,
- "playlists.removeAdmin": true,
- "playlists.requestOrphanedPlaylistSongs": true,
- "punishments.deactivate": true,
- "reports.remove": true,
- "songs.remove": true,
- "songs.updateAll": true,
- "stations.clearEveryStationQueue": true,
- "stations.remove": true,
- "users.remove": true,
- "users.remove.sessions": true,
- "users.update.restricted": true,
- "utils.getModules": true,
- "youtube.getApiRequest": true,
- "youtube.getMissingVideos": true,
- "youtube.resetStoredApiRequests": true,
- "youtube.removeStoredApiRequest": true,
- "youtube.removeVideos": true,
- "youtube.updateVideosV1ToV2": true,
- ...(config.get("experimental.soundcloud")
- ? {
- "soundcloud.fetchNewApiKey": true,
- "soundcloud.testApiKey": true
- }
- : {}),
- ...(config.get("experimental.spotify")
- ? {
- "youtube.getMissingChannels": true
- }
- : {})
- };
- export const hasPermission = async (permission, session, stationId) => {
- const CacheModule = moduleManager.modules.cache;
- const DBModule = moduleManager.modules.db;
- const StationsModule = moduleManager.modules.stations;
- const UtilsModule = moduleManager.modules.utils;
- const userModel = await DBModule.runJob("GET_MODEL", { modelName: "user" }, this);
- return new Promise((resolve, reject) => {
- async.waterfall(
- [
- next => {
- let userId;
- if (typeof session === "object") {
- if (session.userId) userId = session.userId;
- else
- CacheModule.runJob(
- "HGET",
- {
- table: "sessions",
- key: session.sessionId
- },
- this
- )
- .then(_session => {
- if (_session && _session.userId) userId = _session.userId;
- })
- .catch(next);
- } else userId = session;
- if (!userId) return next("User ID required.");
- return userModel.findOne({ _id: userId }, next);
- },
- (user, next) => {
- if (!user) return next("Login required.");
- if (!stationId) return next(null, [user.role]);
- return StationsModule.runJob("GET_STATION", { stationId }, this)
- .then(station => {
- if (!station) return next("Station not found.");
- if (station.type === "community" && station.owner === user._id.toString())
- return next(null, [user.role, "owner"]);
- if (station.djs.find(dj => dj === user._id.toString()))
- return next(null, [user.role, "dj"]);
- if (user.role === "admin" || user.role === "moderator") return next(null, [user.role]);
- return next("Invalid permissions.");
- })
- .catch(next);
- },
- (roles, next) => {
- if (!roles) return next("Role required.");
- let permissionFound;
- roles.forEach(role => {
- if (permissions[role] && permissions[role][permission]) permissionFound = true;
- });
- if (permissionFound) return next();
- return next("Insufficient permissions.");
- }
- ],
- async err => {
- const userId = typeof session === "object" ? session.userId || session.sessionId : session;
- if (err) {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- UtilsModule.log(
- "INFO",
- "HAS_PERMISSION",
- `User "${userId}" does not have required permission "${permission}". "${err}"`
- );
- return reject(err);
- }
- UtilsModule.log(
- "INFO",
- "HAS_PERMISSION",
- `User "${userId}" has required permission "${permission}".`,
- false
- );
- return resolve();
- }
- );
- });
- };
- export const useHasPermission = (options, destination) =>
- async function useHasPermission(session, ...args) {
- const UtilsModule = moduleManager.modules.utils;
- const permission = typeof options === "object" ? options.permission : options;
- const cb = args[args.length - 1];
- async.waterfall(
- [
- next => {
- if (!session || !session.sessionId) return next("Login required.");
- return hasPermission(permission, session)
- .then(() => next())
- .catch(next);
- }
- ],
- async err => {
- if (err) {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- this.log(
- "INFO",
- "USE_HAS_PERMISSION",
- `User "${session.userId}" does not have required permission "${permission}". "${err}"`
- );
- return cb({ status: "error", message: err });
- }
- this.log(
- "INFO",
- "USE_HAS_PERMISSION",
- `User "${session.userId}" has required permission "${permission}".`,
- false
- );
- return destination.apply(this, [session].concat(args));
- }
- );
- };
- export const getUserPermissions = async (session, stationId) => {
- const CacheModule = moduleManager.modules.cache;
- const DBModule = moduleManager.modules.db;
- const StationsModule = moduleManager.modules.stations;
- const UtilsModule = moduleManager.modules.utils;
- const userModel = await DBModule.runJob("GET_MODEL", { modelName: "user" }, this);
- return new Promise((resolve, reject) => {
- async.waterfall(
- [
- next => {
- let userId;
- if (typeof session === "object") {
- if (session.userId) userId = session.userId;
- else
- CacheModule.runJob(
- "HGET",
- {
- table: "sessions",
- key: session.sessionId
- },
- this
- )
- .then(_session => {
- if (_session && _session.userId) userId = _session.userId;
- })
- .catch(next);
- } else userId = session;
- if (!userId) return next("User ID required.");
- return userModel.findOne({ _id: userId }, next);
- },
- (user, next) => {
- if (!user) return next("Login required.");
- if (!stationId) return next(null, [user.role]);
- return StationsModule.runJob("GET_STATION", { stationId }, this)
- .then(station => {
- if (!station) return next("Station not found.");
- if (station.type === "community" && station.owner === user._id.toString())
- return next(null, [user.role, "owner"]);
- if (station.djs.find(dj => dj === user._id.toString()))
- return next(null, [user.role, "dj"]);
- if (user.role === "admin" || user.role === "moderator") return next(null, [user.role]);
- return next("Invalid permissions.");
- })
- .catch(next);
- },
- (roles, next) => {
- if (!roles) return next("Role required.");
- let rolePermissions = {};
- roles.forEach(role => {
- if (permissions[role]) rolePermissions = { ...rolePermissions, ...permissions[role] };
- });
- return next(null, rolePermissions);
- }
- ],
- async (err, rolePermissions) => {
- const userId = typeof session === "object" ? session.userId || session.sessionId : session;
- if (err) {
- err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
- UtilsModule.log(
- "INFO",
- "GET_USER_PERMISSIONS",
- `Failed to get permissions for user "${userId}". "${err}"`
- );
- return reject(err);
- }
- UtilsModule.log("INFO", "GET_USER_PERMISSIONS", `Fetched permissions for user "${userId}".`, false);
- return resolve(rolePermissions);
- }
- );
- });
- };
|