Merge branch 'improving-auth' of OpenServer/OpenAuth_server into master
This commit is contained in:
commit
043aca26da
@ -24,14 +24,16 @@ PermissionRoute.route("/")
|
||||
* @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) => {
|
||||
.get(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let query = {};
|
||||
if (req.query.client) {
|
||||
query = { client: new ObjectID(req.query.client) }
|
||||
query = { client: new ObjectID(req.query.client) };
|
||||
}
|
||||
let permission = await Permission.find(query);
|
||||
res.json(permission);
|
||||
}))
|
||||
let permissions = await Permission.find(query);
|
||||
res.json(permissions);
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {post} /admin/permission
|
||||
* @apiName AdminAddPermission
|
||||
@ -48,8 +50,11 @@ PermissionRoute.route("/")
|
||||
* @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({
|
||||
.post(
|
||||
verify(
|
||||
{
|
||||
client: {
|
||||
type: Types.STRING
|
||||
},
|
||||
@ -58,20 +63,32 @@ PermissionRoute.route("/")
|
||||
},
|
||||
description: {
|
||||
type: Types.STRING
|
||||
},
|
||||
type: {
|
||||
type: Types.ENUM,
|
||||
values: ["user", "client"]
|
||||
}
|
||||
}, true), promiseMiddleware(async (req, res) => {
|
||||
},
|
||||
true
|
||||
),
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let client = await Client.findById(req.body.client);
|
||||
if (!client) {
|
||||
throw new RequestError("Client not found", HttpStatusCode.BAD_REQUEST);
|
||||
throw new RequestError(
|
||||
"Client not found",
|
||||
HttpStatusCode.BAD_REQUEST
|
||||
);
|
||||
}
|
||||
let permission = Permission.new({
|
||||
description: req.body.description,
|
||||
name: req.body.name,
|
||||
client: client._id
|
||||
client: client._id,
|
||||
grant_type: req.body.type
|
||||
});
|
||||
await Permission.save(permission);
|
||||
res.json(permission);
|
||||
}))
|
||||
})
|
||||
)
|
||||
/**
|
||||
* @api {delete} /admin/permission
|
||||
* @apiName AdminDeletePermission
|
||||
@ -83,10 +100,12 @@ PermissionRoute.route("/")
|
||||
*
|
||||
* @apiSuccess {Boolean} success
|
||||
*/
|
||||
.delete(promiseMiddleware(async (req, res) => {
|
||||
.delete(
|
||||
promiseMiddleware(async (req, res) => {
|
||||
let { id } = req.query;
|
||||
await Permission.delete(id);
|
||||
res.json({ success: true });
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
export default PermissionRoute;
|
@ -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
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
98
src/api/client/permissions.ts
Normal file
98
src/api/client/permissions.ts
Normal file
@ -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
|
||||
});
|
||||
}
|
||||
);
|
@ -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<void>[] = [];
|
||||
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);
|
||||
})
|
||||
|
@ -7,8 +7,10 @@
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
|
||||
<script src="https://unpkg.com/popper.js@1.12.6/dist/umd/popper.js" type="text/javascript"></script>
|
||||
<script src="https://unpkg.com/bootstrap-material-design@4.1.1/dist/js/bootstrap-material-design.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js" type="text/javascript"></script>
|
||||
<script src="https://unpkg.com/bootstrap-material-design@4.1.1/dist/js/bootstrap-material-design.js"
|
||||
type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js"
|
||||
type="text/javascript"></script>
|
||||
<script>
|
||||
$(document).ready(() => $('body').bootstrapMaterialDesign())
|
||||
</script>
|
||||
@ -251,6 +253,7 @@
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Description</th>
|
||||
<th scope="col" style="width: 10ch">Type</th>
|
||||
<th scope="col" style="width: 2.5rem"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -260,6 +263,7 @@
|
||||
<td>\{{ _id }}</td>
|
||||
<td>\{{ name }}</td>
|
||||
<td>\{{ description }}</td>
|
||||
<td>\{{ grant_type }}</td>
|
||||
<td style="padding: 0.25em">
|
||||
<button style="border: 0; background-color: rgba(0, 0, 0, 0); padding: 0; text-align: center;" onclick="deletePermission('\{{_id}}')">
|
||||
<i class="material-icons" style="font-size: 2rem; display: inline">
|
||||
@ -280,8 +284,16 @@
|
||||
<input type="text" class="form-control" id="name_input" name=name value="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for=name class="bmd-label-floating">Description</label>
|
||||
<input type="text" class="form-control" id=name name=description value="">
|
||||
<label for=description class="bmd-label-floating">Description</label>
|
||||
<input type="text" class="form-control" id=description name=description value="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for=type class="bmd-label-floating">Type</label>
|
||||
|
||||
<select type="text" class="form-control" id=type name=type>
|
||||
<option value="user">User granted</option>
|
||||
<option value="client">Client granted</option>
|
||||
</select>
|
||||
</div>
|
||||
<span class="form-group bmd-form-group">
|
||||
<!-- needed to match padding for floating labels -->
|
||||
|
Loading…
Reference in New Issue
Block a user