Alex Mikhalev
7 years ago
11 changed files with 164 additions and 66 deletions
@ -1,52 +0,0 @@
@@ -1,52 +0,0 @@
|
||||
import PromiseRouter from "express-promise-router"; |
||||
import { serialize} from "serializr"; |
||||
|
||||
import ApiError from "@common/ApiError"; |
||||
import { ErrorCode } from "@common/ErrorCode"; |
||||
import * as schema from "@common/sprinklersRpc/schema"; |
||||
import { ServerState } from "../state"; |
||||
import { authentication, verifyAuthorization } from "./authentication"; |
||||
|
||||
export default function createApi(state: ServerState) { |
||||
const router = PromiseRouter(); |
||||
|
||||
router.get("/devices/:deviceId", verifyAuthorization(), (req, res) => { |
||||
// TODO: authorize device
|
||||
const device = state.mqttClient.getDevice(req.params.deviceId); |
||||
const j = serialize(schema.sprinklersDevice, device); |
||||
res.send(j); |
||||
}); |
||||
|
||||
// router.post("/devices/register", verifyAuthorization({
|
||||
// type: "device_reg",
|
||||
// }), (req, res) => {
|
||||
// res.json({ data: "device registered" });
|
||||
// });
|
||||
|
||||
router.get("/users", verifyAuthorization(), (req, res) => { |
||||
state.database.users.find() |
||||
.then((users) => { |
||||
res.json({ |
||||
data: users, |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
router.get("/api/users/:username", (req, res, next) => { |
||||
const { username } = req.params; |
||||
state.database.users.findByUsername(username) |
||||
.then((user) => { |
||||
if (!user) { |
||||
throw new ApiError(`user ${username} does not exist`, ErrorCode.NotFound); |
||||
} |
||||
res.json({ |
||||
data: user, |
||||
}); |
||||
}) |
||||
.catch(next); |
||||
}); |
||||
|
||||
router.use("/", authentication(state)); |
||||
|
||||
return router; |
||||
} |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
import PromiseRouter from "express-promise-router"; |
||||
import { serialize} from "serializr"; |
||||
|
||||
import ApiError from "@common/ApiError"; |
||||
import { ErrorCode } from "@common/ErrorCode"; |
||||
import * as schema from "@common/sprinklersRpc/schema"; |
||||
import { AccessOrRefreshToken } from "@common/TokenClaims"; |
||||
import { verifyAuthorization } from "@server/express/authentication"; |
||||
import { ServerState } from "@server/state"; |
||||
|
||||
export function devices(state: ServerState) { |
||||
const router = PromiseRouter(); |
||||
|
||||
router.get("/:deviceId", verifyAuthorization(), async (req, res) => { |
||||
const token = req.token! as AccessOrRefreshToken; |
||||
const userId = token.aud; |
||||
const deviceId = req.params.deviceId; |
||||
const userDevice = await state.database.sprinklersDevices |
||||
.findUserDevice(userId, deviceId); |
||||
if (!userDevice) { |
||||
throw new ApiError("User does not have access to the specified device", ErrorCode.NoPermission); |
||||
} |
||||
const device = state.mqttClient.getDevice(req.params.deviceId); |
||||
const j = serialize(schema.sprinklersDevice, device); |
||||
res.send(j); |
||||
}); |
||||
|
||||
router.post("/register", verifyAuthorization({ |
||||
type: "device_reg", |
||||
}), async (req, res) => { |
||||
|
||||
}); |
||||
|
||||
return router; |
||||
} |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
import PromiseRouter from "express-promise-router"; |
||||
|
||||
import ApiError from "@common/ApiError"; |
||||
import { ErrorCode } from "@common/ErrorCode"; |
||||
import { authentication } from "@server/express/authentication"; |
||||
import { ServerState } from "@server/state"; |
||||
import { devices } from "./devices"; |
||||
import { users } from "./users"; |
||||
|
||||
export default function createApi(state: ServerState) { |
||||
const router = PromiseRouter(); |
||||
|
||||
router.use("/devices", devices(state)); |
||||
router.use("/users", users(state)); |
||||
router.use("/token", authentication(state)); |
||||
|
||||
router.use("*", (req, res) => { |
||||
throw new ApiError("API endpoint not found", ErrorCode.NotFound); |
||||
}); |
||||
|
||||
return router; |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
import PromiseRouter from "express-promise-router"; |
||||
|
||||
import ApiError from "@common/ApiError"; |
||||
import { ErrorCode } from "@common/ErrorCode"; |
||||
import { User } from "@server/entities"; |
||||
import { verifyAuthorization } from "@server/express/authentication"; |
||||
import { ServerState } from "@server/state"; |
||||
|
||||
export function users(state: ServerState) { |
||||
const router = PromiseRouter(); |
||||
|
||||
router.use(verifyAuthorization()); |
||||
|
||||
async function getUser(params: { username: string }): Promise<User> { |
||||
const { username } = params; |
||||
const user = await state.database.users |
||||
.findByUsername(username, { devices: true }); |
||||
if (!user) { |
||||
throw new ApiError(`user ${username} does not exist`, ErrorCode.NotFound); |
||||
} |
||||
return user; |
||||
} |
||||
|
||||
router.get("/", (req, res) => { |
||||
state.database.users.findAll() |
||||
.then((users) => { |
||||
res.json({ |
||||
data: users, |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
router.get("/:username", async (req, res) => { |
||||
const user = await getUser(req.params); |
||||
res.json({ |
||||
data: user, |
||||
}); |
||||
}); |
||||
|
||||
router.get("/:username/devices", async (req, res) => { |
||||
const user = await getUser(req.params); |
||||
res.json({ |
||||
data: user.devices, |
||||
}); |
||||
}); |
||||
|
||||
return router; |
||||
} |
@ -1,10 +1,33 @@
@@ -1,10 +1,33 @@
|
||||
import { EntityRepository, Repository } from "typeorm"; |
||||
|
||||
import { SprinklersDevice } from "../entities"; |
||||
import { SprinklersDevice, User } from "../entities"; |
||||
|
||||
@EntityRepository(SprinklersDevice) |
||||
export class SprinklersDeviceRepository extends Repository<SprinklersDevice> { |
||||
findByName(name: string) { |
||||
return this.findOne({ name }); |
||||
} |
||||
|
||||
async userHasAccess(userId: number, deviceId: number): Promise<boolean> { |
||||
const count = await this.manager |
||||
.createQueryBuilder(User, "user") |
||||
.innerJoinAndSelect("user.devices", "sprinklers_device", |
||||
"user.id = :userId AND sprinklers_device.id = :deviceId", |
||||
{ userId, deviceId }) |
||||
.getCount(); |
||||
return count > 0; |
||||
} |
||||
|
||||
async findUserDevice(userId: number, deviceId: number): Promise<SprinklersDevice | null> { |
||||
const user = await this.manager |
||||
.createQueryBuilder(User, "user") |
||||
.innerJoinAndSelect("user.devices", "sprinklers_device", |
||||
"user.id = :userId AND sprinklers_device.id = :deviceId", |
||||
{ userId, deviceId }) |
||||
.getOne(); |
||||
if (!user) { |
||||
return null; |
||||
} |
||||
return user.devices![0]; |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue