feat(auth): WIP support for OAuth2

This commit is contained in:
David Mosbach 2023-12-03 03:49:20 +00:00
parent 527a270cbf
commit 2351388826
10 changed files with 757 additions and 277 deletions

302
package-lock.json generated
View File

@ -2404,6 +2404,12 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"dev": true
},
"array-ify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
@ -3519,6 +3525,23 @@
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
"dev": true
},
"basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"dev": true,
"requires": {
"safe-buffer": "5.1.2"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
}
}
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@ -4142,6 +4165,15 @@
}
}
},
"content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dev": true,
"requires": {
"safe-buffer": "5.2.1"
}
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
@ -4517,6 +4549,12 @@
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
"dev": true
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"dev": true
},
"copy-webpack-plugin": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz",
@ -5036,6 +5074,12 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
"depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"dev": true
},
"destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@ -5629,6 +5673,12 @@
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"dev": true
},
"eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
@ -5666,6 +5716,112 @@
}
}
},
"express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
"dev": true,
"requires": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.5.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.2.0",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.7",
"qs": "6.11.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.18.0",
"serve-static": "1.15.0",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"dependencies": {
"body-parser": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"dev": true,
"requires": {
"bytes": "3.1.2",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
}
},
"cookie": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
"dev": true
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
"dev": true,
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"statuses": "2.0.1",
"unpipe": "~1.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
"qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"dev": true,
"requires": {
"side-channel": "^1.0.4"
}
}
}
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@ -5881,12 +6037,24 @@
"mime-types": "^2.1.12"
}
},
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"dev": true
},
"fraction.js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
"dev": true
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
"dev": true
},
"fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
@ -6441,6 +6609,15 @@
"integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==",
"dev": true
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"icss-utils": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
@ -6541,6 +6718,12 @@
"loose-envify": "^1.0.0"
}
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"dev": true
},
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@ -6825,6 +7008,12 @@
}
}
},
"jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"dev": true
},
"js-cookie": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
@ -7822,6 +8011,12 @@
}
}
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
"dev": true
},
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@ -7846,6 +8041,12 @@
"underscore": "*"
}
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"dev": true
},
"micromatch": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
@ -9854,6 +10055,27 @@
}
}
},
"oauth2-mock-server": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/oauth2-mock-server/-/oauth2-mock-server-7.1.1.tgz",
"integrity": "sha512-4/PdPZLySsC68IoiO79BKpr5Rv2j2+WgFZskox7bzSlsXqoX8Nm9OWm3IXB0HQ7xJCbzcR4vvvcDe6UnA/UIiw==",
"dev": true,
"requires": {
"basic-auth": "^2.0.1",
"cors": "^2.8.5",
"express": "^4.18.2",
"is-plain-object": "^5.0.0",
"jose": "^4.15.4"
},
"dependencies": {
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"dev": true
}
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -10064,6 +10286,12 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
"dev": true
},
"path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@ -10818,6 +11046,16 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"dev": true,
"requires": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
}
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
@ -11557,6 +11795,58 @@
}
}
},
"send": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
"dev": true,
"requires": {
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"mime": "1.6.0",
"ms": "2.1.3",
"on-finished": "2.4.1",
"range-parser": "~1.2.1",
"statuses": "2.0.1"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
},
"dependencies": {
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
}
}
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"dev": true
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
}
}
},
"serialize-javascript": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
@ -11566,6 +11856,18 @@
"randombytes": "^2.1.0"
}
},
"serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
"dev": true,
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.18.0"
}
},
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",

View File

@ -86,6 +86,7 @@
"mini-css-extract-plugin": "^2.6.0",
"npm-run-all": "^4.1.5",
"null-loader": "^4.0.1",
"oauth2-mock-server": "^7.1.1",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"postcss-loader": "^7.0.0",
"postcss-preset-env": "^7.7.1",

View File

@ -6,6 +6,7 @@ dependencies:
- yesod-core
- yesod-persistent
- yesod-auth
- yesod-auth-oauth2
- yesod-static
- yesod-form
- yesod-persistent

View File

