diff --git a/src/api/admin/permission.ts b/src/api/admin/permission.ts index dba905b..140111e 100644 --- a/src/api/admin/permission.ts +++ b/src/api/admin/permission.ts @@ -12,81 +12,100 @@ PermissionRoute.route("/") /** * @api {get} /admin/permission * @apiName AdminGetPermissions - * + * * @apiParam client Optionally filter by client _id - * + * * @apiGroup admin_permission * @apiPermission admin - * + * * @apiSuccess {Object[]} permissions * @apiSuccess {String} permissions._id The ID * @apiSuccess {String} permissions.name Permission name * @apiSuccess {String} permissions.description A description, that makes it clear to the user, what this Permission allows to do * @apiSuccess {String} permissions.client The ID of the owning client */ - .get(promiseMiddleware(async (req, res) => { - let query = {}; - if (req.query.client) { - query = { client: new ObjectID(req.query.client) } - } - let permission = await Permission.find(query); - res.json(permission); - })) + .get( + promiseMiddleware(async (req, res) => { + let query = {}; + if (req.query.client) { + query = { client: new ObjectID(req.query.client) }; + } + let permissions = await Permission.find(query); + res.json(permissions); + }) + ) /** * @api {post} /admin/permission * @apiName AdminAddPermission - * + * * @apiParam client The ID of the owning client * @apiParam name Permission name * @apiParam description A description, that makes it clear to the user, what this Permission allows to do - * + * * @apiGroup admin_permission * @apiPermission admin - * + * * @apiSuccess {Object[]} permissions * @apiSuccess {String} permissions._id The ID * @apiSuccess {String} permissions.name Permission name * @apiSuccess {String} permissions.description A description, that makes it clear to the user, what this Permission allows to do * @apiSuccess {String} permissions.client The ID of the owning client + * @apiSuccess {String} permissions.grant_type The type of the permission. "user" | "client" granted */ - .post(verify({ - client: { - type: Types.STRING - }, - name: { - type: Types.STRING - }, - description: { - type: Types.STRING - } - }, true), promiseMiddleware(async (req, res) => { - let client = await Client.findById(req.body.client); - if (!client) { - throw new RequestError("Client not found", HttpStatusCode.BAD_REQUEST); - } - let permission = Permission.new({ - description: req.body.description, - name: req.body.name, - client: client._id - }); - await Permission.save(permission); - res.json(permission); - })) + .post( + verify( + { + client: { + type: Types.STRING + }, + name: { + type: Types.STRING + }, + description: { + type: Types.STRING + }, + type: { + type: Types.ENUM, + values: ["user", "client"] + } + }, + true + ), + promiseMiddleware(async (req, res) => { + let client = await Client.findById(req.body.client); + if (!client) { + throw new RequestError( + "Client not found", + HttpStatusCode.BAD_REQUEST + ); + } + let permission = Permission.new({ + description: req.body.description, + name: req.body.name, + client: client._id, + grant_type: req.body.type + }); + await Permission.save(permission); + res.json(permission); + }) + ) /** * @api {delete} /admin/permission * @apiName AdminDeletePermission - * + * * @apiParam id The permission ID - * + * * @apiGroup admin_permission * @apiPermission admin - * + * * @apiSuccess {Boolean} success */ - .delete(promiseMiddleware(async (req, res) => { - let { id } = req.query; - await Permission.delete(id); - res.json({ success: true }); - })); + .delete( + promiseMiddleware(async (req, res) => { + let { id } = req.query; + await Permission.delete(id); + res.json({ success: true }); + }) + ); -export default PermissionRoute; \ No newline at end of file +export default PermissionRoute; diff --git a/src/api/client/index.ts b/src/api/client/index.ts index 0eace9d..bfdd014 100644 --- a/src/api/client/index.ts +++ b/src/api/client/index.ts @@ -6,6 +6,7 @@ import { createJWT } from "../../keys"; import Client from "../../models/client"; import RequestError, { HttpStatusCode } from "../../helper/request_error"; import config from "../../config"; +import Mail from "../../models/mail"; const ClientRouter = Router(); @@ -45,10 +46,15 @@ ClientRouter.get("/user", Stacker(GetClientAuthMiddleware(false), GetUserMiddlew })); ClientRouter.get("/account", Stacker(GetClientApiAuthMiddleware(), async (req: Request, res) => { + let mails = await Promise.all(req.user.mails.map(id => Mail.findById(id))); + + let mail = mails.find(e => e.primary) || mails[0]; + res.json({ user: { username: req.user.username, name: req.user.name, + email: mail } }) })); diff --git a/src/api/client/permissions.ts b/src/api/client/permissions.ts new file mode 100644 index 0000000..625cf2f --- /dev/null +++ b/src/api/client/permissions.ts @@ -0,0 +1,98 @@ +import { Request, Response } from "express"; +import Stacker from "../middlewares/stacker"; +import { + ClientAuthMiddleware, + GetClientAuthMiddleware +} from "../middlewares/client"; +import Permission from "../../models/permissions"; +import User from "../../models/user"; + +import RequestError, { HttpStatusCode } from "../../helper/request_error"; +import Grant from "../../models/grants"; +import { ObjectID } from "mongodb"; + +export const GetPermissions = Stacker( + GetClientAuthMiddleware(true), + async (req: Request, res: Response) => { + const { user, permission } = req.query; + + let permissions: { id: string; name: string; description: string }[]; + let users: string[]; + + if (user) { + const grant = await Grant.findOne({ + client: req.client._id, + user: user + }); + + permissions = await Promise.all( + grant.permissions.map(perm => Permission.findById(perm)) + ).then(res => + res + .filter(e => e.grant_type === "client") + .map(e => { + return { + id: e._id.toHexString(), + name: e.name, + description: e.description + }; + }) + ); + } + + if (permission) { + const grants = await Grant.find({ + client: req.client._id, + permissions: new ObjectID(permission) + }); + + users = grants.map(grant => grant.user.toHexString()); + } + + res.json({ permissions, users }); + } +); + +export const PostPermissions = Stacker( + GetClientAuthMiddleware(true), + async (req: Request, res: Response) => { + const { permission, uid } = req.body; + + const user = await User.findOne({ uid }); + if (!user) { + throw new RequestError("User not found!", HttpStatusCode.BAD_REQUEST); + } + + const permissionDoc = await Permission.findById(permission); + if (!permissionDoc || !permissionDoc.client.equals(req.client._id)) { + throw new RequestError( + "Permission not found!", + HttpStatusCode.BAD_REQUEST + ); + } + + let grant = await Grant.findOne({ + client: req.client._id, + user: req.user._id + }); + + if (!grant) { + grant = Grant.new({ + client: req.client._id, + user: req.user._id, + permissions: [] + }); + } + + //TODO: Fix clients getting user data without consent, when a grant is created and no additional permissions are requested, since for now, it is only checked for grant existance to make client access user data + + if (grant.permissions.indexOf(permission) < 0) + grant.permissions.push(permission); + + await Grant.save(grant); + + res.json({ + success: true + }); + } +); diff --git a/src/api/oauth/auth.ts b/src/api/oauth/auth.ts index 22f86ba..52e9ec7 100644 --- a/src/api/oauth/auth.ts +++ b/src/api/oauth/auth.ts @@ -10,6 +10,7 @@ import { randomBytes } from "crypto"; // import { ObjectID } from "bson"; import Grant, { IGrant } from "../../models/grants"; import GetAuthPage from "../../views/authorize"; +import { ObjectID } from "mongodb"; // const AuthRoute = Stacker(GetUserMiddleware(true), async (req: Request, res: Response) => { // let { response_type, client_id, redirect_uri, scope, state, nored } = req.query; @@ -123,8 +124,15 @@ const GetAuthRoute = (view = false) => let proms: PromiseLike[] = []; if (scopes) { for (let perm of scopes.filter(e => e !== "read_user")) { + let oid = undefined; + try { + oid = new ObjectID(perm); + } catch (err) { + Logging.error(err); + continue; + } proms.push( - Permission.findById(perm).then(p => { + Permission.findById(oid).then(p => { if (!p) return Promise.reject(new Error()); permissions.push(p); }) diff --git a/views/src/admin/admin.hbs b/views/src/admin/admin.hbs index a7f82d5..0552f72 100644 --- a/views/src/admin/admin.hbs +++ b/views/src/admin/admin.hbs @@ -7,8 +7,10 @@ - - + + @@ -251,6 +253,7 @@ ID Name Description + Type @@ -260,6 +263,7 @@ \{{ _id }} \{{ name }} \{{ description }} + \{{ grant_type }}