Add video privacy setting
[oweals/peertube.git] / server / controllers / api / users.ts
1 import * as express from 'express'
2
3 import { database as db, CONFIG } from '../../initializers'
4 import { logger, getFormattedObjects, retryTransactionWrapper } from '../../helpers'
5 import {
6   authenticate,
7   ensureUserHasRight,
8   ensureUserRegistrationAllowed,
9   usersAddValidator,
10   usersRegisterValidator,
11   usersUpdateValidator,
12   usersUpdateMeValidator,
13   usersRemoveValidator,
14   usersVideoRatingValidator,
15   usersGetValidator,
16   paginationValidator,
17   setPagination,
18   usersSortValidator,
19   setUsersSort,
20   token,
21   asyncMiddleware
22 } from '../../middlewares'
23 import {
24   UserVideoRate as FormattedUserVideoRate,
25   UserCreate,
26   UserUpdate,
27   UserUpdateMe,
28   UserRole,
29   UserRight
30 } from '../../../shared'
31 import { createUserAuthorAndChannel } from '../../lib'
32 import { UserInstance } from '../../models'
33 import { videosSortValidator } from '../../middlewares/validators/sort'
34 import { setVideosSort } from '../../middlewares/sort'
35
36 const usersRouter = express.Router()
37
38 usersRouter.get('/me',
39   authenticate,
40   asyncMiddleware(getUserInformation)
41 )
42
43 usersRouter.get('/me/videos',
44   authenticate,
45   paginationValidator,
46   videosSortValidator,
47   setVideosSort,
48   setPagination,
49   asyncMiddleware(getUserVideos)
50 )
51
52 usersRouter.get('/me/videos/:videoId/rating',
53   authenticate,
54   usersVideoRatingValidator,
55   asyncMiddleware(getUserVideoRating)
56 )
57
58 usersRouter.get('/',
59   paginationValidator,
60   usersSortValidator,
61   setUsersSort,
62   setPagination,
63   asyncMiddleware(listUsers)
64 )
65
66 usersRouter.get('/:id',
67   usersGetValidator,
68   getUser
69 )
70
71 usersRouter.post('/',
72   authenticate,
73   ensureUserHasRight(UserRight.MANAGE_USERS),
74   usersAddValidator,
75   createUserRetryWrapper
76 )
77
78 usersRouter.post('/register',
79   ensureUserRegistrationAllowed,
80   usersRegisterValidator,
81   asyncMiddleware(registerUser)
82 )
83
84 usersRouter.put('/me',
85   authenticate,
86   usersUpdateMeValidator,
87   asyncMiddleware(updateMe)
88 )
89
90 usersRouter.put('/:id',
91   authenticate,
92   ensureUserHasRight(UserRight.MANAGE_USERS),
93   usersUpdateValidator,
94   asyncMiddleware(updateUser)
95 )
96
97 usersRouter.delete('/:id',
98   authenticate,
99   ensureUserHasRight(UserRight.MANAGE_USERS),
100   usersRemoveValidator,
101   asyncMiddleware(removeUser)
102 )
103
104 usersRouter.post('/token', token, success)
105 // TODO: Once https://github.com/oauthjs/node-oauth2-server/pull/289 is merged, implement revoke token route
106
107 // ---------------------------------------------------------------------------
108
109 export {
110   usersRouter
111 }
112
113 // ---------------------------------------------------------------------------
114
115 async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
116   const user = res.locals.oauth.token.User
117   const resultList = await db.Video.listUserVideosForApi(user.id ,req.query.start, req.query.count, req.query.sort)
118
119   return res.json(getFormattedObjects(resultList.data, resultList.total))
120 }
121
122 async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
123   const options = {
124     arguments: [ req, res ],
125     errorMessage: 'Cannot insert the user with many retries.'
126   }
127
128   await retryTransactionWrapper(createUser, options)
129
130   // TODO : include Location of the new user -> 201
131   return res.type('json').status(204).end()
132 }
133
134 async function createUser (req: express.Request, res: express.Response, next: express.NextFunction) {
135   const body: UserCreate = req.body
136   const user = db.User.build({
137     username: body.username,
138     password: body.password,
139     email: body.email,
140     displayNSFW: false,
141     role: body.role,
142     videoQuota: body.videoQuota
143   })
144
145   await createUserAuthorAndChannel(user)
146
147   logger.info('User %s with its channel and author created.', body.username)
148 }
149
150 async function registerUser (req: express.Request, res: express.Response, next: express.NextFunction) {
151   const body: UserCreate = req.body
152
153   const user = db.User.build({
154     username: body.username,
155     password: body.password,
156     email: body.email,
157     displayNSFW: false,
158     role: UserRole.USER,
159     videoQuota: CONFIG.USER.VIDEO_QUOTA
160   })
161
162   await createUserAuthorAndChannel(user)
163   return res.type('json').status(204).end()
164 }
165
166 async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
167   // We did not load channels in res.locals.user
168   const user = await db.User.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
169
170   return res.json(user.toFormattedJSON())
171 }
172
173 function getUser (req: express.Request, res: express.Response, next: express.NextFunction) {
174   return res.json(res.locals.oauth.token.User.toFormattedJSON())
175 }
176
177 async function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {
178   const videoId = +req.params.videoId
179   const userId = +res.locals.oauth.token.User.id
180
181   const ratingObj = await db.UserVideoRate.load(userId, videoId, null)
182   const rating = ratingObj ? ratingObj.type : 'none'
183
184   const json: FormattedUserVideoRate = {
185     videoId,
186     rating
187   }
188   res.json(json)
189 }
190
191 async function listUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
192   const resultList = await db.User.listForApi(req.query.start, req.query.count, req.query.sort)
193
194   return res.json(getFormattedObjects(resultList.data, resultList.total))
195 }
196
197 async function removeUser (req: express.Request, res: express.Response, next: express.NextFunction) {
198   const user = await db.User.loadById(req.params.id)
199
200   await user.destroy()
201
202   return res.sendStatus(204)
203 }
204
205 async function updateMe (req: express.Request, res: express.Response, next: express.NextFunction) {
206   const body: UserUpdateMe = req.body
207
208   // FIXME: user is not already a Sequelize instance?
209   const user = res.locals.oauth.token.user
210
211   if (body.password !== undefined) user.password = body.password
212   if (body.email !== undefined) user.email = body.email
213   if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW
214
215   await user.save()
216
217   return res.sendStatus(204)
218 }
219
220 async function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
221   const body: UserUpdate = req.body
222   const user: UserInstance = res.locals.user
223
224   if (body.email !== undefined) user.email = body.email
225   if (body.videoQuota !== undefined) user.videoQuota = body.videoQuota
226   if (body.role !== undefined) user.role = body.role
227
228   await user.save()
229
230   return res.sendStatus(204)
231 }
232
233 function success (req: express.Request, res: express.Response, next: express.NextFunction) {
234   res.end()
235 }