@ -1,4 +1,4 @@
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
-- SPDX-FileCopyrightText: 2023 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,David Mosbach <david.mosbach@uniworx.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
@ -60,7 +60,9 @@ import System.Directory
import Jobs
import qualified Data.Text.Encoding as Text
import qualified Data.Text as Text
import Yesod.Auth.OAuth2.AzureADv2 (oauth2AzureADv2)
import Yesod.Auth.Util.PasswordStore
import qualified Data.ByteString.Lazy as LBS
@ -124,6 +126,8 @@ import Handler.Utils.Memcached (manageMemcachedLocalInvalidations)
import qualified System.Clock as Clock
import Data.Maybe (fromJust)
import Utils.Avs
-- Import all relevant handler modules here.
@ -166,6 +170,8 @@ import Servant.API
import Servant.Client
import Network.HTTP.Client.TLS (mkManagerSettings)
import Auth.OAuth2
-- This line actually creates our YesodDispatch instance. It is the second half
-- of the call to mkYesodData which occurs in Foundation.hs. Please see the
@ -235,7 +241,7 @@ makeFoundation appSettings''@AppSettings{..} = do
-- from there, and then create the real foundation.
let
mkFoundation :: _ -> (forall m. MonadIO m => Custom.Pool' m DBConnLabel DBConnUseState SqlBackend) -> _
mkFoundation appSettings' appConnPool appSmtpPool appLdapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery = UniWorX{..}
mkFoundation appSettings' appConnPool appSmtpPool appLdapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appAuthPlugins appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery = UniWorX{..}
tempFoundation = mkFoundation
(error "appSettings' forced in tempFoundation")
(error "connPool forced in tempFoundation")
@ -252,10 +258,12 @@ makeFoundation appSettings''@AppSettings{..} = do
(error "MinioConn forced in tempFoundation")
(error "VerpSecret forced in tempFoundation")
(error "AuthKey forced in tempFoundation")
(error "AuthPlugins forced in tempFoundation")
(error "PersonalisedSheetFilesSeedKey forced in tempFoundation")
(error "VolatileClusterSettingsCache forced in tempFoundation")
(error "AvsQuery forced in tempFoundation")
runAppLoggingT tempFoundation $ do
$logInfoS "InstanceID" $ UUID.toText appInstanceID
$logInfoS "Configuration" $ tshowCrop appSettings''
@ -317,6 +325,23 @@ makeFoundation appSettings''@AppSettings{..} = do
appAuthKey <- clusterSetting (Proxy :: Proxy 'ClusterAuthKey) `customRunSqlPool` sqlPool
appPersonalisedSheetFilesSeedKey <- clusterSetting (Proxy :: Proxy 'ClusterPersonalisedSheetFilesSeedKey) `customRunSqlPool` sqlPool
mAzureTenantID <- liftIO $ (fmap Text.pack) <$> lookupEnv "AZURE_ADV2_TENANT_ID"
let -- Auth Plugins
tenantID = fromMaybe (error "Tenant ID mising") mAzureTenantID
loadPlugin p prefix = do -- Loads given YesodAuthPlugin
mID <- (fmap Text.pack) <$> (lookupEnv $ prefix ++ "_CLIENT_ID")
mSecret <- (fmap Text.pack) <$> (lookupEnv $ prefix ++ "_CLIENT_SECRET")
let mArgs = (,) <$> mID <*> mSecret
guard $ isJust mArgs
return . uncurry p $ fromJust mArgs
appAuthPlugins <- liftIO $ sequence [
return oauth2MockServer
, loadPlugin (oauth2AzureADv2 tenantID) "AZURE_ADV2"
]
let appVolatileClusterSettingsCacheTime' = Clock.fromNanoSecs ns
where (MkFixed ns :: Nano) = realToFrac appVolatileClusterSettingsCacheTime
appVolatileClusterSettingsCache <- newTVarIO $ mkVolatileClusterSettingsCache appVolatileClusterSettingsCacheTime'
@ -376,7 +401,7 @@ makeFoundation appSettings''@AppSettings{..} = do
$logDebugS "Runtime configuration" $ tshowCrop appSettings'
let foundation = mkFoundation appSettings' sqlPool smtpPool ldapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery
let foundation = mkFoundation appSettings' sqlPool smtpPool ldapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appAuthPlugins appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery
-- Return the foundation
$logInfoS "setup" "*** DONE ***"

58
src/Auth/OAuth2.hs Normal file
View File

@ -0,0 +1,58 @@
-- SPDX-FileCopyrightText: 2023 David Mosbach <david.mosbach@uniworx.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Auth.OAuth2
( OAuthUserException(..)
, oauth2MockServer
, mockPluginName
) where
import Data.Text
import Import.NoFoundation
import Yesod.Auth.OAuth2
import Yesod.Auth.OAuth2.Prelude
data OAuthUserException = OAuthUserError
| OAuthUserAmbiguous -- TODO
deriving (Show, Eq, Generic)
instance Exception OAuthUserException
----------------------------------------
---- OAuth2 development auth plugin ----
----------------------------------------
mockPluginName :: Text
mockPluginName = "uniworx_dev"
newtype UserID = UserID Text
instance FromJSON UserID where
parseJSON = withObject "UserID" $ \o ->
UserID <$> o .: "id"
oauth2MockServer :: YesodAuth m => AuthPlugin m
oauth2MockServer =
let oa = OAuth2
{ oauth2ClientId = "uniworx"
, oauth2ClientSecret = Just "shh"
, oauth2AuthorizeEndpoint = fromString $ mockServerURL <> "/authorize"
, oauth2TokenEndpoint = fromString $ mockServerURL <> "/token"
, oauth2RedirectUri = Nothing
}
mockServerURL = "0.0.0.0/"
profileSrc = fromString $ mockServerURL <> "/foo"
in authOAuth2 mockPluginName oa $ \manager token -> do
(UserID userID, userResponse) <- authGetProfile mockPluginName manager token profileSrc
return Creds
{ credsPlugin = mockPluginName
, credsIdent = userID
, credsExtra = setExtra token userResponse
}

View File

@ -1,4 +1,4 @@
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>,David Mosbach <david.mosbach@uniworx.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
@ -139,9 +139,9 @@ instance YesodAuth UniWorX where
setTitleI MsgLoginTitle
$(widgetFile "login")
authenticate = UniWorX.authenticate
authenticate = UniWorX.oAuthenticate -- UniWorX.authenticate
authPlugins UniWorX{ appSettings' = AppSettings{..}, appLdapPool } = catMaybes
authPlugins UniWorX{ appSettings' = AppSettings{..}, appLdapPool, appAuthPlugins } = appAuthPlugins ++ catMaybes
[ flip campusLogin campusUserFailoverMode <$> appLdapPool
, Just . hashLogin $ pwHashAlgorithm appAuthPWHash
, dummyLogin <$ guard appAuthDummyLogin

View File

@ -97,6 +97,7 @@ data UniWorX = UniWorX
, appUploadCache :: Maybe MinioConn
, appVerpSecret :: VerpSecret
, appAuthKey :: Auth.Key
, appAuthPlugins :: [AuthPlugin UniWorX]
, appFileSourceARC :: Maybe (ARCHandle (FileContentChunkReference, (Int, Int)) Int ByteString)
, appFileSourcePrewarm :: Maybe (LRUHandle (FileContentChunkReference, (Int, Int)) UTCTime Int ByteString)
, appFileInjectInhibit :: TVar (IntervalMap UTCTime (Set FileContentReference))

View File

@ -1,9 +1,10 @@
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>
-- SPDX-FileCopyrightText: 2023 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Steffen Jost <jost@cip.ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,David Mosbach <david.mosbach@uniworx.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
module Foundation.Yesod.Auth
( authenticate
, oAuthenticate
, ldapLookupAndUpsert
, upsertCampusUser
, decodeUserTest
@ -56,6 +57,7 @@ authenticate :: ( MonadHandler m, HandlerSite m ~ UniWorX
)
=> Creds UniWorX -> m (AuthenticationResult UniWorX)
authenticate creds@Creds{..} = liftHandler . runDB . withReaderT projectBackend $ do
$logErrorS "Auth" $ "\a\27[31m" <> tshow creds <> "\27[0m"
now <- liftIO getCurrentTime
let
@ -120,6 +122,82 @@ authenticate creds@Creds{..} = liftHandler . runDB . withReaderT projectBackend
-> acceptExisting
-- | Authentication via OAuth 2
oAuthenticate :: ( MonadHandler m, HandlerSite m ~ UniWorX
, YesodPersist UniWorX, BackendCompatible SqlBackend (YesodPersistBackend UniWorX)
, YesodAuth UniWorX, UserId ~ AuthId UniWorX
)
=> Creds UniWorX -> m (AuthenticationResult UniWorX)
oAuthenticate creds@Creds{..} = liftHandler . runDB . withReaderT projectBackend $ do
$logErrorS "Auth" $ "\a\27[31m" <> tshow creds <> "\27[0m"
now <- liftIO getCurrentTime
let
uAuth = UniqueAuthentication $ CI.mk credsIdent
upsertMode = creds ^? _upsertCampusUserMode -- TODO adjust do OAuth
isDummy = is (_Just . _UpsertCampusUserLoginDummy) upsertMode
isOther = is (_Just . _UpsertCampusUserLoginOther) upsertMode
excRecovery res
| isDummy || isOther
= do
case res of
UserError err -> addMessageI Error err
ServerError err -> addMessage Error $ toHtml err
_other -> return ()
acceptExisting
| otherwise
= return res
excHandlers =
[ C.Handler $ \case
CampusUserNoResult -> do
$logWarnS "LDAP" $ "User lookup failed after successful login for " <> credsIdent
excRecovery . UserError $ IdentifierNotFound credsIdent
CampusUserAmbiguous -> do
$logWarnS "LDAP" $ "Multiple LDAP results for " <> credsIdent
excRecovery . UserError $ IdentifierNotFound credsIdent
err -> do
$logErrorS "LDAP" $ tshow err
mr <- getMessageRender
excRecovery . ServerError $ mr MsgInternalLdapError
, C.Handler $ \(cExc :: CampusUserConversionException) -> do
$logErrorS "LDAP" $ tshow cExc
mr <- getMessageRender
excRecovery . ServerError $ mr cExc
]
acceptExisting :: SqlPersistT (HandlerFor UniWorX) (AuthenticationResult UniWorX)
acceptExisting = do
res <- maybe (UserError $ IdentifierNotFound credsIdent) (Authenticated . entityKey) <$> getBy uAuth
case res of
Authenticated uid
-> associateUserSchoolsByTerms uid
_other
-> return ()
case res of
Authenticated uid
| not isDummy -> res <$ update uid [ UserLastAuthentication =. Just now ]
_other -> return res
$logDebugS "auth" $ tshow Creds{..}
pool <- getsYesod $ view _appLdapPool {-(case credsPlugin of
"azureadv2" -> getsYesod $ view _appLdapPool -- TODO
mockPluginName -> getsYesod $ view _appLdapPool -- TODO
_ -> error "undefined" -- TODO
)-}
flip catches excHandlers $ case pool of
Just ldapPool
| Just upsertMode' <- upsertMode -> do
ldapData <- campusUser ldapPool campusUserFailoverMode Creds{..}
$logDebugS "LDAP" $ "Successful LDAP lookup: " <> tshow ldapData
Authenticated . entityKey <$> upsertCampusUser upsertMode' ldapData
_other
-> acceptExisting
data CampusUserConversionException
= CampusUserInvalidIdent
| CampusUserInvalidEmail

View File

@ -88,6 +88,9 @@ extra-deps:
- yesod-eventsource
- yesod-websockets
- git: https://github.com/freckle/yesod-auth-oauth2
commit: 11948a65c405f1a99ccb327d328d416e492542a1
- git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptonite.git
commit: 71a630edaf5f22c464e24fac8d9d310f4055ea1f

View File

@ -5,539 +5,550 @@
packages:
- completed:
commit: 22fc3bb14841d8d50997aa47f1be3852e666f787
git: https://gitlab.ifi.lmu.de/uni2work/haskell/encoding.git
name: encoding
version: 0.8.2
git: https://gitlab.ifi.lmu.de/uni2work/haskell/encoding.git
pantry-tree:
size: 5723
sha256: fec12328951021bb4d9326ae0b35f0c459e65f28442366efd4366cd1e18abe19
commit: 22fc3bb14841d8d50997aa47f1be3852e666f787
size: 5723
version: 0.8.2
original:
commit: 22fc3bb14841d8d50997aa47f1be3852e666f787
git: https://gitlab.ifi.lmu.de/uni2work/haskell/encoding.git
commit: 22fc3bb14841d8d50997aa47f1be3852e666f787
- completed:
commit: b7071df50bad3a251a544b984e4bf98fa09b8fae
git: https://gitlab.ifi.lmu.de/uni2work/haskell/memcached-binary.git
name: memcached-binary
version: 0.2.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/memcached-binary.git
pantry-tree:
size: 1277
sha256: 0da0539b7b9a56d03a116dcd666bc1bbbef085659910420849484d1418aa0857
commit: b7071df50bad3a251a544b984e4bf98fa09b8fae
size: 1277
version: 0.2.0
original:
commit: b7071df50bad3a251a544b984e4bf98fa09b8fae
git: https://gitlab.ifi.lmu.de/uni2work/haskell/memcached-binary.git
commit: b7071df50bad3a251a544b984e4bf98fa09b8fae
- completed:
commit: cbea6159c2975d42f948525e03e12fc390da53c5
git: https://gitlab.ifi.lmu.de/uni2work/haskell/conduit-resumablesink.git
name: conduit-resumablesink
version: '0.3'
git: https://gitlab.ifi.lmu.de/uni2work/haskell/conduit-resumablesink.git
pantry-tree:
size: 394
sha256: 0cccf4684bbd84f81d2d3d53dd81c46cb103b5322f1d8e89e9b222211281e1b7
commit: cbea6159c2975d42f948525e03e12fc390da53c5
size: 394
version: '0.3'
original:
commit: cbea6159c2975d42f948525e03e12fc390da53c5
git: https://gitlab.ifi.lmu.de/uni2work/haskell/conduit-resumablesink.git
commit: cbea6159c2975d42f948525e03e12fc390da53c5
- completed:
commit: 5aa1f3b009253b02c4822005ac59ee208a10a347
git: https://github.com/jtdaugherty/HaskellNet.git
name: HaskellNet
version: 0.5.1
git: https://github.com/jtdaugherty/HaskellNet.git
pantry-tree:
size: 4011
sha256: 921b437ef18ccb04f889301c407263d6b5b72c5864803a000b1e61328988ce70
commit: 5aa1f3b009253b02c4822005ac59ee208a10a347
size: 4011
version: 0.5.1
original:
commit: 5aa1f3b009253b02c4822005ac59ee208a10a347
git: https://github.com/jtdaugherty/HaskellNet.git
commit: 5aa1f3b009253b02c4822005ac59ee208a10a347
- completed:
commit: 40393c938111ac78232dc2c7eec5edb4a22d03e8
git: https://gitlab.ifi.lmu.de/uni2work/haskell/HaskellNet-SSL.git
name: HaskellNet-SSL
version: 0.3.4.1
git: https://gitlab.ifi.lmu.de/uni2work/haskell/HaskellNet-SSL.git
pantry-tree:
size: 841
sha256: 95dcec22fdb8af986e59f0f60aa76d4a48f34a546dca799bd571e1d183f773e0
commit: 40393c938111ac78232dc2c7eec5edb4a22d03e8
size: 841
version: 0.3.4.1
original:
commit: 40393c938111ac78232dc2c7eec5edb4a22d03e8
git: https://gitlab.ifi.lmu.de/uni2work/haskell/HaskellNet-SSL.git
commit: 40393c938111ac78232dc2c7eec5edb4a22d03e8
- completed:
commit: 01afaf599ba6f8a9d804c269e91d3190b249d3f0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/ldap-client.git
name: ldap-client
version: 0.4.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/ldap-client.git
pantry-tree:
size: 6176
sha256: 3fa8f102427b437b2baaec15cf884e88b47a1621b1c3fd4d8919f0263fde8656
commit: 01afaf599ba6f8a9d804c269e91d3190b249d3f0
size: 6176
version: 0.4.0
original:
commit: 01afaf599ba6f8a9d804c269e91d3190b249d3f0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/ldap-client.git
commit: 01afaf599ba6f8a9d804c269e91d3190b249d3f0
- completed:
subdir: serversession
commit: fda3a000f9039e35e76e28f8e88c4942fac9fd69
git: https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git
name: serversession
version: 1.0.2
git: https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git
pantry-tree:
size: 545
sha256: 83ac78a987399db3da62f84bbd335fead11aadebd57251d0688127fca984db23
commit: fda3a000f9039e35e76e28f8e88c4942fac9fd69
original:
size: 545
subdir: serversession
git: https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git
version: 1.0.2
original:
commit: fda3a000f9039e35e76e28f8e88c4942fac9fd69
git: https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git
subdir: serversession
- completed:
subdir: serversession-backend-acid-state
commit: fda3a000f9039e35e76e28f8e88c4942fac9fd69
git: https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git
name: serversession-backend-acid-state
version: 1.0.4
git: https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git
pantry-tree:
size: 544
sha256: 4804260c6245c12e1728c78dd33bf16e95b7f2b69b38b6900a4e65b1ef3e04b7
commit: fda3a000f9039e35e76e28f8e88c4942fac9fd69
original:
size: 544
subdir: serversession-backend-acid-state
git: https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git
version: 1.0.4
original:
commit: fda3a000f9039e35e76e28f8e88c4942fac9fd69
git: https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git
subdir: serversession-backend-acid-state
- completed:
commit: dc928c3a456074b8777603bea20e81937321777f
git: https://gitlab.ifi.lmu.de/uni2work/haskell/xss-sanitize.git
name: xss-sanitize
version: 0.3.6
git: https://gitlab.ifi.lmu.de/uni2work/haskell/xss-sanitize.git
pantry-tree:
size: 750
sha256: f567a1c834448daaa164f2029fad164e6c8df2d4c92b51f811bae19cc0c95975
commit: dc928c3a456074b8777603bea20e81937321777f
size: 750
version: 0.3.6
original:
commit: dc928c3a456074b8777603bea20e81937321777f
git: https://gitlab.ifi.lmu.de/uni2work/haskell/xss-sanitize.git
commit: dc928c3a456074b8777603bea20e81937321777f
- completed:
subdir: colonnade
commit: f8170266ab25b533576e96715bedffc5aa4f19fa
git: https://gitlab.ifi.lmu.de/uni2work/haskell/colonnade.git
name: colonnade
version: 1.2.0.2
git: https://gitlab.ifi.lmu.de/uni2work/haskell/colonnade.git
pantry-tree:
size: 481
sha256: 392393652cc0f354d351482557b9385c8e6122e706359b030373656565f2e045
commit: f8170266ab25b533576e96715bedffc5aa4f19fa
original:
size: 481
subdir: colonnade
git: https://gitlab.ifi.lmu.de/uni2work/haskell/colonnade.git
version: 1.2.0.2
original:
commit: f8170266ab25b533576e96715bedffc5aa4f19fa
git: https://gitlab.ifi.lmu.de/uni2work/haskell/colonnade.git
subdir: colonnade
- completed:
commit: 42103ab247057c04c8ce7a83d9d4c160713a3df1
git: https://gitlab.ifi.lmu.de/uni2work/haskell/minio-hs.git
name: minio-hs
version: 1.5.2
git: https://gitlab.ifi.lmu.de/uni2work/haskell/minio-hs.git
pantry-tree:
size: 4560
sha256: c5faff15fa22a7a63f45cd903c9bd11ae03f422c26f24750f5c44cb4d0db70fc
commit: 42103ab247057c04c8ce7a83d9d4c160713a3df1
size: 4560
version: 1.5.2
original:
commit: 42103ab247057c04c8ce7a83d9d4c160713a3df1
git: https://gitlab.ifi.lmu.de/uni2work/haskell/minio-hs.git
commit: 42103ab247057c04c8ce7a83d9d4c160713a3df1
- completed:
subdir: cryptoids-class
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
name: cryptoids-class
version: 0.0.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
pantry-tree:
size: 412
sha256: 30466648d273ffb1d580b7961188d67a0bedb3703d6d5f8cca3c15a45295f203
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
original:
size: 412
subdir: cryptoids-class
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
- completed:
subdir: cryptoids-types
name: cryptoids-types
version: 1.0.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
pantry-tree:
size: 320
sha256: 824ac5c55c2ad553bd401bb5a99731bbdccc828ecc5d71f174e9375c4e03c46e
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
original:
subdir: cryptoids-types
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
- completed:
subdir: cryptoids
name: cryptoids
version: 0.5.1.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
pantry-tree:
size: 566
sha256: b1f49dde76ff7e78b76e7f2f3b3f76c55e5e61555d1df5415ad3b6eb80dda2cb
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
original:
subdir: cryptoids
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
- completed:
subdir: filepath-crypto
name: filepath-crypto
version: 0.1.0.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
pantry-tree:
size: 676
sha256: 9c31a2ffb2b1c86f9ba34eb83529c7a5a7dc68a49f89813c9b553427474654d9
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
original:
subdir: filepath-crypto
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
- completed:
subdir: uuid-crypto
name: uuid-crypto
version: 1.4.0.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
pantry-tree:
size: 417
sha256: 852e59807df1f2cf4b5a3748c46fa149d15a78651c93addfe5fc31d2d94c47f4
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
original:
subdir: uuid-crypto
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
- completed:
subdir: gearhash
name: gearhash
version: 1.0.0
git: https://github.com/gkleen/FastCDC.git
pantry-tree:
size: 551
sha256: 89c58554f6780bff2a2cab86e94d2f562eea34e8025a9925bfdc25b56c925d3e
commit: f216e3c0a1efa11a62fd4c9c2db38f7e2b7ac72d
original:
subdir: gearhash
git: https://github.com/gkleen/FastCDC.git
commit: f216e3c0a1efa11a62fd4c9c2db38f7e2b7ac72d
- completed:
subdir: fastcdc
name: fastcdc
version: 0.0.0
git: https://github.com/gkleen/FastCDC.git
original:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
subdir: cryptoids-class
- completed:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
name: cryptoids-types
pantry-tree:
sha256: 824ac5c55c2ad553bd401bb5a99731bbdccc828ecc5d71f174e9375c4e03c46e
size: 320
subdir: cryptoids-types
version: 1.0.0
original:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
subdir: cryptoids-types
- completed:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
name: cryptoids
pantry-tree:
sha256: b1f49dde76ff7e78b76e7f2f3b3f76c55e5e61555d1df5415ad3b6eb80dda2cb
size: 566
subdir: cryptoids
version: 0.5.1.0
original:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
subdir: cryptoids
- completed:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
name: filepath-crypto
pantry-tree:
sha256: 9c31a2ffb2b1c86f9ba34eb83529c7a5a7dc68a49f89813c9b553427474654d9
size: 676
subdir: filepath-crypto
version: 0.1.0.0
original:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
subdir: filepath-crypto
- completed:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
name: uuid-crypto
pantry-tree:
sha256: 852e59807df1f2cf4b5a3748c46fa149d15a78651c93addfe5fc31d2d94c47f4
size: 417
subdir: uuid-crypto
version: 1.4.0.0
original:
commit: 130b0dcbf2b09ccdf387b50262f1efbbbf1819e3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git
subdir: uuid-crypto
- completed:
commit: f216e3c0a1efa11a62fd4c9c2db38f7e2b7ac72d
git: https://github.com/gkleen/FastCDC.git
name: gearhash
pantry-tree:
sha256: 89c58554f6780bff2a2cab86e94d2f562eea34e8025a9925bfdc25b56c925d3e
size: 551
subdir: gearhash
version: 1.0.0
original:
commit: f216e3c0a1efa11a62fd4c9c2db38f7e2b7ac72d
git: https://github.com/gkleen/FastCDC.git
subdir: gearhash
- completed:
commit: f216e3c0a1efa11a62fd4c9c2db38f7e2b7ac72d
git: https://github.com/gkleen/FastCDC.git
name: fastcdc
pantry-tree:
size: 292
sha256: aa588b55c7c9c079e39569489a8089ec312f0538d02cf0e1fffe2f0e058566b8
commit: f216e3c0a1efa11a62fd4c9c2db38f7e2b7ac72d
original:
size: 292
subdir: fastcdc
git: https://github.com/gkleen/FastCDC.git
version: 0.0.0
original:
commit: f216e3c0a1efa11a62fd4c9c2db38f7e2b7ac72d
git: https://github.com/gkleen/FastCDC.git
subdir: fastcdc
- completed:
commit: 843683d024f767de236f74d24a3348f69181a720
git: https://gitlab.ifi.lmu.de/uni2work/haskell/zip-stream.git
name: zip-stream
version: 0.2.0.1
git: https://gitlab.ifi.lmu.de/uni2work/haskell/zip-stream.git
pantry-tree:
size: 812
sha256: 0da8bc38d73034962d2e2d1a7586b6dee848a629319fce9cbbf578348c61118c
commit: 843683d024f767de236f74d24a3348f69181a720
size: 812
version: 0.2.0.1
original:
commit: 843683d024f767de236f74d24a3348f69181a720
git: https://gitlab.ifi.lmu.de/uni2work/haskell/zip-stream.git
commit: 843683d024f767de236f74d24a3348f69181a720
- completed:
subdir: yesod-core
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-core
version: 1.6.20.2
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 5954
sha256: 08c8da10b32c8d9f784238fd87232bf90b752e82f81ef2c52c62210f9aadda9a
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 5954
subdir: yesod-core
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.20.2
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-core
- completed:
subdir: yesod-static
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-static
version: 1.6.1.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 2949
sha256: 32c1608243a5309005ce11e2aa379ac1d6f8c380c529785eb510770118f3da06
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 2949
subdir: yesod-static
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.1.0
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-static
- completed:
subdir: yesod-persistent
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-persistent
version: 1.6.0.7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 497
sha256: 3778ef2964e1a3890afc22cc9124eacb40e64b62bed4983a85d3b99897f54c5c
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 497
subdir: yesod-persistent
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.0.7
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-persistent
- completed:
subdir: yesod-newsfeed
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-newsfeed
version: 1.7.0.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 488
sha256: 53ebad62655863a657dcf749ffd3de46f6af90dd71f55bc4d50805ac48ddb099
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 488
subdir: yesod-newsfeed
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.7.0.0
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-newsfeed
- completed:
subdir: yesod-form
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-form
version: 1.7.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 1914
sha256: 260b7f16a8e1d58da137eb91aeed3a11ccbe59ba3e614457a635b9dc3e71426f
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 1914
subdir: yesod-form
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.7.0
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-form
- completed:
subdir: yesod-form-multi
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-form-multi
version: 1.7.0.2
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 328
sha256: b21fc50db43733dfe6e285345856610ba4feb83329e9cf953bf8047ba18ecbd6
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 328
subdir: yesod-form-multi
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.7.0.2
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-form-multi
- completed:
subdir: yesod-auth
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-auth
version: 1.6.10.3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 1212
sha256: d335b940a207f8155f421b7146746a72d20db6ad54412154f2c829a59bf21e08
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 1212
subdir: yesod-auth
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.10.3
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-auth
- completed:
subdir: yesod-auth-oauth
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-auth-oauth
version: 1.6.0.3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 321
sha256: 39d2f7d5d1abb3a2953858c5f23880e60ecfcdad0549ddc2570204f9c47649f4
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 321
subdir: yesod-auth-oauth
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.0.3
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-auth-oauth
- completed:
subdir: yesod-sitemap
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-sitemap
version: 1.6.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 314
sha256: 971f48af7011ff7816872d067e5de9cadafdd371bdf209170b77df36001abd27
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 314
subdir: yesod-sitemap
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.0
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-sitemap
- completed:
subdir: yesod-test
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-test
version: 1.6.12
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 563
sha256: 3d5022e8e3f8e77abcf075c42cf49efaa26f4951159bbb5ab50b69fdfeacb7c1
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 563
subdir: yesod-test
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.12
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-test
- completed:
subdir: yesod-bin
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-bin
version: 1.6.1
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 1295
sha256: 422d7816965b79826c6c24582d76dadbacd1bfb3e9a8f31208867cd788f2a5b8
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 1295
subdir: yesod-bin
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.1
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-bin
- completed:
subdir: yesod
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod
version: 1.6.1.1
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 666
sha256: cb53ef3f2036185d2b4752d6fbc5d78470b4504e646e7eb4dd2397f2599daf42
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 666
subdir: yesod
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.1.1
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod
- completed:
subdir: yesod-eventsource
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-eventsource
version: 1.6.0.1
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 324
sha256: 6d393201852cd024e377159ba836398e24d191563e08165430113d3c1384aff2
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 324
subdir: yesod-eventsource
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 1.6.0.1
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-eventsource
- completed:
subdir: yesod-websockets
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
name: yesod-websockets
version: 0.3.0.3
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
pantry-tree:
size: 485
sha256: 02df6117e9b74a77879ea750130ba2d8ad8d3c99e14ca678320cb578984301e5
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
original:
size: 485
subdir: yesod-websockets
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
version: 0.3.0.3
original:
commit: aa671eb41fdad360f2f7cb844f8de03479efe3f7
git: https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git
subdir: yesod-websockets
- completed:
commit: 11948a65c405f1a99ccb327d328d416e492542a1
git: https://github.com/freckle/yesod-auth-oauth2
name: yesod-auth-oauth2
pantry-tree:
sha256: a68ec51e1008c315dd15e81cc3ac1f4e2adfd3db623259395757ecae2787cef2
size: 4277
version: 0.7.1.3
original:
commit: 11948a65c405f1a99ccb327d328d416e492542a1
git: https://github.com/freckle/yesod-auth-oauth2
- completed:
commit: 71a630edaf5f22c464e24fac8d9d310f4055ea1f
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptonite.git
name: cryptonite
version: '0.29'
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptonite.git
pantry-tree:
size: 25056
sha256: 19e49259fa5e3c257495d72b3c7c3c49537aeafd508c780c2430ddca2ef71a91
commit: 71a630edaf5f22c464e24fac8d9d310f4055ea1f
size: 25056
version: '0.29'
original:
commit: 71a630edaf5f22c464e24fac8d9d310f4055ea1f
git: https://gitlab.ifi.lmu.de/uni2work/haskell/cryptonite.git
commit: 71a630edaf5f22c464e24fac8d9d310f4055ea1f
- completed:
commit: e18dd125c5ea26fa4e88bed079b61d8c1365ee37
git: https://gitlab.ifi.lmu.de/uni2work/haskell/esqueleto.git
name: esqueleto
version: 3.5.4.0
git: https://gitlab.ifi.lmu.de/uni2work/haskell/esqueleto.git
pantry-tree:
size: 5633
sha256: 8a93dc98eb4529ff64aa5bcdaa3c00dcdf0378033ad675864e2b0fc3d869d947
commit: e18dd125c5ea26fa4e88bed079b61d8c1365ee37
size: 5633
version: 3.5.4.0
original:
git: https://gitlab.ifi.lmu.de/uni2work/haskell/esqueleto.git
commit: e18dd125c5ea26fa4e88bed079b61d8c1365ee37
git: https://gitlab.ifi.lmu.de/uni2work/haskell/esqueleto.git
- completed:
hackage: classy-prelude-yesod-1.5.0@sha256:8f7e183bdfd6d2ea9674284c4f285294ab086aff60d9be4e5d7d2f3c1a2b05b7,1330
pantry-tree:
size: 330
sha256: ae84d4cc0e1daf985db6cdcf2ac92319531b8e60f547183cc46480d00aafbe20
size: 330
original:
hackage: classy-prelude-yesod-1.5.0@sha256:8f7e183bdfd6d2ea9674284c4f285294ab086aff60d9be4e5d7d2f3c1a2b05b7,1330
- completed:
hackage: acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207
pantry-tree:
size: 13678
sha256: d57bcb2ad5e01fe7424abbcf9e58cf943027b5c4a8496d93625c57b6e1272274
size: 13678
original:
hackage: acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207
- completed:
hackage: normaldistribution-1.1.0.3@sha256:2615b784c4112cbf6ffa0e2b55b76790290a9b9dff18a05d8c89aa374b213477,2160
pantry-tree:
size: 269
sha256: 856818862d12df8b030fa9cfef2c4ffa604d06f0eb057498db245dfffcd60e3c
size: 269
original:
hackage: normaldistribution-1.1.0.3@sha256:2615b784c4112cbf6ffa0e2b55b76790290a9b9dff18a05d8c89aa374b213477,2160
- completed:
hackage: pkcs7-1.0.0.1@sha256:b26e5181868667abbde3ce17f9a61cf705eb695da073cdf82e1f9dfd6cc11176,3594
pantry-tree:
size: 316
sha256: ab3c2d2880179a945ab3122c51d1657ab4a7a628292b646e047cd32b0751a80c
size: 316
original:
hackage: pkcs7-1.0.0.1@sha256:b26e5181868667abbde3ce17f9a61cf705eb695da073cdf82e1f9dfd6cc11176,3594
- completed:
hackage: system-locale-0.3.0.0@sha256:13b3982403d8ac8cc6138e68802be8d8e7cf7ebc4cbc7e47e99e3c0dd1be066a,1529
pantry-tree:
size: 446
sha256: 3b22af3e6315835bf614a0d30381ec7e47aca147b59ba601aeaa26f1fdc19373
size: 446
original:
hackage: system-locale-0.3.0.0@sha256:13b3982403d8ac8cc6138e68802be8d8e7cf7ebc4cbc7e47e99e3c0dd1be066a,1529
- completed:
hackage: token-bucket-0.1.0.1@sha256:d8e85f2fc373939975e7ace7907baee177531ab6e43df94e330a2357e64a2d11,1899
pantry-tree:
size: 399
sha256: b0b4a08ea1bf76bd108310f64d7f80e0f30b61ddc3d71f6cab7bdce329d2c1fa
size: 399
original:
hackage: token-bucket-0.1.0.1@sha256:d8e85f2fc373939975e7ace7907baee177531ab6e43df94e330a2357e64a2d11,1899
- completed:
hackage: tz-0.1.3.5@sha256:fb17ca50a7d943e511c0ca70342dc83f66aa2532de2745632f1f5f9b1ad783c4,5086
pantry-tree:
size: 1179
sha256: 6482698ea1b1a93bd684fca35836b35e8cdf53fe51b0fa6b215afa7da1f983a6
size: 1179
original:
hackage: tz-0.1.3.5@sha256:fb17ca50a7d943e511c0ca70342dc83f66aa2532de2745632f1f5f9b1ad783c4,5086
- completed:
hackage: unidecode-0.1.0.4@sha256:99581ee1ea334a4596a09ae3642e007808457c66893b587e965b31f15cbf8c4d,1144
pantry-tree:
size: 492
sha256: 4959068a0caf410dd4b8046f0b0138e3cf6471abb0cc865c9993db3b2930d283
size: 492
original:
hackage: unidecode-0.1.0.4@sha256:99581ee1ea334a4596a09ae3642e007808457c66893b587e965b31f15cbf8c4d,1144
- completed:
hackage: hlint-test-0.1.0.0@sha256:e427c0593433205fc629fb05b74c6b1deb1de72d1571f26142de008f0d5ee7a9,1814
pantry-tree:
size: 442
sha256: 347eac6c8a3c02fc0101444d6526b57b3c27785809149b12f90d8db57c721fea
size: 442
original:
hackage: hlint-test-0.1.0.0@sha256:e427c0593433205fc629fb05b74c6b1deb1de72d1571f26142de008f0d5ee7a9,1814
- completed:
hackage: servant-quickcheck-0.0.10.0@sha256:1d5849d703c2487752f8fc7391cca7c998ee24f54ca0bb72d238bf99b64ac667,3755
pantry-tree:
size: 976
sha256: 37dab60111c71d011fc4964e9a8b4b05ac544bc0ba8155e895518680066c2adb
size: 976
original:
hackage: servant-quickcheck-0.0.10.0@sha256:1d5849d703c2487752f8fc7391cca7c998ee24f54ca0bb72d238bf99b64ac667,3755
- completed:
hackage: servant-flatten-0.2@sha256:276896f7c5cdec5b8f8493f6205fded0cc602d050b58fdb09a6d7c85c3bb0837,1234
pantry-tree:
size: 325
sha256: 04f12c7bef2c3f9a25d94eb9489752ed498db8e243069fe95838dbb51df1dcb3
size: 325
original:
hackage: servant-flatten-0.2@sha256:276896f7c5cdec5b8f8493f6205fded0cc602d050b58fdb09a6d7c85c3bb0837,1234
- completed:
hackage: network-arbitrary-0.7.0.0@sha256:0cd381c80ae20c16048936edcdb018b1d9fbe2b6ac8c44e908df403a5c6d7cd5,2520
pantry-tree:
size: 912
sha256: a40b62eddfb12cfec753a10836a4ef5fe8ec94d7478e6957e1fe5729017928fb
size: 912
original:
hackage: network-arbitrary-0.7.0.0@sha256:0cd381c80ae20c16048936edcdb018b1d9fbe2b6ac8c44e908df403a5c6d7cd5,2520
- completed:
hackage: saltine-0.2.0.0@sha256:2232a285ef326b0942bbcbfa6f465933a020f27e19552213e688fe371d66dddd,5198
pantry-tree:
size: 5016
sha256: fdf4397f4b1ed7975f38d0b463eb6c9d206d0c85d157c41c19983e80b2005763
size: 5016
original:
hackage: saltine-0.2.0.0@sha256:2232a285ef326b0942bbcbfa6f465933a020f27e19552213e688fe371d66dddd,5198
- completed:
hackage: persistent-postgresql-2.13.0.3@sha256:43384bf8ed9c931c673e6abb763c8811113d1b7004095faaae1eb42e2cd52d8f,3601
pantry-tree:
size: 1059
sha256: 2d647a17372e42bc54331cfb35f5a55a71e6854dac8299b7ed6a1c69ae12734d
size: 1059
original:
hackage: persistent-postgresql-2.13.0.3@sha256:43384bf8ed9c931c673e6abb763c8811113d1b7004095faaae1eb42e2cd52d8f,3601
snapshots:
- completed:
sha256: c632012da648385b9fa3c29f4e0afd56ead299f1c5528ee789058be410e883c0
size: 585393
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/0.yaml
sha256: c632012da648385b9fa3c29f4e0afd56ead299f1c5528ee789058be410e883c0
original: lts-18.0