Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2019
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.03 KB | None | 0 0
  1. const express = require('express');
  2. const sha256 = require('sha256');
  3. const bodyParser = require('body-parser');
  4. const OAuth2Server = require('oauth2-server');
  5. const cors = require('cors');
  6.  
  7. const app = express();
  8.  
  9. app.use(cors());
  10.  
  11. // kljucni vrstici
  12. app.use(bodyParser.urlencoded({ extended: true }));
  13. app.use(bodyParser.json());
  14.  
  15. /***************Mongodb configuratrion********************/
  16. var mongoose = require('mongoose');
  17. var configDB = require('./config/database.js');
  18. //configuration ===============================================================
  19. mongoose.connect(
  20. configDB.url,
  21. { useNewUrlParser: true }
  22. ); // connect to our database
  23. require('./models/Post');
  24. require('./models/Comment');
  25. require('./models/User');
  26. require('./models/Client');
  27. require('./models/Token');
  28.  
  29. const apiPost = require('./api/apiPosts');
  30.  
  31. const router = express.Router();
  32.  
  33. const User = mongoose.model('User');
  34. const Client = mongoose.model('Client');
  35. const Token = mongoose.model('Token');
  36.  
  37. /*
  38. https://alexbilbie.com/guide-to-oauth-2-grants/
  39. https://tools.ietf.org/html/rfc6749.html
  40. https://oauth2-server.readthedocs.io/en/latest/model/overview.html
  41. https://oauth2-server.readthedocs.io/en/latest/model/spec.html
  42. password grant:
  43. getClient -> getUser -> validateScope -> generateAccessToken(optional) ->
  44. -> generateRefreshToken(optional) -> saveToken
  45.  
  46. refresh_token grant:
  47. getClient -> getRefreshToken
  48. (ce naj vrne novi refresh token [alwaysIssueNewRefreshToken: true] potem se kličeju tudi)
  49. -> revokeToken -> generateAccessToken -> generateRefreshToken -> saveToken
  50.  
  51. pri avtentikaciji:
  52. getAccessToken -> verifyScope
  53. */
  54.  
  55. const ACCES_TOKEN_VALIDATION_HOURS = 1.0;
  56.  
  57. // @ts-ignore
  58. const oauth = new OAuth2Server({
  59. model: {
  60. generateAccessToken(client, user, scope) {
  61. console.log('generateAccessToken');
  62. // če iz te funkcije ne vrnete nič, potem se ustvari default vrednost
  63. },
  64. generateRefreshToken(client, user, scope) {
  65. console.log('generateRefreshToken');
  66. // če iz te funkcije ne vrnete nič, potem se ustvari default vrednost
  67. },
  68. async getClient(clientId, clientSecret) {
  69. // poišči klienta v bazi in ga vrni
  70. console.log('getClient');
  71. const allClinets = await Client.find({});
  72. console.log(allClinets);
  73. const client = await Client.findOne({ name: 'MyApp' });
  74. return client;
  75.  
  76. /*return {
  77. id: 'MyApp',
  78. // redirectUris: [''],
  79. grants: ['password', 'refresh_token'], // mora se nastaviti, za tiste grante ki jih dovolite
  80. }*/
  81. },
  82. getUserFromClient(client) {
  83. console.log('getUserFromClient');
  84. },
  85. async getUser(username, password) {
  86. // poišči uporabnika v bazi in ga vrni
  87. console.log('getUser');
  88. const user = await User.findOne({
  89. username: username,
  90. password: sha256(password)
  91. });
  92. console.log('USER: ', user);
  93.  
  94. return user;
  95.  
  96. /*return {
  97. username: 'goran.hrovat',
  98. role: 'admin'
  99. };*/
  100. },
  101. async saveToken(token, client, user) {
  102. // v bazo shrani access in refresh token in ga nato vrni v objketu (glej primer)
  103. console.log(
  104. 'saveToken ' +
  105. JSON.stringify(token) +
  106. ' user: ' +
  107. JSON.stringify(user) +
  108. ' client ' +
  109. JSON.stringify(client)
  110. );
  111.  
  112. var token = new Token({
  113. accessToken: token.accessToken,
  114. accessTokenExpiresAt: token.accessTokenExpiresAt,
  115. refreshToken: token.refreshToken,
  116. refreshTokenExpiresAt: token.refreshTokenExpiresAt,
  117. scope: user.scope,
  118. role: user.role,
  119. client: client._id,
  120. user: user._id,
  121. username: user.username,
  122. fullname: user.name + ' ' + user.surname
  123. });
  124.  
  125. await token.save();
  126.  
  127. return token;
  128.  
  129. /*return {
  130. accessToken: token.accessToken,
  131. accessTokenExpiresAt: token.accessTokenExpiresAt,
  132. refreshToken: token.refreshToken,
  133. refreshTokenExpiresAt: token.refreshTokenExpiresAt,
  134. scope: token.scope,
  135. client: {id: client.id},
  136. user: {id: user.username}
  137. }*/
  138. },
  139. validateScope(user, client, scope) {
  140. // uporabnik zahteva določen scope in tu spustimo naprej samo scope, ki jih dovolimo
  141. // ne rabimo mu odobriti vseh scopov, ki jih zahteva
  142. // dovoljeni scopi uporabnika so ponavadi zapisani v bazi
  143. // scope je poljuben niz, ponavadi več scopov ločimo z vejico
  144. console.log('validateScope ' + JSON.stringify(scope));
  145. const VALID_SCOPES = ['read', 'write'];
  146. return scope
  147. .split(' ')
  148. .filter(s => VALID_SCOPES.indexOf(s) >= 0)
  149. .join(' ');
  150. },
  151. generateAuthorizationCode(code, client, user) {
  152. console.log('generateAuthorizationCode');
  153. },
  154. async getAccessToken(accessToken) {
  155. console.log('getAccessToken: ' + accessToken);
  156.  
  157. // če najdeš token v bazi (shranjen je bil v funkciji saveToken) vrni objekt s tokenom
  158. // drugace null ali false
  159.  
  160. const token = await Token.findOne({ accessToken: accessToken });
  161. return token;
  162. /*
  163. var myDate = new Date();
  164. myDate.setTime(
  165. myDate.getTime() + ACCES_TOKEN_VALIDATION_HOURS * 60 * 60 * 1000
  166. );
  167. return {
  168. accessToken: accessToken,
  169. accessTokenExpiresAt: myDate,
  170. scope: 'read write',
  171. client: { id: 'MyApp' }, // with 'id' property
  172. user: { username: 'goran.hrovat', role: 'admin' }
  173. };*/
  174. },
  175. getAuthorizationCode(authorizationCode) {
  176. console.log('getAuthorizationCode');
  177. },
  178. async getRefreshToken(refreshToken) {
  179. console.log('getRefreshToken ' + JSON.stringify(refreshToken));
  180. // poišči refresh token v bazi, shranjen v funkciji saveToken
  181. const token = await Token.findOne({ refreshToken: refreshToken });
  182. return token;
  183.  
  184. /*return {
  185. refreshToken: refreshToken,
  186. scope: 'read write',
  187. client: { id: 'MyApp' }, // with 'id' property
  188. user: { username: 'goran.hrovat', role: 'admin' }
  189. };*/
  190. },
  191. revokeAuthorizationCode(code) {
  192. console.log('revokeAuthorizationCode');
  193. },
  194. revokeToken(token) {
  195. // iz baze pobriši refresh token
  196. console.log('revokeToken: ' + JSON.stringify(token));
  197. // če najdes vrneš, true drugače false
  198. return true;
  199. },
  200. saveAuthorizationCode(code, client, user) {
  201. console.log('saveAuthorizationCode');
  202. },
  203. verifyScope(accessToken, scope) {
  204. // zahtevan scope je v scope, ki se poda pri klicu authenicate za api metodo
  205. // scope, ki je dovoljen userju je shranjen v accessToken.scope,
  206. // scope, ki ga uporabnik hoče uveljavit pa v argumentu scope
  207. console.log(
  208. 'verifyScope: ' + JSON.stringify(accessToken) + ' scope: ' + scope
  209. );
  210. if (!accessToken.scope) {
  211. return false;
  212. }
  213. let requestedScopes = scope.split(' ');
  214. let authorizedScopes = accessToken.scope.split(' ');
  215. return requestedScopes.every(s => authorizedScopes.indexOf(s) >= 0);
  216. }
  217. }
  218. // requireClientAuthentication: false,
  219. // grants: ['refresh_token', 'password'],
  220. // accessTokenLifetime: 60 * 60 * 24,
  221. // alwaysIssueNewRefreshToken: true, // default = true
  222. });
  223.  
  224. // endpoint za pridobivanje access in refresh tokena
  225. app.post('/oauth/token', async function(req, res, next) {
  226. console.log('oauth/token');
  227. var request = new OAuth2Server.Request(req);
  228. var response = new OAuth2Server.Response(res);
  229.  
  230. try {
  231. let token = await oauth.token(request, response);
  232. // Todo: remove unnecessary values in response
  233. // console.log("oauth.token: " + JSON.stringify(token));
  234. return res.json(token);
  235. } catch (err) {
  236. return res.status(err.code || 500).json(err);
  237. }
  238. });
  239.  
  240. // middleware za authentikacijo, ki se uporabi pri REST storitvah
  241. function authenticate(options) {
  242. options = options || {};
  243. return async function(req, res, next) {
  244. console.log('start authenticate!');
  245. var request = new OAuth2Server.Request({
  246. headers: { authorization: req.headers.authorization },
  247. method: req.method,
  248. query: req.query,
  249. body: req.body
  250. });
  251. var response = new OAuth2Server.Response(res);
  252.  
  253. try {
  254. let token = await oauth.authenticate(request, response, options);
  255. // Request is authorized.
  256. console.log('authenticate middleware: ' + JSON.stringify(token));
  257.  
  258. if (options.role) {
  259. if (options.role != token.role) {
  260. throw new Error('User role error!');
  261. }
  262. }
  263. req.user = token;
  264. next();
  265. } catch (err) {
  266. // Request is not authorized.
  267. res.status(err.code || 500).json(err);
  268. // lahko tudi kličeš next, vendar bo req.user = undefined
  269. // req.user moraš potem preverjati v REST storitvah, ki jih želiš zaščititi
  270. }
  271. };
  272. }
  273.  
  274. // uporabnik mora podati bearer token in imeti scope read
  275. // authenticate middleware lahko damo na cel /api, kot je v tem primeru, ali pa na posamezno metodo
  276. /*app.use('/api/free', apiFree);
  277. app.use('/api/paid', authenticate({scope:"read"}), apiPaid);
  278. app.use('/api/admin', authenticate({scope:"read"}), apiAdmin);*/
  279.  
  280. router.get('/novice/free', apiPost.free);
  281. router.get('/novice/paid', authenticate({ scope: 'read' }), apiPost.paid);
  282. router.post('/novice/paid', authenticate({ role: 'admin' }), apiPost.addPost);
  283. router.post(
  284. '/novice/comment/:id',
  285. authenticate({ scope: 'write' }),
  286. apiPost.addComment
  287. );
  288. router.post(
  289. '/novice/update/:id',
  290. authenticate({ role: 'admin' }),
  291. apiPost.updatePost
  292. );
  293.  
  294. app.use('/api', router);
  295. // error middleware vrača nek status, če prejšnji middleware kliče next(err) namesto res.send("")
  296. app.use((err, req, res, next) => {
  297. res.status(400).send({ error: err });
  298. });
  299.  
  300. app.listen(process.env.port || 3000, () => {
  301. console.log('listening on port 3000');
  302. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement