Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b050a4c31 | ||
|
|
96085213fe | ||
|
|
2ce2b457bf | ||
|
|
a2171aa27b | ||
|
|
ea3d71c0df | ||
|
|
b154be24ec | ||
|
|
3590c9172c | ||
|
|
e981868246 | ||
|
|
5ee8045916 | ||
|
|
36086722b3 | ||
|
|
8edd5946e5 | ||
|
|
a0b2a28ee2 | ||
|
|
39a845ad31 | ||
|
|
669bdc7e38 | ||
|
|
5d4c073730 | ||
|
|
48ca83f31d | ||
|
|
fff4060b31 | ||
|
|
9fdda038a9 | ||
|
|
ef67409d61 | ||
|
|
d90472014d | ||
|
|
a2b67b933e | ||
|
|
b98e881d84 | ||
|
|
e978621597 | ||
|
|
5fe52b9cfe | ||
|
|
5c6d00d545 | ||
|
|
6429a5b31a | ||
|
|
e68c8305a2 | ||
|
|
e095d382b3 | ||
|
|
25ada15546 | ||
|
|
5581f0909a | ||
|
|
462b86df8d | ||
|
|
6645625e6b | ||
|
|
cfb68d73a0 | ||
|
|
9574f43f87 | ||
|
|
a53be65ab0 | ||
|
|
cc989c5c08 | ||
|
|
313224e6f5 | ||
|
|
2adb29ffc0 | ||
|
|
80ccd62d38 | ||
|
|
b81ff45d34 | ||
|
|
81b78dd2b2 | ||
|
|
e2302a6c9b | ||
|
|
2486b79450 | ||
|
|
0b52ef6eb0 | ||
|
|
a533620684 | ||
|
|
09d8d0f362 | ||
|
|
4e067835c3 | ||
|
|
37278f2cd3 | ||
|
|
16d2a3096a | ||
|
|
083509eb97 | ||
|
|
0c154deeec | ||
|
|
082c9707c0 | ||
|
|
15798ee168 | ||
|
|
e37b7eae3f | ||
|
|
ae2d588f46 | ||
|
|
12d93d0805 | ||
|
|
2549688bdf | ||
|
|
c2ed799113 | ||
|
|
71526ac79f | ||
|
|
3d685ef96c | ||
|
|
2fdde6218a | ||
|
|
09693d14d1 | ||
|
|
dcaeb20e29 | ||
|
|
d93ec3bb91 | ||
|
|
f29852f6f0 | ||
|
|
7d5fc84747 | ||
|
|
4a3a5174b2 | ||
|
|
e0d094b2aa | ||
|
|
e3190b86ab | ||
|
|
b9b0a573e5 | ||
|
|
0dbfbd8dfc | ||
|
|
6e42d9113b | ||
|
|
460fb7ec29 | ||
|
|
c86a2b643a | ||
|
|
b2042f48cd | ||
|
|
d276f37e87 | ||
|
|
7c88ee7cff | ||
|
|
93ddc4a5ba | ||
|
|
9f12747d9b | ||
|
|
5a086a9173 | ||
|
|
e1067ffe67 | ||
|
|
d5f537aae4 | ||
|
|
5b12483416 | ||
|
|
07eb541806 | ||
|
|
065a3aa2f5 | ||
|
|
2aa2d79de2 | ||
|
|
a0deab901d | ||
|
|
4bc4ca1ba9 | ||
|
|
ac8e8961ce | ||
|
|
2c51925638 | ||
|
|
e0eac875b6 | ||
|
|
9ac08c263b | ||
|
|
658a2de619 | ||
|
|
a487a51135 | ||
|
|
2d58f60a53 | ||
|
|
faa49687be | ||
|
|
3ddf941cd7 | ||
|
|
37dece2cd8 | ||
|
|
1ead82f9b8 |
No files matched your search
@@ -23,19 +23,18 @@ Python Dependencies
|
||||
|
||||
Name Version Licence URL
|
||||
---- ------- ------- ---
|
||||
cheroot 8.5.2 UNKNOWN https://cheroot.cherrypy.org
|
||||
Flask 1.1.2 BSD-3-Clause https://palletsprojects.com/p/flask/
|
||||
Flask 1.1.4 BSD-3-Clause https://palletsprojects.com/p/flask/
|
||||
Flask-Gravatar 0.5.0 BSD https://github.com/zzzsochi/Flask-Gravatar/
|
||||
Flask-Login 0.5.0 MIT https://github.com/maxcountryman/flask-login
|
||||
Flask-Mail 0.9.1 BSD https://github.com/rduplain/flask-mail
|
||||
Flask-Migrate 2.6.0 MIT http://github.com/miguelgrinberg/flask-migrate/
|
||||
Flask-SQLAlchemy 2.4.4 BSD-3-Clause https://github.com/pallets/flask-sqlalchemy
|
||||
Flask-Migrate 2.7.0 MIT http://github.com/miguelgrinberg/flask-migrate/
|
||||
Flask-SQLAlchemy 2.5.1 BSD-3-Clause https://github.com/pallets/flask-sqlalchemy
|
||||
Flask-WTF 0.14.3 BSD https://github.com/lepture/flask-wtf
|
||||
Flask-Compress 1.8.0 MIT https://github.com/colour-science/flask-compress
|
||||
Flask-Compress 1.9.0 MIT https://github.com/colour-science/flask-compress
|
||||
passlib 1.7.4 BSD https://passlib.readthedocs.io
|
||||
pytz 2021.1 MIT http://pythonhosted.org/pytz
|
||||
simplejson 3.17.2 MIT License https://github.com/simplejson/simplejson
|
||||
six 1.15.0 MIT https://github.com/benjaminp/six
|
||||
six 1.16.0 MIT https://github.com/benjaminp/six
|
||||
speaklater3 1.4 UNKNOWN https://github.com/ThomasWaldmann/speaklater
|
||||
sqlparse 0.4.1 BSD-3-Clause https://github.com/andialbrecht/sqlparse
|
||||
WTForms 2.3.3 BSD-3-Clause https://wtforms.readthedocs.io/
|
||||
@@ -43,16 +42,27 @@ Flask-Paranoid 0.2.0
|
||||
psutil 5.8.0 BSD https://github.com/giampaolo/psutil
|
||||
psycopg2 2.8.6 LGPL with exceptions https://psycopg.org/
|
||||
python-dateutil 2.8.1 Dual License https://dateutil.readthedocs.io
|
||||
SQLAlchemy 1.3.23 MIT http://www.sqlalchemy.org
|
||||
Flask-Security-Too 3.4.5 MIT https://github.com/Flask-Middleware/flask-security
|
||||
SQLAlchemy 1.3.24 MIT http://www.sqlalchemy.org
|
||||
itsdangerous 1.1.0 BSD https://palletsprojects.com/p/itsdangerous/
|
||||
Flask-Security-Too 4.0.1 MIT https://github.com/Flask-Middleware/flask-security
|
||||
bcrypt 3.2.0 Apache License, Version 2.0 https://github.com/pyca/bcrypt/
|
||||
cryptography 3.3.1 BSD or Apache License, Version 2.0 https://github.com/pyca/cryptography
|
||||
cryptography 3.4.7 BSD or Apache License, Version 2.0 https://github.com/pyca/cryptography
|
||||
sshtunnel 0.4.0 MIT https://github.com/pahaz/sshtunnel
|
||||
ldap3 2.9 LGPL v3 https://github.com/cannatag/ldap3
|
||||
Flask-BabelEx 0.9.4 BSD http://github.com/mrjoes/flask-babelex
|
||||
gssapi 1.6.12 LICENSE.txt https://github.com/pythongssapi/python-gssapi
|
||||
Flask-SocketIO 5.0.3 MIT http://github.com/miguelgrinberg/Flask-SocketIO/
|
||||
eventlet 0.31.0 UNKNOWN http://eventlet.net
|
||||
httpagentparser 1.9.1 http://www.opensource.org/licenses/mit-license.php http://shon.github.com/httpagentparser
|
||||
user-agents 2.2.0 MIT https://github.com/selwin/python-user-agents
|
||||
pywinpty 1.1.1 Unknown Unknown
|
||||
Authlib 0.15.4 BSD-3-Clause https://authlib.org/
|
||||
requests 2.25.1 Apache 2.0 https://requests.readthedocs.io
|
||||
|
||||
28 dependencies listed.
|
||||
NOTE: This report was generated using Python 3.9. Full information may not be
|
||||
shown for Python modules that are not required with this version.
|
||||
|
||||
35 dependencies listed.
|
||||
|
||||
Javascript Dependencies
|
||||
=======================
|
||||
@@ -61,11 +71,11 @@ Name Version
|
||||
---- ------- ------- ---
|
||||
@babel/code-frame 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/compat-data 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/core 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/generator 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/core 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/generator 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-annotate-as-pure 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-compilation-targets 7.13.16 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-create-class-features-plugin 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-create-class-features-plugin 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-function-name 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-get-function-arity 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-member-expression-to-functions 7.13.12 MIT https://github.com/babel/babel.git
|
||||
@@ -73,18 +83,18 @@ Name Version
|
||||
@babel/helper-module-transforms 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-optimise-call-expression 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-plugin-utils 7.13.0 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-replace-supers 7.13.12 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-replace-supers 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-simple-access 7.13.12 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-split-export-declaration 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-validator-identifier 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-validator-option 7.12.17 MIT https://github.com/babel/babel.git
|
||||
@babel/helpers 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/highlight 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/parser 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/parser 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-proposal-class-properties 7.13.0 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-syntax-jsx 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-display-name 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-jsx 7.13.12 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-jsx 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-jsx-development 7.12.17 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-pure-annotations 7.12.1 MIT https://github.com/babel/babel.git
|
||||
@babel/preset-react 7.13.13 MIT https://github.com/babel/babel.git
|
||||
@@ -101,8 +111,9 @@ Name Version
|
||||
@projectstorm/react-diagrams-routing 6.5.2 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@simonwep/pickr 1.8.1 MIT https://github.com/Simonwep/pickr.git
|
||||
@tippyjs/react 4.2.5 MIT git+https://github.com/atomiks/tippyjs-react.git
|
||||
@types/component-emitter 1.2.10 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/json-schema 7.0.7 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/node 15.0.3 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/node 15.6.1 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/parse-json 4.0.0 MIT https://www.github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
acitree 4.5.0-rc.7 MIT https://github.com/imsurinder90/jquery-aciTree.git
|
||||
ajv 6.12.6 MIT https://github.com/ajv-validator/ajv.git
|
||||
@@ -131,8 +142,10 @@ backform 0.2.0
|
||||
backgrid 0.3.8 MIT http://github.com/cloudflare/backgrid
|
||||
backgrid-filter 0.3.7 MIT git://github.com/wyuenho/backgrid-text-cell.git
|
||||
backgrid-select-all 0.3.5 MIT git://github.com/wyuenho/backgrid-select-all.git
|
||||
backo2 1.0.2 MIT https://github.com/mokesmokes/backo.git
|
||||
balanced-match 1.0.2 MIT git://github.com/juliangruber/balanced-match.git
|
||||
base64-arraybuffer 0.2.0 MIT https://github.com/niklasvh/base64-arraybuffer
|
||||
base64-arraybuffer 0.1.4 MIT https://github.com/niklasvh/base64-arraybuffer
|
||||
big.js 5.2.2 MIT https://github.com/MikeMcl/big.js.git
|
||||
bignumber.js 9.0.1 MIT https://github.com/MikeMcl/bignumber.js.git
|
||||
bignumber.js 7.2.1 MIT https://github.com/MikeMcl/bignumber.js.git
|
||||
@@ -141,7 +154,6 @@ bootstrap4-toggle 3.6.1
|
||||
brace-expansion 1.1.11 MIT git://github.com/juliangruber/brace-expansion.git
|
||||
browserslist 4.16.6 MIT https://github.com/browserslist/browserslist.git
|
||||
callsites 3.1.0 MIT https://github.com/sindresorhus/callsites.git
|
||||
camelcase 6.2.0 MIT https://github.com/sindresorhus/camelcase.git
|
||||
caniuse-api 3.0.0 MIT https://github.com/nyalab/caniuse-api.git
|
||||
chalk 2.4.2 MIT https://github.com/chalk/chalk.git
|
||||
chalk 4.1.1 MIT https://github.com/chalk/chalk.git
|
||||
@@ -151,38 +163,39 @@ chartjs-color 2.4.1
|
||||
chartjs-color-string 0.6.0 MIT https://github.com/chartjs/chartjs-color-string.git
|
||||
closest 0.0.1 MIT https://github.com/ForbesLindesay/closest.git
|
||||
co 4.6.0 MIT https://github.com/tj/co.git
|
||||
codemirror 5.61.0 MIT https://github.com/codemirror/CodeMirror.git
|
||||
color 3.1.3 MIT https://github.com/Qix-/color.git
|
||||
codemirror 5.61.1 MIT https://github.com/codemirror/CodeMirror.git
|
||||
color-convert 1.9.3 MIT https://github.com/Qix-/color-convert.git
|
||||
color-convert 2.0.1 MIT https://github.com/Qix-/color-convert.git
|
||||
color-name 1.1.3 MIT git@github.com:dfcreative/color-name.git
|
||||
color-name 1.1.4 MIT git@github.com:colorjs/color-name.git
|
||||
color-string 1.5.5 MIT https://github.com/Qix-/color-string.git
|
||||
colord 2.0.0 MIT https://github.com/omgovich/colord.git
|
||||
colorette 1.2.2 MIT https://github.com/jorgebucaran/colorette.git
|
||||
commander 7.2.0 MIT https://github.com/tj/commander.js.git
|
||||
component-emitter 1.3.0 MIT https://github.com/component/emitter.git
|
||||
concat-map 0.0.1 MIT git://github.com/substack/node-concat-map.git
|
||||
convert-source-map 1.7.0 MIT git://github.com/thlorenz/convert-source-map.git
|
||||
core-js 3.12.1 MIT https://github.com/zloirock/core-js.git
|
||||
core-js 3.13.0 MIT https://github.com/zloirock/core-js.git
|
||||
core-js 2.6.12 MIT https://github.com/zloirock/core-js.git
|
||||
cosmiconfig 7.0.0 MIT git+https://github.com/davidtheclark/cosmiconfig.git
|
||||
css-color-names 1.0.1 MIT git://github.com/bahamas10/css-color-names.git
|
||||
css-color-names 0.0.4 MIT git://github.com/bahamas10/css-color-names.git
|
||||
css-line-break 1.1.1 MIT git+ssh://git@github.com/niklasvh/css-line-break.git
|
||||
css-loader 5.2.4 MIT https://github.com/webpack-contrib/css-loader.git
|
||||
css-loader 5.2.6 MIT https://github.com/webpack-contrib/css-loader.git
|
||||
css-tree 1.1.3 MIT https://github.com/csstree/csstree.git
|
||||
cssesc 3.0.0 MIT https://github.com/mathiasbynens/cssesc.git
|
||||
cssnano 5.0.2 MIT https://github.com/cssnano/cssnano.git
|
||||
cssnano-preset-default 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
cssnano-utils 2.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
cssnano 5.0.4 MIT https://github.com/cssnano/cssnano.git
|
||||
cssnano-preset-default 5.1.1 MIT https://github.com/cssnano/cssnano.git
|
||||
cssnano-utils 2.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
csso 4.2.0 MIT https://github.com/css/csso.git
|
||||
dagre 0.8.5 MIT https://github.com/dagrejs/dagre.git
|
||||
debug 4.3.1 MIT git://github.com/visionmedia/debug.git
|
||||
debug 2.6.9 MIT git://github.com/visionmedia/debug.git
|
||||
detect-indent 4.0.0 MIT https://github.com/sindresorhus/detect-indent.git
|
||||
dom-serializer 1.3.1 MIT git://github.com/cheeriojs/dom-renderer.git
|
||||
dot-prop 5.3.0 MIT https://github.com/sindresorhus/dot-prop.git
|
||||
dom-serializer 1.3.2 MIT git://github.com/cheeriojs/dom-renderer.git
|
||||
dropzone 5.9.2 MIT https://github.com/dropzone/dropzone.git
|
||||
emojis-list 3.0.0 MIT git+https://github.com/kikobeats/emojis-list.git
|
||||
engine.io-client 5.1.1 MIT https://github.com/socketio/engine.io-client.git
|
||||
engine.io-parser 4.0.2 MIT git@github.com:socketio/engine.io-parser.git
|
||||
error-ex 1.3.2 MIT https://github.com/qix-/node-error-ex.git
|
||||
escalade 3.1.1 MIT https://github.com/lukeed/escalade.git
|
||||
escape-string-regexp 1.0.5 MIT https://github.com/sindresorhus/escape-string-regexp.git
|
||||
@@ -195,6 +208,7 @@ globals 11.12.0
|
||||
globals 9.18.0 MIT https://github.com/sindresorhus/globals.git
|
||||
graphlib 2.1.8 MIT https://github.com/dagrejs/graphlib.git
|
||||
has-ansi 2.0.0 MIT https://github.com/sindresorhus/has-ansi.git
|
||||
has-cors 1.1.0 MIT git://github.com/component/has-cors.git
|
||||
has-flag 3.0.0 MIT https://github.com/sindresorhus/has-flag.git
|
||||
has-flag 4.0.0 MIT https://github.com/sindresorhus/has-flag.git
|
||||
hex-color-regex 1.1.0 MIT https://github.com/regexps/hex-color-regex.git
|
||||
@@ -205,16 +219,13 @@ html2canvas 1.0.0-rc.7
|
||||
immutability-helper 3.1.1 MIT git+https://github.com/kolodny/immutability-helper.git
|
||||
import-fresh 3.3.0 MIT https://github.com/sindresorhus/import-fresh.git
|
||||
imports-loader 2.0.0 MIT https://github.com/webpack-contrib/imports-loader.git
|
||||
indexes-of 1.0.1 MIT git://github.com/dominictarr/indexes-of.git
|
||||
invariant 2.2.4 MIT https://github.com/zertosh/invariant
|
||||
ip-address 7.1.0 MIT git://github.com/beaugunderson/ip-address.git
|
||||
is-absolute-url 3.0.3 MIT https://github.com/sindresorhus/is-absolute-url.git
|
||||
is-any-array 1.0.0 MIT https://github.com/cheminfo-js/is-any-array.git
|
||||
is-arrayish 0.2.1 MIT https://github.com/qix-/node-is-arrayish.git
|
||||
is-arrayish 0.3.2 MIT https://github.com/qix-/node-is-arrayish.git
|
||||
is-color-stop 1.1.0 MIT git+https://github.com/pigcan/is-color-stop.git
|
||||
is-finite 1.1.0 MIT https://github.com/sindresorhus/is-finite.git
|
||||
is-obj 2.0.0 MIT https://github.com/sindresorhus/is-obj.git
|
||||
istanbul-instrumenter-loader 3.0.1 MIT https://github.com/webpack-contrib/istanbul-instrumenter-loader.git
|
||||
jquery 3.6.0 MIT https://github.com/jquery/jquery.git
|
||||
jquery-contextmenu 2.9.2 MIT git://github.com/swisnl/jQuery-contextMenu.git
|
||||
@@ -253,46 +264,47 @@ ms 2.1.2
|
||||
ms 2.0.0 MIT https://github.com/zeit/ms.git
|
||||
nanoid 3.1.23 MIT https://github.com/ai/nanoid.git
|
||||
nanopop 2.1.0 MIT https://github.com/Simonwep/nanopop.git
|
||||
node-releases 1.1.71 MIT git+https://github.com/chicoxyzzy/node-releases.git
|
||||
normalize-url 4.5.0 MIT https://github.com/sindresorhus/normalize-url.git
|
||||
node-releases 1.1.72 MIT git+https://github.com/chicoxyzzy/node-releases.git
|
||||
normalize-url 4.5.1 MIT https://github.com/sindresorhus/normalize-url.git
|
||||
object-assign 4.1.1 MIT https://github.com/sindresorhus/object-assign.git
|
||||
parent-module 1.0.1 MIT https://github.com/sindresorhus/parent-module.git
|
||||
parse-json 5.2.0 MIT https://github.com/sindresorhus/parse-json.git
|
||||
parseqs 0.0.6 MIT https://github.com/get/querystring.git
|
||||
parseuri 0.0.6 MIT https://github.com/get/parseuri.git
|
||||
path-type 4.0.0 MIT https://github.com/sindresorhus/path-type.git
|
||||
pathfinding 0.4.18 MIT git://github.com/qiao/PathFinding.js.git
|
||||
performance-now 2.1.0 MIT git://github.com/braveg1rl/performance-now.git
|
||||
popper.js 1.16.1 MIT git+https://github.com/FezVrasta/popper.js.git
|
||||
postcss 8.2.15 MIT https://github.com/postcss/postcss.git
|
||||
postcss 8.3.0 MIT https://github.com/postcss/postcss.git
|
||||
postcss-calc 8.0.0 MIT https://github.com/postcss/postcss-calc.git
|
||||
postcss-colormin 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-convert-values 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-discard-comments 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-discard-duplicates 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-discard-empty 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-discard-overridden 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-merge-longhand 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-merge-rules 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-minify-font-values 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-minify-gradients 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-minify-params 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-minify-selectors 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-colormin 5.1.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-convert-values 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-discard-comments 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-discard-duplicates 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-discard-empty 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-discard-overridden 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-merge-longhand 5.0.2 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-merge-rules 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-minify-font-values 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-minify-gradients 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-minify-params 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-minify-selectors 5.1.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-modules-local-by-default 4.0.0 MIT https://github.com/css-modules/postcss-modules-local-by-default.git
|
||||
postcss-normalize-charset 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-display-values 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-positions 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-repeat-style 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-string 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-timing-functions 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-unicode 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-url 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-whitespace 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-ordered-values 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-reduce-initial 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-reduce-transforms 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-charset 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-display-values 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-positions 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-repeat-style 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-string 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-timing-functions 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-unicode 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-url 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-normalize-whitespace 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-ordered-values 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-reduce-initial 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-reduce-transforms 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-selector-parser 6.0.6 MIT https://github.com/postcss/postcss-selector-parser.git
|
||||
postcss-selector-parser 3.1.2 MIT https://github.com/postcss/postcss-selector-parser.git
|
||||
postcss-svgo 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-unique-selectors 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-svgo 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-unique-selectors 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-value-parser 4.1.0 MIT https://github.com/TrySound/postcss-value-parser.git
|
||||
punycode 2.1.1 MIT https://github.com/bestiejs/punycode.js.git
|
||||
raf 3.4.1 MIT git://github.com/chrisdickinson/raf.git
|
||||
@@ -309,15 +321,16 @@ schema-utils 3.0.0
|
||||
schema-utils 0.3.0 MIT git+https://github.com/webpack-contrib/schema-utils.git
|
||||
select2 4.0.13 MIT git://github.com/select2/select2.git
|
||||
shim-loader 1.0.1 MIT https://github.com/zinserjan/shim-loader
|
||||
simple-swizzle 0.2.2 MIT https://github.com/qix-/node-simple-swizzle.git
|
||||
slickgrid 2.3.16 MIT git+https://github.com/6pac/SlickGrid.git
|
||||
snapsvg-cjs 0.0.6 MIT git+https://github.com/geelen/Snap.svg-cjs.git
|
||||
socket.io-client 4.1.2 MIT https://github.com/socketio/socket.io-client.git
|
||||
socket.io-parser 4.0.4 MIT https://github.com/socketio/socket.io-parser.git
|
||||
source-list-map 1.1.2 MIT https://github.com/webpack/source-list-map.git
|
||||
split.js 1.6.4 MIT https://github.com/nathancahill/split
|
||||
stable 0.1.8 MIT https://github.com/Two-Screen/stable.git
|
||||
strip-ansi 3.0.1 MIT https://github.com/chalk/strip-ansi.git
|
||||
strip-comments 2.0.1 MIT https://github.com/jonschlinkert/strip-comments.git
|
||||
stylehacks 5.0.0 MIT https://github.com/cssnano/cssnano.git
|
||||
stylehacks 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
supports-color 5.5.0 MIT https://github.com/chalk/supports-color.git
|
||||
supports-color 7.2.0 MIT https://github.com/chalk/supports-color.git
|
||||
supports-color 2.0.0 MIT https://github.com/chalk/supports-color.git
|
||||
@@ -330,17 +343,22 @@ to-fast-properties 2.0.0
|
||||
to-fast-properties 1.0.3 MIT https://github.com/sindresorhus/to-fast-properties.git
|
||||
trim-right 1.0.1 MIT https://github.com/sindresorhus/trim-right.git
|
||||
underscore 1.13.1 MIT git://github.com/jashkenas/underscore.git
|
||||
uniq 1.0.1 MIT git://github.com/mikolalysenko/uniq.git
|
||||
uniqs 2.0.0 MIT git://github.com/fgnass/uniqs.git
|
||||
util-deprecate 1.0.2 MIT git://github.com/TooTallNate/util-deprecate.git
|
||||
vendors 1.0.4 MIT https://github.com/wooorm/vendors.git
|
||||
webpack-sources 0.2.3 MIT git+https://github.com/webpack/webpack-sources.git
|
||||
wkx 0.5.0 MIT http://github.com/cschwarz/wkx.git
|
||||
ws 7.4.6 MIT https://github.com/websockets/ws.git
|
||||
xterm 4.12.0 MIT https://github.com/xtermjs/xterm.js
|
||||
xterm-addon-fit 0.5.0 MIT https://github.com/xtermjs/xterm.js
|
||||
xterm-addon-search 0.8.0 MIT https://github.com/xtermjs/xterm.js
|
||||
xterm-addon-web-links 0.4.0 MIT https://github.com/xtermjs/xterm.js
|
||||
yeast 0.1.2 MIT https://github.com/unshiftio/yeast.git
|
||||
@fortawesome/fontawesome-free 5.15.3 (CC-BY-4.0 AND OFL-1.1 AND MIT) https://github.com/FortAwesome/Font-Awesome
|
||||
@trysound/sax 0.1.1 ISC git://github.com/svg/sax.git
|
||||
boolbase 1.0.0 ISC https://github.com/fb55/boolbase
|
||||
css-declaration-sorter 6.0.0 ISC https://github.com/Siilwyn/css-declaration-sorter.git
|
||||
electron-to-chromium 1.3.727 ISC https://github.com/kilian/electron-to-chromium/
|
||||
css-declaration-sorter 6.0.3 ISC https://github.com/Siilwyn/css-declaration-sorter.git
|
||||
electron-to-chromium 1.3.740 ISC https://github.com/kilian/electron-to-chromium/
|
||||
icss-utils 5.1.0 ISC git+https://github.com/css-modules/icss-utils.git
|
||||
is-resolvable 1.1.0 ISC https://github.com/shinnn/is-resolvable.git
|
||||
lru-cache 6.0.0 ISC git://github.com/isaacs/node-lru-cache.git
|
||||
@@ -357,7 +375,7 @@ bootstrap-datepicker 1.9.0
|
||||
eve 0.5.4 Apache-2.0 git@github.com:adobe-webplatform/eve.git
|
||||
paths-js 0.4.11 Apache-2.0 https://github.com/andreaferretti/paths-js.git
|
||||
snapsvg 0.5.1 Apache-2.0 git@github.com:adobe-webplatform/Snap.svg.git
|
||||
caniuse-lite 1.0.30001228 CC-BY-4.0 https://github.com/browserslist/caniuse-lite.git
|
||||
caniuse-lite 1.0.30001230 CC-BY-4.0 https://github.com/browserslist/caniuse-lite.git
|
||||
css-select 3.1.2 BSD-2-Clause git://github.com/fb55/css-select.git
|
||||
css-what 4.0.0 BSD-2-Clause https://github.com/fb55/css-what
|
||||
domelementtype 2.2.0 BSD-2-Clause git://github.com/fb55/domelementtype.git
|
||||
@@ -379,12 +397,13 @@ istanbul-lib-source-maps 4.0.0
|
||||
istanbul-reports 3.0.2 BSD-3-Clause git+ssh://git@github.com/istanbuljs/istanbuljs.git
|
||||
source-map 0.5.7 BSD-3-Clause http://github.com/mozilla/source-map.git
|
||||
source-map 0.6.1 BSD-3-Clause http://github.com/mozilla/source-map.git
|
||||
source-map-js 0.6.2 BSD-3-Clause http://github.com/7rulnik/source-map.git
|
||||
sprintf-js 1.1.2 BSD-3-Clause https://github.com/alexei/sprintf.js.git
|
||||
mdn-data 2.0.14 CC0-1.0 https://github.com/mdn/data.git
|
||||
mousetrap 1.6.5 Apache-2.0 WITH LLVM-exception git://github.com/ccampbell/mousetrap.git
|
||||
precond 0.2.3 MIT* https://github.com/MathieuTurcotte/node-precond.git
|
||||
webcabin-docker 2.2.4-dev MIT* Unknown
|
||||
webcabin-docker 2.2.5 MIT* Unknown
|
||||
tablesorter 2.31.3 (MIT OR GPL-2.0) git://github.com/Mottie/tablesorter.git
|
||||
|
||||
326 dependencies listed.
|
||||
335 dependencies listed.
|
||||
|
||||
@@ -142,7 +142,7 @@ msg-extract:
|
||||
cd web && pybabel extract -F babel.cfg -o pgadmin/messages.pot pgadmin
|
||||
|
||||
msg-update:
|
||||
cd web && pybabel update -i pgadmin/messages.pot -d pgadmin/translations
|
||||
cd web && pybabel update --no-fuzzy-matching -i pgadmin/messages.pot -d pgadmin/translations
|
||||
|
||||
.PHONY: docs
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ The configuration files are as follows:
|
||||
|
||||
Linux,/etc/pgadmin/config_system.py
|
||||
macOS,/Library/Preferences/pgadmin/config_system.py
|
||||
Windows,%CommonProgramFiles%\pgadmin\config_system.py
|
||||
Windows,%CommonProgramFiles%\\pgadmin\\config_system.py
|
||||
|
||||
.. note:: If the SERVER_MODE setting is changed in ``config_distro.py``,
|
||||
``config_local.py``, or ``config_system.py`` you will most likely need to
|
||||
|
||||
@@ -23,8 +23,19 @@ server:
|
||||
* PostgreSQL 12: */usr/local/pgsql-12*
|
||||
* PostgreSQL 13: */usr/local/pgsql-13*
|
||||
|
||||
The most recent version of the utilities is used by default; this may be
|
||||
changed in the :ref:`preferences`.
|
||||
The default binary paths set in the container are as follows:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
'pg-13': '/usr/local/pgsql-13'
|
||||
'pg-12': '/usr/local/pgsql-12'
|
||||
'pg-11': '/usr/local/pgsql-11'
|
||||
'pg-10': '/usr/local/pgsql-10'
|
||||
'pg-9.6': '/usr/local/pgsql-9.6'
|
||||
}
|
||||
|
||||
this may be changed in the :ref:`preferences`.
|
||||
|
||||
Environment Variables
|
||||
*********************
|
||||
@@ -104,7 +115,7 @@ Adjust the number of threads the Gunicorn server uses to handle incoming
|
||||
requests. This should typically be left as-is, except in highly loaded systems
|
||||
where it may be increased.
|
||||
|
||||
**PGADMIN_CONFIG_**
|
||||
**PGADMIN_CONFIG_***
|
||||
|
||||
This is a variable prefix that can be used to override any of the configuration
|
||||
options in pgAdmin's *config.py* file. Add the *PGADMIN_CONFIG_* prefix to any
|
||||
@@ -117,6 +128,12 @@ is read after */pgadmin4/config.py* and before */pgadmin4/config_local.py*.
|
||||
Any settings given will therefore override anything in config.py, but can be
|
||||
overridden by settings in config_local.py.
|
||||
|
||||
Settings are only written to */pgadmin4/config_distro.py* once, typically on
|
||||
first launch of the container. If */pgadmin4/config_distro.py* contains one or
|
||||
more lines, then no changes are made; for example, if the container instance is
|
||||
restarted, or */pgadmin4/config_distro.py* is mapped to a file on persistent
|
||||
storage (not recommended - use */pgadmin4/config_local.py* instead)!
|
||||
|
||||
See :ref:`config_py` for more information on the available configuration settings.
|
||||
|
||||
Mapped Files and Directories
|
||||
|
||||
@@ -16,3 +16,4 @@ PL/SQL code.
|
||||
editgrid
|
||||
schema_diff
|
||||
erd_tool
|
||||
psql_tool
|
||||
@@ -37,6 +37,7 @@ Mode is pre-configured for security.
|
||||
change_user_password
|
||||
ldap
|
||||
kerberos
|
||||
oauth2
|
||||
|
||||
|
||||
.. note:: Pre-compiled and configured installation packages are available for
|
||||
|
||||
|
After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 237 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
@@ -34,6 +34,7 @@ from *config.py* file and modify the values for the following parameters.
|
||||
Please note that if it is not set, it will take the value of
|
||||
*default_server* parameter."
|
||||
|
||||
|
||||
Keytab file for HTTP Service
|
||||
============================
|
||||
|
||||
@@ -116,3 +117,13 @@ PostgreSQL Server settings to configure Kerberos Authentication
|
||||
|
||||
* Note that, you have to login into pgAdmin with Kerberos authentication to
|
||||
then connect to PostgreSQL using Kerberos.
|
||||
|
||||
|
||||
Master Password
|
||||
===============
|
||||
|
||||
In the multi user mode, pgAdmin uses user's login password to encrypt/decrypt the PostgreSQL server password.
|
||||
In the Kerberos authentication, the pgAdmin user does not have the password, so we need an encryption key to store
|
||||
the PostgreSQL server password for the servers which are not configured to use the Kerberos authentication.
|
||||
To accomplish this, set the configuration parameter MASTER_PASSWORD to *True*, so upon setting the master password,
|
||||
it will be used as an encryption key while storing the password. If it is False, the server password can not be stored.
|
||||
@@ -18,4 +18,5 @@ database, right-click on the *Databases* node, and select *Create Database...*
|
||||
move_objects
|
||||
resource_group_dialog
|
||||
role_dialog
|
||||
tablespace_dialog
|
||||
tablespace_dialog
|
||||
role_reassign_dialog
|
||||
@@ -128,6 +128,8 @@ Use the *Tools* menu to access the following options (in alphabetical order):
|
||||
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| *Search Objects...* | Click to open the :ref:`Search Objects... <search_objects>` and start searching any kind of objects in a database. |
|
||||
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| *PSQL Tool* | Click to open the :ref:`PSQL Tool <psql_tool>` and start PSQL in the current database context. |
|
||||
+---------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
The Help Menu
|
||||
*************
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
.. _oauth2:
|
||||
|
||||
*****************************************
|
||||
`Enabling OAUTH2 Authentication`:index:
|
||||
*****************************************
|
||||
|
||||
|
||||
To enable OAUTH2 authentication for pgAdmin, you must configure the OAUTH2
|
||||
settings in the *config_local.py* or *config_system.py* file (see the
|
||||
:ref:`config.py <config_py>` documentation) on the system where pgAdmin is
|
||||
installed in Server mode. You can copy these settings from *config.py* file
|
||||
and modify the values for the following parameters:
|
||||
|
||||
|
||||
.. csv-table::
|
||||
:header: "**Parameter**", "**Description**"
|
||||
:class: longtable
|
||||
:widths: 35, 55
|
||||
|
||||
"AUTHENTICATION_SOURCES", "The default value for this parameter is *internal*.
|
||||
To enable OAUTH2 authentication, you must include *oauth2* in the list of values
|
||||
for this parameter. you can modify the value as follows:
|
||||
|
||||
* [‘oauth2’, ‘internal’]: pgAdmin will display an additional button for authenticating with oauth2"
|
||||
"OAUTH2_NAME", "The name of the Oauth2 provider, ex: Google, Github"
|
||||
"OAUTH2_DISPLAY_NAME", "Oauth2 display name in pgAdmin"
|
||||
"OAUTH2_CLIENT_ID", "Oauth2 Client ID"
|
||||
"OAUTH2_CLIENT_SECRET", "Oauth2 Client Secret"
|
||||
"OAUTH2_TOKEN_URL", "Oauth2 Access Token endpoint"
|
||||
"OAUTH2_AUTHORIZATION_URL", "Endpoint for user authorization"
|
||||
"OAUTH2_API_BASE_URL", "Oauth2 base URL endpoint to make requests simple, ex: *https://api.github.com/*"
|
||||
"OAUTH2_USERINFO_ENDPOINT", "User Endpoint, ex: *user* (for github) and *useinfo* (for google)"
|
||||
"OAUTH2_ICON", "The Font-awesome icon to be placed on the oauth2 button, ex: fa-github"
|
||||
"OAUTH2_BUTTON_COLOR", "Oauth2 button color"
|
||||
"OAUTH2_AUTO_CREATE_USER", "Set the value to *True* if you want to automatically
|
||||
create a pgAdmin user corresponding to a successfully authenticated Oauth2 user.
|
||||
Please note that password is not stored in the pgAdmin database."
|
||||
|
||||
Redirect URL
|
||||
============
|
||||
|
||||
The redirect url to configure Oauth2 server is *http://<pgAdmin Server URL>/oauth2/authorize*
|
||||
|
||||
Master Password
|
||||
===============
|
||||
|
||||
In the multi user mode, pgAdmin uses user's login password to encrypt/decrypt the PostgreSQL server password.
|
||||
In the Oauth2 authentication, the pgAdmin does not store the user's password, so we need an encryption key to store
|
||||
the PostgreSQL server password.
|
||||
To accomplish this, set the configuration parameter MASTER_PASSWORD to *True*, so upon setting the master password,
|
||||
it will be used as an encryption key while storing the password. If it is False, the server password can not be stored.
|
||||
|
||||
|
||||
Login Page
|
||||
============
|
||||
|
||||
After configuration, on restart, you can see the login page with the Oauth2 login button(s).
|
||||
|
||||
.. image:: images/oauth2_login.png
|
||||
:alt: Oauth2 login
|
||||
:align: center
|
||||
@@ -154,6 +154,9 @@ the graphs on the *Dashboard* tab:
|
||||
:alt: Preferences dialog dashboard display options
|
||||
:align: center
|
||||
|
||||
* Set the warning and alert threshold value to highlight the long-running
|
||||
queries on the dashboard.
|
||||
|
||||
* When the *Show activity?* switch is set to *True*, activity tables will be
|
||||
displayed on dashboards.
|
||||
|
||||
@@ -211,21 +214,23 @@ files.
|
||||
:align: center
|
||||
|
||||
Use the fields on the *Binary paths* panel to specify the path to the directory
|
||||
that contains the utility programs (pg_dump, pg_restore, and pg_dumpall) for
|
||||
that contains the utility programs (pg_dump, pg_dumpall, pg_restore and psql) for
|
||||
monitored databases:
|
||||
|
||||
* Use the *EDB Advanced Server Binary Path* field to specify the location of the
|
||||
EDB Postgres Advanced Server utility programs. If this path is not set,
|
||||
pgAdmin will attempt to find the utilities in standard locations used by
|
||||
EnterpriseDB.
|
||||
* Use the *EDB Advanced Server Binary Path* grid to specify the location of the
|
||||
EDB Postgres Advanced Server utility programs based on the server version.
|
||||
If the respective path is not set, then pgAdmin will pick up the path for which
|
||||
'Set as default' is checked else pgAdmin will attempt to find the utilities in
|
||||
standard locations used by EnterpriseDB.
|
||||
|
||||
* Use the *Greenplum Database Binary Path* field to specify the location of the
|
||||
Greenplum database utility programs. If this path is not set, pgAdmin will
|
||||
attempt to find the utilities in standard locations used by Greenplum.
|
||||
* Use the *PostgreSQL Binary Path* grid to specify the location of the
|
||||
PostgreSQL utility programs based on the server version. If the respective
|
||||
path is not set, then pgAdmin will pick up the path for which 'Set as default'
|
||||
is checked else pgAdmin will attempt to find the utilities in standard
|
||||
locations used by PostgreSQL.
|
||||
|
||||
* Use the *PostgreSQL Binary Path* field to specify the location of the
|
||||
PostgreSQL utility programs. If this path is not set, pgAdmin will attempt
|
||||
to find the utilities in standard locations used by PostgreSQL.
|
||||
**Note:** Use the 'Validate path' button to check the existence of the utility
|
||||
programs (pg_dump, pg_dumpall, pg_restore and psql) and there respective versions.
|
||||
|
||||
.. image:: images/preferences_paths_help.png
|
||||
:alt: Preferences dialog binary path help section
|
||||
@@ -372,6 +377,10 @@ Use the fields on the *Options* panel to manage editor preferences.
|
||||
Use the fields on the *Results grid* panel to specify your formatting
|
||||
preferences for copied data.
|
||||
|
||||
* Specify the maximum width of the column when 'Resize by data?' is set to True.
|
||||
If it is set to 0 then columns will auto-size to the maximum width of the data
|
||||
in the column. If 'Resize by data?' is set to False then this setting won't
|
||||
take any effect.
|
||||
* When the *Resize by data?* switch is set to *True*, then data columns will
|
||||
auto-size to the maximum width of the data in the column as loaded in the
|
||||
first batch. If False, the column will be sized to the widest of the data
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
.. _psql_tool:
|
||||
|
||||
******************
|
||||
`PSQL Tool`:index:
|
||||
******************
|
||||
|
||||
The PSQL tool allows users to connect to PostgreSQL or EDB Advanced server using
|
||||
the psql command line interface through their browser.
|
||||
|
||||
* Open the PSQL tool from the Tools or browser tree context menu, or use PSQL
|
||||
tool button at the top of the browser tree.
|
||||
|
||||
* PSQL will connect to the current connected database from the browser tree.
|
||||
|
||||
.. image:: images/psql_tool.png
|
||||
:alt: PSQL tool window
|
||||
:align: center
|
||||
|
||||
You can open multiple instances of the PSQL tool in individual tabs simultaneously.
|
||||
To close the PSQL tool, click the *X* in the upper-right hand corner of the tab bar.
|
||||
|
||||
**Note:** On the Windows platform, this feature is available on Windows 10 (1809
|
||||
version), and Windows Server 2019 and onwards.
|
||||
|
||||
**Note:** The PSQL tool is always available when pgAdmin is running in Desktop
|
||||
mode, but is disabled by default in Server mode. This is because users can run
|
||||
arbitrary shell commands through psql which may be considered a security risk in
|
||||
some deployments. System Administrators can enable the use of the PSQL tool in
|
||||
the pgAdmin configuration by setting the *ENABLE_PSQL* option to *True*; see
|
||||
:ref:`config_py` for more information.
|
||||
@@ -11,6 +11,8 @@ notes for it.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
release_notes_5_5
|
||||
release_notes_5_4
|
||||
release_notes_5_3
|
||||
release_notes_5_2
|
||||
release_notes_5_1
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
************
|
||||
Version 5.4
|
||||
************
|
||||
|
||||
Release date: 2021-06-17
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin4 5.3.
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #1561 <https://redmine.postgresql.org/issues/1561>`_ - Added browse button to select the binary path in the Preferences.
|
||||
| `Issue #1591 <https://redmine.postgresql.org/issues/1591>`_ - Added Grant Wizard option under Package node.
|
||||
| `Issue #2341 <https://redmine.postgresql.org/issues/2341>`_ - Added support to launch PSQL for the connected database server.
|
||||
| `Issue #4064 <https://redmine.postgresql.org/issues/4064>`_ - Added window maximize/restore functionality for properties dialog.
|
||||
| `Issue #5370 <https://redmine.postgresql.org/issues/5370>`_ - Added support to set the binary path for the different database server versions.
|
||||
| `Issue #6231 <https://redmine.postgresql.org/issues/6231>`_ - Added OS, Browser, Configuration details in the About dialog.
|
||||
| `Issue #6395 <https://redmine.postgresql.org/issues/6395>`_ - Added support for rotating the pgAdmin log file on the basis of size and age.
|
||||
| `Issue #6524 <https://redmine.postgresql.org/issues/6524>`_ - Support non-admin installation on Windows.
|
||||
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
| `Issue #4622 <https://redmine.postgresql.org/issues/4622>`_ - Added RESQL/MSQL test cases for Table and its child nodes.
|
||||
| `Issue #6225 <https://redmine.postgresql.org/issues/6225>`_ - Updated Flask-Security-Too to the latest v4.
|
||||
| `Issue #6460 <https://redmine.postgresql.org/issues/6460>`_ - Added a mechanism to detect a corrupt/broken config database file.
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #4203 <https://redmine.postgresql.org/issues/4203>`_ - Fixed the issue of renaming the database by another user.
|
||||
| `Issue #6404 <https://redmine.postgresql.org/issues/6404>`_ - Ensure that the Query Tool connection string should not be changed as per the 'Query Tool tab title'.
|
||||
| `Issue #6466 <https://redmine.postgresql.org/issues/6466>`_ - Ensure that the user should be able to add members in Login/Role group while creating it.
|
||||
| `Issue #6469 <https://redmine.postgresql.org/issues/6469>`_ - Ensure that the calendar control should be disabled in the properties panel for Role.
|
||||
| `Issue #6473 <https://redmine.postgresql.org/issues/6473>`_ - Disable browser password saving in the runtime.
|
||||
| `Issue #6478 <https://redmine.postgresql.org/issues/6478>`_ - Fixed duplicate SQL issue for tables with more than one partition.
|
||||
| `Issue #6482 <https://redmine.postgresql.org/issues/6482>`_ - Fixed an issue where the Foreground Color property of server dialog does not work.
|
||||
| `Issue #6513 <https://redmine.postgresql.org/issues/6513>`_ - Fixed an issue where pgAdmin does not open after password reset in server mode.
|
||||
| `Issue #6520 <https://redmine.postgresql.org/issues/6520>`_ - Fixed an issue where a decimal number is appended for character varying fields while downloading the data in CSV format.
|
||||
@@ -0,0 +1,37 @@
|
||||
************
|
||||
Version 5.5
|
||||
************
|
||||
|
||||
Release date: 2021-07-15
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin4 5.4.
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #1975 <https://redmine.postgresql.org/issues/1975>`_ - Highlighted long running queries on the dashboards.
|
||||
| `Issue #3893 <https://redmine.postgresql.org/issues/3893>`_ - Added support for Reassign/Drop Owned for login roles.
|
||||
| `Issue #3920 <https://redmine.postgresql.org/issues/3920>`_ - Do not block the query editor window when running a query.
|
||||
| `Issue #5940 <https://redmine.postgresql.org/issues/5940>`_ - Added support for OAuth 2 authentication.
|
||||
| `Issue #6559 <https://redmine.postgresql.org/issues/6559>`_ - Added option to provide maximum width of the column when 'Resize by data?’ option in the preferences is set to True.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #4189 <https://redmine.postgresql.org/issues/4189>`_ - Ensure that the Data Output panel can be snapped back after it is detached.
|
||||
| `Issue #6388 <https://redmine.postgresql.org/issues/6388>`_ - Fixed replace keyboard shortcut issue in the query tool on the normal keyboard layout.
|
||||
| `Issue #6398 <https://redmine.postgresql.org/issues/6398>`_ - Fixed an issue where detaching the query editor panel gives a blank white panel.
|
||||
| `Issue #6427 <https://redmine.postgresql.org/issues/6427>`_ - Remove leading whitespace and replace it with '[...] ' in the Query Tool data grid so cells don't look empty.
|
||||
| `Issue #6448 <https://redmine.postgresql.org/issues/6448>`_ - Fixed an issue in the search object when searching in 'all types' or 'subscription' if the user doesn't have access to the subscription.
|
||||
| `Issue #6489 <https://redmine.postgresql.org/issues/6489>`_ - Fixed an issue where Execute/Refresh button should not be disabled when we run the empty query.
|
||||
| `Issue #6505 <https://redmine.postgresql.org/issues/6505>`_ - Fixed an issue where the New Connection Drop Down has lost default maintenance database, auto-select, and tab-through functionality.
|
||||
| `Issue #6536 <https://redmine.postgresql.org/issues/6536>`_ - Fixed directory selection issue with the folder dialog.
|
||||
| `Issue #6541 <https://redmine.postgresql.org/issues/6541>`_ - Ensure that setting 'Open in new browser tab' should be visible, it should not be based on the value of 'ENABLE_PSQL'.
|
||||
| `Issue #6547 <https://redmine.postgresql.org/issues/6547>`_ - Fixed copy/paste issues for PSQL tool terminal.
|
||||
| `Issue #6550 <https://redmine.postgresql.org/issues/6550>`_ - Disable email deliverability check that was introduced in flask-security-too by default to maintain backwards compatibility.
|
||||
| `Issue #6555 <https://redmine.postgresql.org/issues/6555>`_ - Fixed Czech translation string for 'Login' keyword.
|
||||
| `Issue #6557 <https://redmine.postgresql.org/issues/6557>`_ - Fixed an issue where incorrect column name listed in the properties of Index.
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
.. _role_reassign_dialog:
|
||||
|
||||
**************************************
|
||||
`Role Reassign/Drop Own Dialog`:index:
|
||||
**************************************
|
||||
|
||||
Use the *Reassign/Drop Own* dialog to change the ownership of database objects owned
|
||||
by a database role. This dialog instructs the system to change the ownership of database
|
||||
objects owned by any of the *old_roles* to *new_role*.
|
||||
|
||||
The *Reassign/Drop Own* dialog organizes the Reassign & Drop role through General tab.
|
||||
|
||||
.. image:: images/role_reassign_dialog.png
|
||||
:alt: Reassign/Drop Own dialog
|
||||
:align: center
|
||||
|
||||
* Use the *Operation* field to provide Reassign option.
|
||||
* Provide a new role in the *Reassign Objects to* field; The ownership of all the objects within the selected database,
|
||||
and of all shared objects (databases, tablespaces), owned by the *old_role* will be reassigned to *new_role*.
|
||||
* Provide a database on which the reassignment is to be carried out.
|
||||
|
||||
The above example demonstrates reassigning *old_role* to *new_role*.
|
||||
|
||||
Click the *SQL* tab to continue.
|
||||
|
||||
.. image:: images/role_reassign_dialog_sql.png
|
||||
:alt: Reassign/Drop Own dialog sql
|
||||
:align: center
|
||||
|
||||
Removing database objects owned by a database role.
|
||||
|
||||
.. image:: images/role_drop_dialog.png
|
||||
:alt: Reassign/Drop Own dialog
|
||||
:align: center
|
||||
|
||||
* Use the *Operation* field to provide Drop option.
|
||||
* Use the *Cascade?* field to provide Yes, No is default.
|
||||
* Provide a database on which the drop of objects is to be carried out.
|
||||
|
||||
Click the *SQL* tab to continue.
|
||||
|
||||
.. image:: images/role_drop_dialog_sql.png
|
||||
:alt: Reassign/Drop Own dialog sql
|
||||
:align: center
|
||||
|
||||
The above examples demonstrates drop owned by *role*.
|
||||
|
||||
* Click the *Help* button (?) to access online help.
|
||||
* Click the *OK* button to save work.
|
||||
* Click the *Cancel* button to exit without saving work.
|
||||
@@ -20,4 +20,6 @@ the selected browser node.
|
||||
* Use the :ref:`Filtered Rows <viewdata_filter>` button to access the Data Filter popup
|
||||
to apply a filter to a set of data for viewing/editing.
|
||||
* Use the :ref:`Search objects <search_objects>` button to access the search objects
|
||||
dialog. It helps you search any database object.
|
||||
dialog. It helps you search any database object.
|
||||
* Use the :ref:`PSQL Tool <psql_tool>` button to open the PSQL in the current
|
||||
database context.
|
||||
@@ -10,7 +10,12 @@ CA_FILE = '/etc/ssl/certs/ca-certificates.crt'
|
||||
LOG_FILE = '/dev/null'
|
||||
HELP_PATH = '../../docs'
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
'pg': '/usr/local/pgsql-13'
|
||||
'pg': '/usr/local/pgsql-13',
|
||||
'pg-13': '/usr/local/pgsql-13',
|
||||
'pg-12': '/usr/local/pgsql-12',
|
||||
'pg-11': '/usr/local/pgsql-11',
|
||||
'pg-10': '/usr/local/pgsql-10',
|
||||
'pg-9.6': '/usr/local/pgsql-9.6'
|
||||
}
|
||||
EOF
|
||||
|
||||
|
||||
@@ -6,21 +6,27 @@ builds may still work with suitable adjustments.
|
||||
|
||||
## Installing build requirements
|
||||
|
||||
1. Install Visual Studio 2017 Pro from https://my.visualstudio.com/Downloads?q=Visual%20Studio%202017
|
||||
|
||||
Choose the Desktop development with C++ option.
|
||||
1. Install Visual Studio 2017 Pro from https://my.visualstudio.com/Downloads?q=Visual%20Studio%202017.
|
||||
Choose the Desktop development with C++ option, and ensure that you add the
|
||||
'Visual C++ MFC for x86 and x64' option.
|
||||
|
||||
2. Install Chocolatey from https://chocolatey.org/install#individual
|
||||
|
||||
3. Install various command line tools:
|
||||
|
||||
choco install -y bzip2 cmake diffutils dotnet3.5 gzip git innosetup nodejs-lts python strawberryperl wget yarn
|
||||
choco install -y awk bzip2 cmake diffutils dotnet3.5 gnuwin32-coreutils.install gzip git html-help-workshop innosetup nodejs-lts python sed strawberryperl wget yarn
|
||||
|
||||
4. Upgrade pip (this may give a permissions error that can be ignored):
|
||||
4. Ensure the GNU CoreUtils and Microsoft HTML Help Workshop are in the system path - add:
|
||||
|
||||
pip install --upgrade pip
|
||||
* C:\Program Files (x86)\GnuWin32\bin
|
||||
* C:\Program Files (x86)\HTML Help Workshop
|
||||
|
||||
|
||||
5. Install virtualenv:
|
||||
5. Upgrade pip:
|
||||
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
6. Install virtualenv:
|
||||
|
||||
pip install virtualenv
|
||||
|
||||
@@ -39,19 +45,22 @@ prompt.
|
||||
tar -zxvf zlib-1.2.11.tar.gz
|
||||
cd zlib-1.2.11
|
||||
cmake -DCMAKE_INSTALL_PREFIX=C:/build64/zlib -G "Visual Studio 15 2017 Win64" .
|
||||
msbuild ALL_BUILD.vcxproj /p:Configuration=Release
|
||||
msbuild RUN_TESTS.vcxproj /p:Configuration=Release
|
||||
msbuild INSTALL.vcxproj /p:Configuration=Release
|
||||
copy C:\build64\zlib\lib\zlib.lib C:\build64\zlib\lib\zdll.lib
|
||||
cd ..
|
||||
|
||||
3. Download the OpenSSL source code, unpack and build it:
|
||||
|
||||
wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz
|
||||
tar -zxvf openssl-1.1.1g.tar.gz
|
||||
cd openssl-1.1.1g
|
||||
wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
|
||||
tar -zxvf openssl-1.1.1k.tar.gz
|
||||
cd openssl-1.1.1k
|
||||
perl Configure VC-WIN64A no-asm --prefix=C:\build64\openssl no-ssl2 no-ssl3 no-comp
|
||||
nmake
|
||||
nmake test
|
||||
nmake install
|
||||
cd ..
|
||||
|
||||
Note that if you are not working in an administrative account, you may need to
|
||||
create and give your regular account appropriate permissions to write/modify
|
||||
@@ -63,8 +72,10 @@ users could potentially write to.
|
||||
|
||||
In a *32bit* Visual Studio 2017 command prompt:
|
||||
|
||||
wget https://kerberos.org/dist/krb5/1.19/krb5-1.19.1.tar.gz
|
||||
tar -zxvf krb5-1.19.1.tar.gz
|
||||
mkdir C:\build64\krb5
|
||||
cd krb5-1.18.3\src
|
||||
cd krb5-1.19.1\src
|
||||
set KRB_INSTALL_DIR=C:\build64\krb5
|
||||
nmake -f Makefile.in prep-windows
|
||||
|
||||
@@ -75,17 +86,18 @@ users could potentially write to.
|
||||
|
||||
In a *64bit* Visual Studio 2017 command prompt:
|
||||
|
||||
cd krb5-1.18.3\src
|
||||
cd krb5-1.19.1\src
|
||||
set PATH=%PATH%;"%WindowsSdkVerBinPath%"\x86
|
||||
set KRB_INSTALL_DIR=C:\build64\krb5
|
||||
nmake NODEBUG=1
|
||||
nmake install NODEBUG=1
|
||||
cd ..\..
|
||||
|
||||
5. Download the PostgreSQL source code, unpack and build it:
|
||||
|
||||
wget https://ftp.postgresql.org/pub/source/v12.3/postgresql-13.1.tar.bz2
|
||||
tar -zxvf postgresql-13.1.tar.gz
|
||||
cd postgresql-13.1\src\tools\msvc
|
||||
wget https://ftp.postgresql.org/pub/source/v13.3/postgresql-13.3.tar.gz
|
||||
tar -zxvf postgresql-13.3.tar.gz
|
||||
cd postgresql-13.3\src\tools\msvc
|
||||
|
||||
>> config.pl echo # Configuration arguments for vcbuild.
|
||||
>> config.pl echo use strict;
|
||||
@@ -154,9 +166,9 @@ Studio 2017 64bit command prompt. Note that the examples shown below are the
|
||||
defaults for the build system, so if they match your requirements you don't
|
||||
need to set them:
|
||||
|
||||
SET "PGADMIN_POSTGRES_DIR=C:\Program Files\PostgreSQL\13"
|
||||
SET "PGADMIN_POSTGRES_DIR=C:\build64\pgsql"
|
||||
SET "PGADMIN_PYTHON_DIR=C:\Python39"
|
||||
SET "PGADMIN_KRB5_DIR=C:\jenkins\build64\krb5"
|
||||
SET "PGADMIN_KRB5_DIR=C:\build64\krb5"
|
||||
SET "PGADMIN_INNOTOOL_DIR=C:\Program Files (x86)\Inno Setup 6"
|
||||
SET "PGADMIN_SIGNTOOL_DIR=C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64"
|
||||
SET "PGADMIN_VCREDIST_DIR=C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Redist\MSVC\14.16.27012"
|
||||
|
||||
@@ -19,7 +19,7 @@ AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
DefaultDirName={commonpf}\{#MyAppName}\{#MyAppVersion}
|
||||
DefaultDirName={autopf}\{#MyAppName}\{#MyAppVersion}
|
||||
DefaultGroupName={#MyAppName}
|
||||
DisableWelcomePage=no
|
||||
DisableProgramGroupPage=auto
|
||||
@@ -28,9 +28,10 @@ OutputBaseFilename=pgadmin4-setup
|
||||
SetupIconFile=Resources\pgAdmin4.ico
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
PrivilegesRequired=admin
|
||||
PrivilegesRequired=lowest
|
||||
PrivilegesRequiredOverridesAllowed=dialog
|
||||
ChangesEnvironment=yes
|
||||
;UninstallFilesDir={app}\{#MyAppVersion}
|
||||
UninstallDisplayIcon={app}\runtime\{#MyAppExeName}
|
||||
ArchitecturesInstallIn64BitMode={#MyAppArchitecturesMode}
|
||||
AllowNoIcons=yes
|
||||
WizardImageFile=sidebar.bmp
|
||||
@@ -57,10 +58,10 @@ Source: "..\..\win-build\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdi
|
||||
Filename: "{app}\installer\{#MyAppVCDist}"; StatusMsg: "VC runtime redistributable package"; Parameters: "/passive /verysilent /norestart"; Check: InstallVC;
|
||||
|
||||
[Registry]
|
||||
Root: HKLM; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; Flags: uninsdeletekeyifempty
|
||||
Root: HKLM; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; Flags: uninsdeletekey
|
||||
Root: HKLM; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"
|
||||
Root: HKLM; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; ValueType: string; ValueName: "Version"; ValueData: "{#MyAppFullVersion}"
|
||||
Root: HKA; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; Flags: uninsdeletekeyifempty
|
||||
Root: HKA; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; Flags: uninsdeletekey
|
||||
Root: HKA; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"
|
||||
Root: HKA; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; ValueType: string; ValueName: "Version"; ValueData: "{#MyAppFullVersion}"
|
||||
|
||||
[Code]
|
||||
var
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
cheroot==8.*
|
||||
Flask==1.*
|
||||
Flask-Gravatar==0.*
|
||||
Flask-Login==0.*
|
||||
@@ -30,10 +29,17 @@ psycopg2==2.8.*
|
||||
python-dateutil==2.*
|
||||
SQLAlchemy==1.3.*
|
||||
itsdangerous<=1.1.0
|
||||
Flask-Security-Too==3.*
|
||||
Flask-Security-Too==4.*
|
||||
bcrypt==3.*
|
||||
cryptography==3.*
|
||||
sshtunnel==0.*
|
||||
ldap3==2.*
|
||||
Flask-BabelEx==0.*
|
||||
gssapi==1.6.*
|
||||
flask-socketio>=5.0.1
|
||||
eventlet==0.31.0
|
||||
httpagentparser==1.9.*
|
||||
user-agents==2.2.0
|
||||
pywinpty==1.1.1; sys_platform=="win32"
|
||||
Authlib==0.15.*
|
||||
requests==2.25.*
|
||||
@@ -6,6 +6,7 @@
|
||||
"author": "pgAdmin Development Team (https://www.pgadmin.org/)",
|
||||
"license": "PostgreSQL",
|
||||
"chromium-args": "--disable-popup-blocking",
|
||||
"user-agent": "Nwjs:%nwver-%osinfo-%chromium_ver",
|
||||
"window": {
|
||||
"width": 440,
|
||||
"height": 170,
|
||||
|
||||
@@ -28,6 +28,17 @@
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Disable/block all password saving in nw.js -->
|
||||
<script type="text/javascript">
|
||||
chrome.passwordsPrivate.getSavedPasswordList(function(passwords) {
|
||||
passwords.forEach((p, i) => {
|
||||
chrome.passwordsPrivate.removeSavedPassword(i);
|
||||
});
|
||||
});
|
||||
chrome.privacy.services.passwordSavingEnabled.set({ value: false });
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
let platform = require("os").platform;
|
||||
</script>
|
||||
|
||||
@@ -43,7 +43,7 @@ APP_ICON = 'pg-icon'
|
||||
|
||||
# Application version number components
|
||||
APP_RELEASE = 5
|
||||
APP_REVISION = 3
|
||||
APP_REVISION = 5
|
||||
|
||||
# Application version suffix, e.g. 'beta1', 'dev'. Usually an empty string
|
||||
# for GA releases.
|
||||
@@ -52,7 +52,7 @@ APP_SUFFIX = ''
|
||||
# Numeric application version for upgrade checks. Should be in the format:
|
||||
# [X]XYYZZ, where X is the release version, Y is the revision, with a leading
|
||||
# zero if needed, and Z represents the suffix, with a leading zero if needed
|
||||
APP_VERSION_INT = 50300
|
||||
APP_VERSION_INT = 50500
|
||||
|
||||
# DO NOT CHANGE!
|
||||
# The application version string, constructed from the components
|
||||
@@ -156,8 +156,8 @@ X_FRAME_OPTIONS = "SAMEORIGIN"
|
||||
# such as JavaScript, CSS, or pretty much anything that the browser loads.
|
||||
# see https://content-security-policy.com/#source_list for more info
|
||||
# e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';"
|
||||
CONTENT_SECURITY_POLICY = "default-src http: data: blob: 'unsafe-inline' " \
|
||||
"'unsafe-eval';"
|
||||
CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \
|
||||
" 'unsafe-eval';"
|
||||
|
||||
# STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the
|
||||
# Strict-Transport-Security header
|
||||
@@ -286,6 +286,13 @@ if SERVER_MODE and not IS_WIN:
|
||||
else:
|
||||
LOG_FILE = os.path.join(DATA_DIR, 'pgadmin4.log')
|
||||
|
||||
# Log rotation setting
|
||||
# Log file will be rotated considering values for LOG_ROTATION_SIZE
|
||||
# & LOG_ROTATION_AGE. Rotated file will be named in format
|
||||
# - LOG_FILE.Y-m-d_H-M-S
|
||||
LOG_ROTATION_SIZE = 10 # In MBs
|
||||
LOG_ROTATION_AGE = 1440 # In minutes
|
||||
LOG_ROTATION_MAX_LOG_FILES = 90 # Maximum number of backups to retain
|
||||
##########################################################################
|
||||
# Server Connection Driver Settings
|
||||
##########################################################################
|
||||
@@ -374,6 +381,17 @@ SECURITY_EMAIL_SUBJECT_PASSWORD_NOTICE = "Your %s password has been reset" \
|
||||
SECURITY_EMAIL_SUBJECT_PASSWORD_CHANGE_NOTICE = \
|
||||
"Your password for %s has been changed" % APP_NAME
|
||||
|
||||
##########################################################################
|
||||
# Email address validation
|
||||
##########################################################################
|
||||
|
||||
# flask-security-too will validate email addresses and check deliverability
|
||||
# by default. Disable the deliverability check by default, which was the old
|
||||
# behaviour in <= v5.3
|
||||
CHECK_EMAIL_DELIVERABILITY = False
|
||||
SECURITY_EMAIL_VALIDATOR_ARGS = \
|
||||
{"check_deliverability": CHECK_EMAIL_DELIVERABILITY}
|
||||
|
||||
##########################################################################
|
||||
# Upgrade checks
|
||||
##########################################################################
|
||||
@@ -416,6 +434,10 @@ STORAGE_DIR = os.path.join(DATA_DIR, 'storage')
|
||||
#
|
||||
# A default location can be specified for each database driver ID, in
|
||||
# a dictionary. Either an absolute or relative path can be specified.
|
||||
#
|
||||
# Version-specific defaults can also be specified, which will take priority
|
||||
# over un-versioned paths.
|
||||
#
|
||||
# In cases where it may be difficult to know what the working directory
|
||||
# is, "$DIR" can be specified. This will be replaced with the path to the
|
||||
# top-level pgAdmin4.py file. For example, on macOS we might use:
|
||||
@@ -425,8 +447,17 @@ STORAGE_DIR = os.path.join(DATA_DIR, 'storage')
|
||||
##########################################################################
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
"pg": "",
|
||||
"pg-9.6": "",
|
||||
"pg-10": "",
|
||||
"pg-11": "",
|
||||
"pg-12": "",
|
||||
"pg-13": "",
|
||||
"ppas": "",
|
||||
"gpdb": ""
|
||||
"ppas-9.6": "",
|
||||
"ppas-10": "",
|
||||
"ppas-11": "",
|
||||
"ppas-12": "",
|
||||
"ppas-13": ""
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
@@ -531,10 +562,11 @@ ENHANCED_COOKIE_PROTECTION = True
|
||||
##########################################################################
|
||||
|
||||
# Default setting is internal
|
||||
# External Supported Sources: ldap, kerberos
|
||||
# External Supported Sources: ldap, kerberos, oauth2
|
||||
# Multiple authentication can be achieved by setting this parameter to
|
||||
# ['ldap', 'internal']. pgAdmin will authenticate the user with ldap first,
|
||||
# in case of failure internal authentication will be done.
|
||||
# ['ldap', 'internal'] or ['oauth2', 'internal'] etc.
|
||||
# pgAdmin will authenticate the user with ldap/oauth2 whatever first in the
|
||||
# list, in case of failure the second authentication option will be considered.
|
||||
|
||||
AUTHENTICATION_SOURCES = ['internal']
|
||||
|
||||
@@ -614,7 +646,6 @@ LDAP_CA_CERT_FILE = ''
|
||||
LDAP_CERT_FILE = ''
|
||||
LDAP_KEY_FILE = ''
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Kerberos Configuration
|
||||
##########################################################################
|
||||
@@ -636,6 +667,62 @@ KRB_AUTO_CREATE_USER = True
|
||||
|
||||
KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache')
|
||||
|
||||
##########################################################################
|
||||
# OAuth2 Configuration
|
||||
##########################################################################
|
||||
|
||||
# Multiple OAUTH2 providers can be added in the list like [{...},{...}]
|
||||
# All parameters are required
|
||||
|
||||
OAUTH2_CONFIG = [
|
||||
{
|
||||
# The name of the of the oauth provider, ex: github, google
|
||||
'OAUTH2_NAME': None,
|
||||
# The display name, ex: Google
|
||||
'OAUTH2_DISPLAY_NAME': '<Oauth2 Display Name>',
|
||||
# Oauth client id
|
||||
'OAUTH2_CLIENT_ID': None,
|
||||
# Oauth secret
|
||||
'OAUTH2_CLIENT_SECRET': None,
|
||||
# URL to generate a token,
|
||||
# Ex: https://github.com/login/oauth/access_token
|
||||
'OAUTH2_TOKEN_URL': None,
|
||||
# URL is used for authentication,
|
||||
# Ex: https://github.com/login/oauth/authorize
|
||||
'OAUTH2_AUTHORIZATION_URL': None,
|
||||
# Oauth base url, ex: https://api.github.com/
|
||||
'OAUTH2_API_BASE_URL': None,
|
||||
# Name of the Endpoint, ex: user
|
||||
'OAUTH2_USERINFO_ENDPOINT': None,
|
||||
# Font-awesome icon, ex: fa-github
|
||||
'OAUTH2_ICON': None,
|
||||
# UI button colour, ex: #0000ff
|
||||
'OAUTH2_BUTTON_COLOR': None,
|
||||
}
|
||||
]
|
||||
|
||||
# After Oauth authentication, user will be added into the SQLite database
|
||||
# automatically, if set to True.
|
||||
# Set it to False, if user should not be added automatically,
|
||||
# in this case Admin has to add the user manually in the SQLite database.
|
||||
|
||||
OAUTH2_AUTO_CREATE_USER = True
|
||||
|
||||
##########################################################################
|
||||
# PSQL tool settings
|
||||
##########################################################################
|
||||
# This will enable PSQL tool in pgAdmin when running in server mode.
|
||||
# PSQL is always enabled in Desktop mode, however in server mode it is
|
||||
# disabled by default because users can run arbitrary commands on the
|
||||
# server through it.
|
||||
ENABLE_PSQL = False
|
||||
|
||||
##########################################################################
|
||||
# ENABLE_BINARY_PATH_BROWSING setting is used to enable the browse button
|
||||
# while selecting binary path for the database server in server mode.
|
||||
# In Desktop mode it is always enabled and setting is of no use.
|
||||
##########################################################################
|
||||
ENABLE_BINARY_PATH_BROWSING = False
|
||||
|
||||
##########################################################################
|
||||
# Local config settings
|
||||
@@ -676,3 +763,5 @@ if 'PGADMIN_CONFIG_DEFAULT_SERVER' in os.environ:
|
||||
# Disable USER_INACTIVITY_TIMEOUT when SERVER_MODE=False
|
||||
if not SERVER_MODE:
|
||||
USER_INACTIVITY_TIMEOUT = 0
|
||||
# Enable PSQL in Desktop Mode.
|
||||
ENABLE_PSQL = True
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
"""empty message
|
||||
|
||||
Revision ID: c465fee44968
|
||||
Revises: d0bc9f32b2b9
|
||||
Create Date: 2021-06-04 14:42:12.843116
|
||||
|
||||
"""
|
||||
from pgadmin.model import db, User
|
||||
import uuid
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'c465fee44968'
|
||||
down_revision = 'd0bc9f32b2b9'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
db.engine.execute("ALTER TABLE user RENAME TO user_old")
|
||||
|
||||
db.engine.execute("""
|
||||
CREATE TABLE user (
|
||||
id INTEGER NOT NULL,
|
||||
username VARCHAR(256) NOT NULL,
|
||||
email VARCHAR(256),
|
||||
password VARCHAR(256),
|
||||
active BOOLEAN NOT NULL,
|
||||
confirmed_at DATETIME,
|
||||
masterpass_check VARCHAR(256),
|
||||
auth_source VARCHAR(256) NOT NULL DEFAULT 'internal',
|
||||
fs_uniquifier NOT NULL UNIQUE,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE (username, auth_source),
|
||||
CHECK (active IN (0, 1))
|
||||
);
|
||||
""")
|
||||
|
||||
user_old = db.engine.execute(
|
||||
'select id, username, email, password, active, '
|
||||
'confirmed_at, masterpass_check, auth_source '
|
||||
'from user_old')
|
||||
|
||||
db.engine.execute(User.__table__.insert(), [
|
||||
{
|
||||
**row,
|
||||
'fs_uniquifier': uuid.uuid4().hex
|
||||
} for row in user_old
|
||||
])
|
||||
|
||||
db.engine.execute("DROP TABLE user_old")
|
||||
|
||||
|
||||
def downgrade():
|
||||
# pgAdmin only upgrades, downgrade not implemented.
|
||||
pass
|
||||
@@ -117,13 +117,18 @@
|
||||
"shim-loader": "^1.0.1",
|
||||
"slickgrid": "git+https://github.com/6pac/SlickGrid.git#2.3.16",
|
||||
"snapsvg-cjs": "^0.0.6",
|
||||
"socket.io-client": "^4.0.0",
|
||||
"split.js": "^1.5.10",
|
||||
"tablesorter": "^2.31.2",
|
||||
"tempusdominus-bootstrap-4": "^5.1.2",
|
||||
"tempusdominus-core": "^5.0.3",
|
||||
"underscore": "^1.13.1",
|
||||
"webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36",
|
||||
"wkx": "^0.5.0"
|
||||
"webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#06daee1a8111b4ed08d58670674a2967e4f68313",
|
||||
"wkx": "^0.5.0",
|
||||
"xterm": "^4.11.0",
|
||||
"xterm-addon-fit": "^0.5.0",
|
||||
"xterm-addon-search": "^0.8.0",
|
||||
"xterm-addon-web-links": "^0.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .",
|
||||
|
||||
@@ -13,7 +13,7 @@ to start a web server."""
|
||||
|
||||
|
||||
import sys
|
||||
from cheroot.wsgi import Server as CherootServer
|
||||
|
||||
|
||||
if sys.version_info < (3, 4):
|
||||
raise RuntimeError('This application must be run under Python 3.4 '
|
||||
@@ -37,7 +37,7 @@ else:
|
||||
builtins.SERVER_MODE = None
|
||||
|
||||
import config
|
||||
from pgadmin import create_app
|
||||
from pgadmin import create_app, socketio
|
||||
from pgadmin.utils import u_encode, fs_encoding, file_quote
|
||||
from pgadmin.utils.constants import INTERNAL
|
||||
# Get the config database schema version. We store this in pgadmin.model
|
||||
@@ -97,6 +97,8 @@ if not os.path.isfile(config.SQLITE_PATH):
|
||||
##########################################################################
|
||||
app = create_app()
|
||||
app.debug = False
|
||||
app.config['sessions'] = dict()
|
||||
|
||||
if config.SERVER_MODE:
|
||||
app.wsgi_app = ReverseProxied(app.wsgi_app)
|
||||
|
||||
@@ -206,17 +208,16 @@ def main():
|
||||
else:
|
||||
# Can use cheroot instead of flask dev server when not in debug
|
||||
# 10 is default thread count in CherootServer
|
||||
num_threads = 10 if config.THREADED_MODE else 1
|
||||
prod_server = CherootServer(
|
||||
(config.DEFAULT_SERVER, config.EFFECTIVE_SERVER_PORT),
|
||||
wsgi_app=app,
|
||||
numthreads=num_threads,
|
||||
server_name=config.APP_NAME)
|
||||
# num_threads = 10 if config.THREADED_MODE else 1
|
||||
try:
|
||||
print("Using production server...")
|
||||
prod_server.start()
|
||||
socketio.run(
|
||||
app,
|
||||
host=config.DEFAULT_SERVER,
|
||||
port=config.EFFECTIVE_SERVER_PORT,
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
prod_server.stop()
|
||||
print("CLOSE SERVER")
|
||||
socketio.stop()
|
||||
|
||||
except IOError:
|
||||
app.logger.error("Error starting the app server: %s", sys.exc_info())
|
||||
|
||||
@@ -14,11 +14,14 @@ import os
|
||||
import sys
|
||||
import re
|
||||
import ipaddress
|
||||
import traceback
|
||||
|
||||
from types import MethodType
|
||||
from collections import defaultdict
|
||||
from importlib import import_module
|
||||
|
||||
from flask import Flask, abort, request, current_app, session, url_for
|
||||
from flask_socketio import SocketIO
|
||||
from werkzeug.exceptions import HTTPException
|
||||
from flask_babelex import Babel, gettext
|
||||
from flask_babelex import gettext as _
|
||||
@@ -37,25 +40,31 @@ from pgadmin.utils import PgAdminModule, driver, KeyManager
|
||||
from pgadmin.utils.preferences import Preferences
|
||||
from pgadmin.utils.session import create_session_interface, pga_unauthorised
|
||||
from pgadmin.utils.versioned_template_loader import VersionedTemplateLoader
|
||||
from datetime import timedelta
|
||||
from pgadmin.setup import get_version, set_version
|
||||
from datetime import timedelta, datetime
|
||||
from pgadmin.setup import get_version, set_version, check_db_tables
|
||||
from pgadmin.utils.ajax import internal_server_error, make_json_response
|
||||
from pgadmin.utils.csrf import pgCSRFProtect
|
||||
from pgadmin import authenticate
|
||||
from pgadmin.utils.security_headers import SecurityHeaders
|
||||
from pgadmin.utils.constants import KERBEROS
|
||||
from pgadmin.utils.constants import KERBEROS, OAUTH2, INTERNAL, LDAP
|
||||
|
||||
# Explicitly set the mime-types so that a corrupted windows registry will not
|
||||
# affect pgAdmin 4 to be load properly. This will avoid the issues that may
|
||||
# occur due to security fix of X_CONTENT_TYPE_OPTIONS = "nosniff".
|
||||
import mimetypes
|
||||
|
||||
mimetypes.add_type('application/javascript', '.js')
|
||||
mimetypes.add_type('text/css', '.css')
|
||||
|
||||
|
||||
winreg = None
|
||||
if os.name == 'nt':
|
||||
import winreg
|
||||
|
||||
socketio = SocketIO(manage_session=False, async_mode='threading',
|
||||
logger=False, engineio_logger=False, debug=False,
|
||||
ping_interval=25, ping_timeout=120)
|
||||
|
||||
|
||||
class PgAdmin(Flask):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -256,7 +265,13 @@ def create_app(app_name=None):
|
||||
create_app_data_directory(config)
|
||||
|
||||
# File logging
|
||||
fh = logging.FileHandler(config.LOG_FILE, encoding='utf-8')
|
||||
from pgadmin.utils.enhanced_log_rotation import \
|
||||
EnhancedRotatingFileHandler
|
||||
fh = EnhancedRotatingFileHandler(config.LOG_FILE,
|
||||
config.LOG_ROTATION_SIZE,
|
||||
config.LOG_ROTATION_AGE,
|
||||
config.LOG_ROTATION_MAX_LOG_FILES)
|
||||
|
||||
fh.setLevel(config.FILE_LOG_LEVEL)
|
||||
fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT))
|
||||
app.logger.addHandler(fh)
|
||||
@@ -293,7 +308,7 @@ def create_app(app_name=None):
|
||||
if current_user.is_authenticated:
|
||||
user_id = current_user.id
|
||||
else:
|
||||
user = user_datastore.get_user(config.DESKTOP_USER)
|
||||
user = user_datastore.find_user(email=config.DESKTOP_USER)
|
||||
if user is not None:
|
||||
user_id = user.id
|
||||
user_language = Preferences.raw_value(
|
||||
@@ -337,6 +352,44 @@ def create_app(app_name=None):
|
||||
##########################################################################
|
||||
# Upgrade the schema (if required)
|
||||
##########################################################################
|
||||
def backup_db_file():
|
||||
"""
|
||||
Create a backup of the current database file
|
||||
and create new database file with default settings.
|
||||
"""
|
||||
backup_file_name = "{0}.{1}".format(
|
||||
SQLITE_PATH, datetime.now().strftime('%Y%m%d%H%M%S'))
|
||||
os.rename(SQLITE_PATH, backup_file_name)
|
||||
app.logger.error('Exception in database migration.')
|
||||
app.logger.info('Creating new database file.')
|
||||
try:
|
||||
db_upgrade(app)
|
||||
os.environ[
|
||||
'CORRUPTED_DB_BACKUP_FILE'] = backup_file_name
|
||||
app.logger.info('Database migration completed.')
|
||||
except Exception as e:
|
||||
app.logger.error('Database migration failed')
|
||||
app.logger.error(traceback.format_exc())
|
||||
raise RuntimeError('Migration failed')
|
||||
|
||||
def upgrade_db():
|
||||
"""
|
||||
Execute the migrations.
|
||||
"""
|
||||
try:
|
||||
db_upgrade(app)
|
||||
os.environ['CORRUPTED_DB_BACKUP_FILE'] = ''
|
||||
except Exception as e:
|
||||
backup_db_file()
|
||||
|
||||
# check all tables are present in the db.
|
||||
is_db_error, invalid_tb_names = check_db_tables()
|
||||
if is_db_error:
|
||||
app.logger.error(
|
||||
'Table(s) {0} are missing in the'
|
||||
' database'.format(invalid_tb_names))
|
||||
backup_db_file()
|
||||
|
||||
with app.app_context():
|
||||
# Run migration for the first time i.e. create database
|
||||
from config import SQLITE_PATH
|
||||
@@ -344,25 +397,34 @@ def create_app(app_name=None):
|
||||
|
||||
# If version not available, user must have aborted. Tables are not
|
||||
# created and so its an empty db
|
||||
if not os.path.exists(SQLITE_PATH) or get_version() == -1:
|
||||
version = get_version()
|
||||
if not os.path.exists(SQLITE_PATH) or version == -1:
|
||||
# If running in cli mode then don't try to upgrade, just raise
|
||||
# the exception
|
||||
if not cli_mode:
|
||||
db_upgrade(app)
|
||||
upgrade_db()
|
||||
else:
|
||||
if not os.path.exists(SQLITE_PATH):
|
||||
raise FileNotFoundError(
|
||||
'SQLite database file "' + SQLITE_PATH +
|
||||
'" does not exists.')
|
||||
raise RuntimeError('Specified SQLite database file '
|
||||
'is not valid.')
|
||||
raise RuntimeError(
|
||||
'The configuration database file is not valid.')
|
||||
else:
|
||||
schema_version = get_version()
|
||||
|
||||
# Run migration if current schema version is greater than the
|
||||
# schema version stored in version table
|
||||
if CURRENT_SCHEMA_VERSION >= schema_version:
|
||||
db_upgrade(app)
|
||||
upgrade_db()
|
||||
else:
|
||||
# check all tables are present in the db.
|
||||
is_db_error, invalid_tb_names = check_db_tables()
|
||||
if is_db_error:
|
||||
app.logger.error(
|
||||
'Table(s) {0} are missing in the'
|
||||
' database'.format(invalid_tb_names))
|
||||
backup_db_file()
|
||||
|
||||
# Update schema version to the latest
|
||||
if CURRENT_SCHEMA_VERSION > schema_version:
|
||||
@@ -404,6 +466,15 @@ def create_app(app_name=None):
|
||||
# CSRF Token expiration till session expires
|
||||
'WTF_CSRF_TIME_LIMIT': getattr(config, 'CSRF_TIME_LIMIT', None),
|
||||
'WTF_CSRF_METHODS': ['GET', 'POST', 'PUT', 'DELETE'],
|
||||
# Disable deliverable check for email addresss
|
||||
'SECURITY_EMAIL_VALIDATOR_ARGS': config.SECURITY_EMAIL_VALIDATOR_ARGS
|
||||
}))
|
||||
|
||||
app.config.update(dict({
|
||||
'INTERNAL': INTERNAL,
|
||||
'LDAP': LDAP,
|
||||
'KERBEROS': KERBEROS,
|
||||
'OAUTH2': OAUTH2
|
||||
}))
|
||||
|
||||
security.init_app(app, user_datastore)
|
||||
@@ -685,7 +756,7 @@ def create_app(app_name=None):
|
||||
abort(401)
|
||||
|
||||
if not config.SERVER_MODE and not current_user.is_authenticated:
|
||||
user = user_datastore.get_user(config.DESKTOP_USER)
|
||||
user = user_datastore.find_user(email=config.DESKTOP_USER)
|
||||
# Throw an error if we failed to find the desktop user, to give
|
||||
# the sysadmin a hint. We'll continue to try to login anyway as
|
||||
# that'll through a nice 500 error for us.
|
||||
@@ -697,19 +768,18 @@ def create_app(app_name=None):
|
||||
)
|
||||
abort(401)
|
||||
login_user(user)
|
||||
elif config.SERVER_MODE and\
|
||||
app.PGADMIN_EXTERNAL_AUTH_SOURCE ==\
|
||||
KERBEROS and \
|
||||
elif config.SERVER_MODE and \
|
||||
not current_user.is_authenticated and \
|
||||
request.endpoint in ('redirects.index', 'security.login'):
|
||||
return authenticate.login()
|
||||
|
||||
if app.PGADMIN_EXTERNAL_AUTH_SOURCE == KERBEROS:
|
||||
return authenticate.login()
|
||||
# if the server is restarted the in memory key will be lost
|
||||
# but the user session may still be active. Logout the user
|
||||
# to get the key again when login
|
||||
if config.SERVER_MODE and current_user.is_authenticated and \
|
||||
app.PGADMIN_EXTERNAL_AUTH_SOURCE != \
|
||||
KERBEROS and \
|
||||
KERBEROS and app.PGADMIN_EXTERNAL_AUTH_SOURCE != \
|
||||
OAUTH2 and\
|
||||
current_app.keyManager.get() is None and \
|
||||
request.endpoint not in ('security.login', 'security.logout'):
|
||||
logout_user()
|
||||
@@ -811,4 +881,5 @@ def create_app(app_name=None):
|
||||
##########################################################################
|
||||
# All done!
|
||||
##########################################################################
|
||||
socketio.init_app(app)
|
||||
return app
|
||||
@@ -10,13 +10,17 @@
|
||||
"""A blueprint module implementing the about box."""
|
||||
|
||||
import sys
|
||||
from flask import Response, render_template, __version__, url_for
|
||||
from flask import Response, render_template, __version__, url_for, request
|
||||
from flask_babelex import gettext
|
||||
from flask_security import current_user, login_required
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.menu import MenuItem
|
||||
from pgadmin.utils.constants import MIMETYPE_APP_JS
|
||||
import config
|
||||
import httpagentparser
|
||||
from pgadmin.model import User
|
||||
from user_agents import parse
|
||||
import platform
|
||||
|
||||
MODULE_NAME = 'about'
|
||||
|
||||
@@ -59,23 +63,81 @@ blueprint = AboutModule(MODULE_NAME, __name__, static_url_path='')
|
||||
@login_required
|
||||
def index():
|
||||
"""Render the about box."""
|
||||
info = {
|
||||
'python_version': sys.version,
|
||||
'flask_version': __version__
|
||||
}
|
||||
info = {}
|
||||
# Get OS , NW.js, Browser details
|
||||
browser, os_details, nwjs_version = detect_browser(request)
|
||||
|
||||
if nwjs_version:
|
||||
info['nwjs'] = nwjs_version
|
||||
|
||||
info['browser_details'] = browser
|
||||
info['os_details'] = os_details
|
||||
info['config_db'] = config.SQLITE_PATH
|
||||
info['log_file'] = config.LOG_FILE
|
||||
|
||||
if config.SERVER_MODE:
|
||||
info['app_mode'] = gettext('Server')
|
||||
admin = is_admin(current_user.email)
|
||||
info['admin'] = admin
|
||||
else:
|
||||
info['app_mode'] = gettext('Desktop')
|
||||
|
||||
info['current_user'] = current_user.email
|
||||
|
||||
settings = ""
|
||||
for setting in dir(config):
|
||||
if not setting.startswith('_') and setting.isupper() and \
|
||||
setting not in ['CSRF_SESSION_KEY',
|
||||
'SECRET_KEY',
|
||||
'SECURITY_PASSWORD_SALT',
|
||||
'SECURITY_PASSWORD_HASH',
|
||||
'ALLOWED_HOSTS',
|
||||
'MAIL_PASSWORD',
|
||||
'LDAP_BIND_PASSWORD',
|
||||
'SECURITY_PASSWORD_HASH']:
|
||||
if isinstance(getattr(config, setting), str):
|
||||
settings = \
|
||||
settings + '{} = "{}"\n'.format(
|
||||
setting, gettext(getattr(config, setting)))
|
||||
else:
|
||||
settings = \
|
||||
settings + '{} = {}\n'.format(
|
||||
setting, gettext(getattr(config, setting)))
|
||||
|
||||
info['settings'] = settings
|
||||
|
||||
return render_template(
|
||||
MODULE_NAME + '/index.html', info=info, _=gettext
|
||||
)
|
||||
|
||||
|
||||
def is_admin(load_user):
|
||||
user = User.query.filter_by(email=load_user).first()
|
||||
return user.has_role("Administrator")
|
||||
|
||||
|
||||
def detect_browser(request):
|
||||
"""This function returns the browser and os details"""
|
||||
nwjs_version = None
|
||||
agent = request.environ.get('HTTP_USER_AGENT')
|
||||
os_details = parse(platform.platform()).ua_string
|
||||
|
||||
if 'Nwjs' in agent:
|
||||
agent = agent.split('-')
|
||||
nwjs_version = agent[0].split(':')[1]
|
||||
browser = 'Chromium' + ' ' + agent[2]
|
||||
|
||||
else:
|
||||
browser = httpagentparser.detect(agent)
|
||||
if not browser:
|
||||
browser = agent.split('/')[0]
|
||||
else:
|
||||
browser = browser['browser']['name'] + ' ' + browser['browser'][
|
||||
'version']
|
||||
|
||||
return browser, os_details, nwjs_version
|
||||
|
||||
|
||||
@blueprint.route("/about.js")
|
||||
@login_required
|
||||
def script():
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
define(
|
||||
['jquery', 'alertify', 'sources/pgadmin', 'sources/gettext',
|
||||
'sources/url_for','sources/utils',
|
||||
'sources/url_for','sources/utils','pgadmin.user_management.current_user',
|
||||
],
|
||||
function($, alertify, pgAdmin, gettext, url_for, commonUtils) {
|
||||
function($, alertify, pgAdmin, gettext, url_for, commonUtils, current_user) {
|
||||
pgAdmin = pgAdmin || window.pgAdmin || {};
|
||||
|
||||
/* Return back, this has been called more than once */
|
||||
@@ -45,14 +45,28 @@ define(
|
||||
},
|
||||
hooks:{
|
||||
onshow:function(){
|
||||
var self = this;
|
||||
var container = $(this.elements.footer).find('button:not([disabled])');
|
||||
commonUtils.findAndSetFocus(container);
|
||||
$('#copy_textarea').on('click', function(){
|
||||
//Copy the server configuration details
|
||||
let textarea = document.getElementById('about-textarea');
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
$('#copy_textarea').text('Copied');
|
||||
});
|
||||
|
||||
$(this.elements.resizeHandle).on('click', function(){
|
||||
// Set the height of the Textarea
|
||||
var height = self.elements.dialog.scrollHeight - 300;
|
||||
if (height < 0)
|
||||
height = self.elements.dialog.scrollHeight - 150;
|
||||
$('#about-textarea').css({'height':height});
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
prepare:function() {
|
||||
this.setContent(this.message);
|
||||
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -60,9 +74,15 @@ define(
|
||||
|
||||
$.get(url_for('about.index'),
|
||||
function(data) {
|
||||
alertify.aboutDialog(
|
||||
gettext('About %s', pgAdmin.Browser.utils.app_name), data
|
||||
).resizeTo(pgAdmin.Browser.stdW.md, pgAdmin.Browser.stdH.md);
|
||||
if(!current_user.is_admin && pgAdmin.server_mode){
|
||||
alertify.aboutDialog(
|
||||
gettext('About %s', pgAdmin.Browser.utils.app_name), data
|
||||
).resizeTo(pgAdmin.Browser.stdW.md, 300);
|
||||
}else{
|
||||
alertify.aboutDialog(
|
||||
gettext('About %s', pgAdmin.Browser.utils.app_name), data
|
||||
).resizeTo(750, 470);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,18 +3,6 @@
|
||||
<div class="col-sm-3"><strong>{{ _('Version') }}</strong></div>
|
||||
<div class="col-sm-9">{{ config.APP_VERSION }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Copyright') }}</strong></div>
|
||||
<div class="col-sm-9">{{ config.APP_COPYRIGHT }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Python Version') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.python_version }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Flask Version') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.flask_version }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Application Mode') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.app_mode }}</div>
|
||||
@@ -23,10 +11,37 @@
|
||||
<div class="col-sm-3"><strong>{{ _('Current User') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.current_user }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 text-right"><img
|
||||
src="{{ url_for('static', filename='img/logo-right-128.png') }}"
|
||||
alt="{{ config.APP_NAME }} {{ _('logo') }}"
|
||||
></div>
|
||||
{% if info.nwjs %}
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('NW.js Version') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.nwjs }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Browser') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.browser_details }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Operating System') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.os_details }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('pgAdmin Database File') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.config_db }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><strong>{{ _('Log File') }}</strong></div>
|
||||
<div class="col-sm-9">{{ info.log_file }}</div>
|
||||
</div>
|
||||
{%if (info.app_mode == 'Desktop') or (info.app_mode == 'Server' and info.admin)%}
|
||||
<div class="row">
|
||||
<div class="col-sm-3"><b>{{ _('Server Configuration') }}</b></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<textarea id="about-textarea" rows="7" cols="150" style="position: relative;width:105%; white-space: pre-wrap;" readonly>{{ info.settings|safe }}</textarea>
|
||||
<button class="btn btn-secondary about-copy" id="copy_textarea" style="position:absolute;top:0;right:0;z-index:20;">Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -9,68 +9,33 @@
|
||||
|
||||
"""A blueprint module implementing the Authentication."""
|
||||
|
||||
import flask
|
||||
import pickle
|
||||
from flask import current_app, flash, Response, request, url_for,\
|
||||
render_template
|
||||
from flask_babelex import gettext
|
||||
from flask_security import current_user, login_required
|
||||
from flask_security.views import _security, _ctx
|
||||
from flask_security.utils import config_value, get_post_logout_redirect, \
|
||||
get_post_login_redirect, logout_user
|
||||
from pgadmin.utils.ajax import make_json_response, internal_server_error
|
||||
import os
|
||||
|
||||
from flask import session
|
||||
|
||||
import config
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.constants import KERBEROS
|
||||
from pgadmin.utils.csrf import pgCSRFProtect
|
||||
import copy
|
||||
|
||||
from flask import current_app, flash, Response, request, url_for,\
|
||||
session, redirect
|
||||
from flask_babelex import gettext
|
||||
from flask_security.views import _security
|
||||
from flask_security.utils import get_post_logout_redirect, \
|
||||
get_post_login_redirect
|
||||
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.constants import KERBEROS, INTERNAL, OAUTH2, LDAP
|
||||
from pgadmin.authenticate.registry import AuthSourceRegistry
|
||||
|
||||
from .registry import AuthSourceRegistry
|
||||
|
||||
MODULE_NAME = 'authenticate'
|
||||
auth_obj = None
|
||||
|
||||
|
||||
class AuthenticateModule(PgAdminModule):
|
||||
def get_exposed_url_endpoints(self):
|
||||
return ['authenticate.login',
|
||||
'authenticate.kerberos_login',
|
||||
'authenticate.kerberos_logout',
|
||||
'authenticate.kerberos_update_ticket',
|
||||
'authenticate.kerberos_validate_ticket']
|
||||
return ['authenticate.login']
|
||||
|
||||
|
||||
blueprint = AuthenticateModule(MODULE_NAME, __name__, static_url_path='')
|
||||
|
||||
|
||||
@blueprint.route("/login/kerberos",
|
||||
endpoint="kerberos_login", methods=["GET"])
|
||||
@pgCSRFProtect.exempt
|
||||
def kerberos_login():
|
||||
logout_user()
|
||||
return Response(render_template("browser/kerberos_login.html",
|
||||
login_url=url_for('security.login'),
|
||||
))
|
||||
|
||||
|
||||
@blueprint.route("/logout/kerberos",
|
||||
endpoint="kerberos_logout", methods=["GET"])
|
||||
@pgCSRFProtect.exempt
|
||||
def kerberos_logout():
|
||||
logout_user()
|
||||
if 'KRB5CCNAME' in session:
|
||||
# Remove the credential cache
|
||||
cache_file_path = session['KRB5CCNAME'].split(":")[1]
|
||||
if os.path.exists(cache_file_path):
|
||||
os.remove(cache_file_path)
|
||||
|
||||
return Response(render_template("browser/kerberos_logout.html",
|
||||
login_url=url_for('security.login'),
|
||||
))
|
||||
|
||||
|
||||
@blueprint.route('/login', endpoint='login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
"""
|
||||
@@ -78,15 +43,20 @@ def login():
|
||||
The user input will be validated and authenticated.
|
||||
"""
|
||||
form = _security.login_form()
|
||||
auth_obj = AuthSourceManager(form, config.AUTHENTICATION_SOURCES)
|
||||
session['_auth_source_manager_obj'] = None
|
||||
|
||||
auth_obj = AuthSourceManager(form, copy.deepcopy(
|
||||
config.AUTHENTICATION_SOURCES))
|
||||
if OAUTH2 in config.AUTHENTICATION_SOURCES\
|
||||
and 'oauth2_button' in request.form:
|
||||
session['auth_obj'] = auth_obj
|
||||
|
||||
session['auth_source_manager'] = None
|
||||
# Validate the user
|
||||
if not auth_obj.validate():
|
||||
for field in form.errors:
|
||||
for error in form.errors[field]:
|
||||
flash(error, 'warning')
|
||||
return flask.redirect(get_post_logout_redirect())
|
||||
return redirect(get_post_logout_redirect())
|
||||
|
||||
# Authenticate the user
|
||||
status, msg = auth_obj.authenticate()
|
||||
@@ -94,34 +64,42 @@ def login():
|
||||
# Login the user
|
||||
status, msg = auth_obj.login()
|
||||
current_auth_obj = auth_obj.as_dict()
|
||||
|
||||
if not status:
|
||||
if current_auth_obj['current_source'] ==\
|
||||
KERBEROS:
|
||||
return flask.redirect('{0}?next={1}'.format(url_for(
|
||||
return redirect('{0}?next={1}'.format(url_for(
|
||||
'authenticate.kerberos_login'), url_for('browser.index')))
|
||||
|
||||
flash(msg, 'danger')
|
||||
return flask.redirect(get_post_logout_redirect())
|
||||
|
||||
session['_auth_source_manager_obj'] = current_auth_obj
|
||||
return flask.redirect(get_post_login_redirect())
|
||||
return redirect(get_post_logout_redirect())
|
||||
session['auth_source_manager'] = current_auth_obj
|
||||
if 'auth_obj' in session:
|
||||
session.pop('auth_obj')
|
||||
return redirect(get_post_login_redirect())
|
||||
|
||||
elif isinstance(msg, Response):
|
||||
return msg
|
||||
elif 'oauth2_button' in request.form and not isinstance(msg, str):
|
||||
return msg
|
||||
if 'auth_obj' in session:
|
||||
session.pop('auth_obj')
|
||||
flash(msg, 'danger')
|
||||
response = flask.redirect(get_post_logout_redirect())
|
||||
response = redirect(get_post_logout_redirect())
|
||||
return response
|
||||
|
||||
|
||||
class AuthSourceManager():
|
||||
class AuthSourceManager:
|
||||
"""This class will manage all the authentication sources.
|
||||
"""
|
||||
|
||||
def __init__(self, form, sources):
|
||||
self.form = form
|
||||
self.auth_sources = sources
|
||||
self.source = None
|
||||
self.source_friendly_name = None
|
||||
self.current_source = None
|
||||
self.source_friendly_name = INTERNAL
|
||||
self.current_source = INTERNAL
|
||||
self.update_auth_sources()
|
||||
|
||||
def as_dict(self):
|
||||
"""
|
||||
@@ -135,6 +113,17 @@ class AuthSourceManager():
|
||||
|
||||
return res
|
||||
|
||||
def update_auth_sources(self):
|
||||
for auth_src in [KERBEROS, OAUTH2]:
|
||||
if auth_src in self.auth_sources:
|
||||
if 'internal_button' in request.form:
|
||||
self.auth_sources.remove(auth_src)
|
||||
else:
|
||||
if INTERNAL in self.auth_sources:
|
||||
self.auth_sources.remove(INTERNAL)
|
||||
if LDAP in self.auth_sources:
|
||||
self.auth_sources.remove(LDAP)
|
||||
|
||||
def set_current_source(self, source):
|
||||
self.current_source = source
|
||||
|
||||
@@ -170,36 +159,19 @@ class AuthSourceManager():
|
||||
msg = None
|
||||
for src in self.auth_sources:
|
||||
source = get_auth_sources(src)
|
||||
self.set_source(source)
|
||||
current_app.logger.debug(
|
||||
"Authentication initiated via source: %s" %
|
||||
source.get_source_name())
|
||||
|
||||
if self.form.data['email'] and self.form.data['password'] and \
|
||||
source.get_source_name() == KERBEROS:
|
||||
msg = gettext('pgAdmin internal user authentication'
|
||||
' is not enabled, please contact administrator.')
|
||||
continue
|
||||
|
||||
status, msg = source.authenticate(self.form)
|
||||
|
||||
# When server sends Unauthorized header to get the ticket over HTTP
|
||||
# OR When kerberos authentication failed while accessing pgadmin,
|
||||
# we need to break the loop as no need to authenticate further
|
||||
# even if the authentication sources set to multiple
|
||||
if not status:
|
||||
if (hasattr(msg, 'status') and
|
||||
msg.status == '401 UNAUTHORIZED') or\
|
||||
(source.get_source_name() ==
|
||||
KERBEROS and
|
||||
request.method == 'GET'):
|
||||
break
|
||||
|
||||
if status:
|
||||
self.set_source(source)
|
||||
self.set_current_source(source.get_source_name())
|
||||
if msg is not None and 'username' in msg:
|
||||
self.form._fields['email'].data = msg['username']
|
||||
return status, msg
|
||||
|
||||
return status, msg
|
||||
|
||||
def login(self):
|
||||
@@ -209,6 +181,13 @@ class AuthSourceManager():
|
||||
current_app.logger.debug(
|
||||
"Authentication and Login successfully done via source : %s" %
|
||||
self.source.get_source_name())
|
||||
|
||||
# Set the login, logout view as per source if available
|
||||
current_app.login_manager.login_view = getattr(
|
||||
self.source, 'LOGIN_VIEW', 'security.login')
|
||||
current_app.login_manager.logout_view = getattr(
|
||||
self.source, 'LOGOUT_VIEW', 'security.logout')
|
||||
|
||||
return status, msg
|
||||
|
||||
|
||||
@@ -223,7 +202,7 @@ def get_auth_sources(type):
|
||||
if type in auth_sources:
|
||||
return auth_sources[type]
|
||||
|
||||
auth_source = AuthSourceRegistry.create(type)
|
||||
auth_source = AuthSourceRegistry.get(type)
|
||||
|
||||
if auth_source is not None:
|
||||
auth_sources[type] = auth_source
|
||||
@@ -236,61 +215,6 @@ def init_app(app):
|
||||
auth_sources = dict()
|
||||
|
||||
setattr(app, '_pgadmin_auth_sources', auth_sources)
|
||||
AuthSourceRegistry.load_auth_sources()
|
||||
AuthSourceRegistry.load_modules(app)
|
||||
|
||||
return auth_sources
|
||||
|
||||
|
||||
@blueprint.route("/kerberos/update_ticket",
|
||||
endpoint="kerberos_update_ticket", methods=["GET"])
|
||||
@pgCSRFProtect.exempt
|
||||
@login_required
|
||||
def kerberos_update_ticket():
|
||||
"""
|
||||
Update the kerberos ticket.
|
||||
"""
|
||||
from werkzeug.datastructures import Headers
|
||||
headers = Headers()
|
||||
|
||||
authorization = request.headers.get("Authorization", None)
|
||||
|
||||
if authorization is None:
|
||||
# Send the Negotiate header to the client
|
||||
# if Kerberos ticket is not found.
|
||||
headers.add('WWW-Authenticate', 'Negotiate')
|
||||
return Response("Unauthorised", 401, headers)
|
||||
else:
|
||||
source = get_auth_sources(KERBEROS)
|
||||
auth_header = authorization.split()
|
||||
in_token = auth_header[1]
|
||||
|
||||
# Validate the Kerberos ticket
|
||||
status, context = source.negotiate_start(in_token)
|
||||
if status:
|
||||
return Response("Ticket updated successfully.")
|
||||
|
||||
return Response(context, 500)
|
||||
|
||||
|
||||
@blueprint.route("/kerberos/validate_ticket",
|
||||
endpoint="kerberos_validate_ticket", methods=["GET"])
|
||||
@pgCSRFProtect.exempt
|
||||
@login_required
|
||||
def kerberos_validate_ticket():
|
||||
"""
|
||||
Return the kerberos ticket lifetime left after getting the
|
||||
ticket from the credential cache
|
||||
"""
|
||||
import gssapi
|
||||
|
||||
try:
|
||||
del_creds = gssapi.Credentials(store={'ccache': session['KRB5CCNAME']})
|
||||
creds = del_creds.acquire(store={'ccache': session['KRB5CCNAME']})
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
return make_json_response(
|
||||
data={'ticket_lifetime': creds.lifetime},
|
||||
status=200
|
||||
)
|
||||
@@ -10,7 +10,7 @@
|
||||
"""Implements Internal Authentication"""
|
||||
|
||||
import six
|
||||
from flask import current_app
|
||||
from flask import current_app, flash
|
||||
from flask_security import login_user
|
||||
from abc import abstractmethod, abstractproperty
|
||||
from flask_babelex import gettext
|
||||
@@ -31,6 +31,8 @@ class BaseAuthentication(object):
|
||||
'PASSWORD_NOT_PROVIDED': gettext('Password not provided'),
|
||||
'INVALID_EMAIL': gettext('Email/Username is not valid')
|
||||
}
|
||||
LOGIN_VIEW = 'security.login'
|
||||
LOGOUT_VIEW = 'security.logout'
|
||||
|
||||
@abstractmethod
|
||||
def get_source_name(self):
|
||||
@@ -97,7 +99,7 @@ class InternalAuthentication(BaseAuthentication):
|
||||
"""User validation"""
|
||||
# validate the email id first
|
||||
if not validate_email(form.data['email']):
|
||||
form.errors['email'] = [self.messages('INVALID_EMAIL')]
|
||||
flash(self.messages('INVALID_EMAIL'), 'warning')
|
||||
return False
|
||||
# Flask security validation
|
||||
return form.validate_on_submit()
|
||||
|
||||
@@ -10,22 +10,28 @@
|
||||
"""A blueprint module implementing the Spnego/Kerberos authentication."""
|
||||
|
||||
import base64
|
||||
from os import environ, path
|
||||
from os import environ, path, remove
|
||||
|
||||
from werkzeug.datastructures import Headers
|
||||
from werkzeug.datastructures import Headers, MultiDict
|
||||
from flask_babelex import gettext
|
||||
from flask import Flask, request, Response, session,\
|
||||
current_app, render_template, flash
|
||||
from flask import request, Response, session,\
|
||||
current_app, render_template, flash, url_for
|
||||
from flask_security.views import _security
|
||||
from flask_security.utils import logout_user
|
||||
from flask_security import login_required
|
||||
|
||||
import config
|
||||
from pgadmin.model import User
|
||||
from pgadmin.tools.user_management import create_user
|
||||
from pgadmin.utils.constants import KERBEROS
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.ajax import make_json_response, internal_server_error
|
||||
|
||||
from flask_security.views import _security
|
||||
from werkzeug.datastructures import MultiDict
|
||||
|
||||
from .internal import BaseAuthentication
|
||||
from pgadmin.authenticate.internal import BaseAuthentication
|
||||
from pgadmin.authenticate import get_auth_sources
|
||||
from pgadmin.utils.csrf import pgCSRFProtect
|
||||
|
||||
|
||||
try:
|
||||
import gssapi
|
||||
@@ -46,8 +52,110 @@ if config.KRB_KTNAME and config.KRB_KTNAME != '<KRB5_KEYTAB_FILE>':
|
||||
environ['KRB5_KTNAME'] = config.KRB_KTNAME
|
||||
|
||||
|
||||
class KerberosModule(PgAdminModule):
|
||||
def register(self, app, options, first_registration=False):
|
||||
# Do not look for the sub_modules,
|
||||
# instead call blueprint.register(...) directly
|
||||
super(PgAdminModule, self).register(app, options, first_registration)
|
||||
|
||||
def get_exposed_url_endpoints(self):
|
||||
return ['kerberos.login',
|
||||
'kerberos.logout',
|
||||
'kerberos.update_ticket',
|
||||
'kerberos.validate_ticket']
|
||||
|
||||
|
||||
def init_app(app):
|
||||
MODULE_NAME = 'kerberos'
|
||||
|
||||
blueprint = KerberosModule(MODULE_NAME, __name__, static_url_path='')
|
||||
|
||||
@blueprint.route("/login",
|
||||
endpoint="login", methods=["GET"])
|
||||
@pgCSRFProtect.exempt
|
||||
def kerberos_login():
|
||||
logout_user()
|
||||
return Response(render_template("browser/kerberos_login.html",
|
||||
login_url=url_for('security.login'),
|
||||
))
|
||||
|
||||
@blueprint.route("/logout",
|
||||
endpoint="logout", methods=["GET"])
|
||||
@pgCSRFProtect.exempt
|
||||
def kerberos_logout():
|
||||
logout_user()
|
||||
if 'KRB5CCNAME' in session:
|
||||
# Remove the credential cache
|
||||
cache_file_path = session['KRB5CCNAME'].split(":")[1]
|
||||
if path.exists(cache_file_path):
|
||||
remove(cache_file_path)
|
||||
|
||||
return Response(render_template("browser/kerberos_logout.html",
|
||||
login_url=url_for('security.login'),
|
||||
))
|
||||
|
||||
@blueprint.route("/update_ticket",
|
||||
endpoint="update_ticket", methods=["GET"])
|
||||
@pgCSRFProtect.exempt
|
||||
@login_required
|
||||
def kerberos_update_ticket():
|
||||
"""
|
||||
Update the kerberos ticket.
|
||||
"""
|
||||
from werkzeug.datastructures import Headers
|
||||
headers = Headers()
|
||||
|
||||
authorization = request.headers.get("Authorization", None)
|
||||
|
||||
if authorization is None:
|
||||
# Send the Negotiate header to the client
|
||||
# if Kerberos ticket is not found.
|
||||
headers.add('WWW-Authenticate', 'Negotiate')
|
||||
return Response("Unauthorised", 401, headers)
|
||||
else:
|
||||
source = get_auth_sources(KERBEROS)
|
||||
auth_header = authorization.split()
|
||||
in_token = auth_header[1]
|
||||
|
||||
# Validate the Kerberos ticket
|
||||
status, context = source.negotiate_start(in_token)
|
||||
if status:
|
||||
return Response("Ticket updated successfully.")
|
||||
|
||||
return Response(context, 500)
|
||||
|
||||
@blueprint.route("/validate_ticket",
|
||||
endpoint="validate_ticket", methods=["GET"])
|
||||
@pgCSRFProtect.exempt
|
||||
@login_required
|
||||
def kerberos_validate_ticket():
|
||||
"""
|
||||
Return the kerberos ticket lifetime left after getting the
|
||||
ticket from the credential cache
|
||||
"""
|
||||
import gssapi
|
||||
|
||||
try:
|
||||
del_creds = gssapi.Credentials(store={
|
||||
'ccache': session['KRB5CCNAME']})
|
||||
creds = del_creds.acquire(store={'ccache': session['KRB5CCNAME']})
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
return make_json_response(
|
||||
data={'ticket_lifetime': creds.lifetime},
|
||||
status=200
|
||||
)
|
||||
|
||||
app.register_blueprint(blueprint)
|
||||
|
||||
|
||||
class KerberosAuthentication(BaseAuthentication):
|
||||
|
||||
LOGIN_VIEW = 'kerberos.login'
|
||||
LOGOUT_VIEW = 'kerberos.logout'
|
||||
|
||||
def get_source_name(self):
|
||||
return KERBEROS
|
||||
|
||||
@@ -85,7 +193,7 @@ class KerberosAuthentication(BaseAuthentication):
|
||||
if status:
|
||||
# Saving the first 15 characters of the kerberos key
|
||||
# to encrypt/decrypt database password
|
||||
session['kerberos_key'] = auth_header[1][0:15]
|
||||
session['pass_enc_key'] = auth_header[1][0:15]
|
||||
# Create user
|
||||
retval = self.__auto_create_user(
|
||||
str(negotiate.initiator_name))
|
||||
@@ -162,7 +270,7 @@ class KerberosAuthentication(BaseAuthentication):
|
||||
username = str(username)
|
||||
if config.KRB_AUTO_CREATE_USER:
|
||||
user = User.query.filter_by(
|
||||
username=username).first()
|
||||
username=username, auth_source=KERBEROS).first()
|
||||
if user is None:
|
||||
return create_user({
|
||||
'username': username,
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""A blueprint module implementing the Oauth2 authentication."""
|
||||
|
||||
import config
|
||||
|
||||
from authlib.integrations.flask_client import OAuth
|
||||
from flask import current_app, url_for, session, request,\
|
||||
redirect, Flask, flash
|
||||
from flask_babelex import gettext
|
||||
from flask_security import login_user, current_user
|
||||
from flask_security.utils import get_post_logout_redirect, \
|
||||
get_post_login_redirect, logout_user
|
||||
|
||||
from pgadmin.authenticate.internal import BaseAuthentication
|
||||
from pgadmin.model import User
|
||||
from pgadmin.tools.user_management import create_user
|
||||
from pgadmin.utils.constants import OAUTH2
|
||||
from pgadmin.utils import PgAdminModule
|
||||
from pgadmin.utils.csrf import pgCSRFProtect
|
||||
from pgadmin.model import db
|
||||
|
||||
OAUTH2_LOGOUT = 'oauth2.logout'
|
||||
OAUTH2_AUTHORIZE = 'oauth2.authorize'
|
||||
|
||||
|
||||
class Oauth2Module(PgAdminModule):
|
||||
def register(self, app, options, first_registration=False):
|
||||
# Do not look for the sub_modules,
|
||||
# instead call blueprint.register(...) directly
|
||||
super(PgAdminModule, self).register(app, options, first_registration)
|
||||
|
||||
def get_exposed_url_endpoints(self):
|
||||
return [OAUTH2_AUTHORIZE,
|
||||
OAUTH2_LOGOUT]
|
||||
|
||||
|
||||
def init_app(app):
|
||||
MODULE_NAME = 'oauth2'
|
||||
|
||||
blueprint = Oauth2Module(MODULE_NAME, __name__, static_url_path='')
|
||||
|
||||
@blueprint.route('/authorize', endpoint="authorize",
|
||||
methods=['GET', 'POST'])
|
||||
@pgCSRFProtect.exempt
|
||||
def oauth_authorize():
|
||||
auth_obj = session['auth_obj']
|
||||
auth_obj.set_current_source(auth_obj.source.get_source_name())
|
||||
status, msg = auth_obj.login()
|
||||
if status:
|
||||
session['auth_source_manager'] = auth_obj.as_dict()
|
||||
if 'auth_obj' in session:
|
||||
session.pop('auth_obj')
|
||||
return redirect(get_post_login_redirect())
|
||||
if 'auth_obj' in session:
|
||||
session.pop('auth_obj')
|
||||
logout_user()
|
||||
flash(msg, 'danger')
|
||||
return redirect(get_post_login_redirect())
|
||||
|
||||
@blueprint.route('/logout', endpoint="logout",
|
||||
methods=['GET', 'POST'])
|
||||
@pgCSRFProtect.exempt
|
||||
def oauth_logout():
|
||||
if not current_user.is_authenticated:
|
||||
return redirect(get_post_logout_redirect())
|
||||
for key in list(session.keys()):
|
||||
session.pop(key)
|
||||
logout_user()
|
||||
return redirect(get_post_logout_redirect())
|
||||
|
||||
app.register_blueprint(blueprint)
|
||||
app.login_manager.logout_view = OAUTH2_LOGOUT
|
||||
|
||||
|
||||
class OAuth2Authentication(BaseAuthentication):
|
||||
"""OAuth Authentication Class"""
|
||||
|
||||
LOGOUT_VIEW = OAUTH2_LOGOUT
|
||||
|
||||
oauth_obj = OAuth(Flask(__name__))
|
||||
oauth2_clients = {}
|
||||
oauth2_config = {}
|
||||
|
||||
def __init__(self):
|
||||
for oauth2_config in config.OAUTH2_CONFIG:
|
||||
|
||||
OAuth2Authentication.oauth2_config[
|
||||
oauth2_config['OAUTH2_NAME']] = oauth2_config
|
||||
|
||||
OAuth2Authentication.oauth2_clients[
|
||||
oauth2_config['OAUTH2_NAME']
|
||||
] = OAuth2Authentication.oauth_obj.register(
|
||||
name=oauth2_config['OAUTH2_NAME'],
|
||||
client_id=oauth2_config['OAUTH2_CLIENT_ID'],
|
||||
client_secret=oauth2_config['OAUTH2_CLIENT_SECRET'],
|
||||
access_token_url=oauth2_config['OAUTH2_TOKEN_URL'],
|
||||
authorize_url=oauth2_config['OAUTH2_AUTHORIZATION_URL'],
|
||||
api_base_url=oauth2_config['OAUTH2_API_BASE_URL'],
|
||||
client_kwargs={'scope': 'email profile'}
|
||||
)
|
||||
|
||||
def get_source_name(self):
|
||||
return OAUTH2
|
||||
|
||||
def get_friendly_name(self):
|
||||
return self.oauth2_config[self.oauth2_current_client]['OAUTH2_NAME']
|
||||
|
||||
def validate(self, form):
|
||||
return True
|
||||
|
||||
def login(self, form):
|
||||
profile = self.get_user_profile()
|
||||
if 'email' not in profile or not profile['email']:
|
||||
current_app.logger.exception(
|
||||
"An email id is required to login into pgAdmin. "
|
||||
"Please update your Oauth2 profile."
|
||||
)
|
||||
return False, gettext(
|
||||
"An email id is required to login into pgAdmin. "
|
||||
"Please update your Oauth2 profile.")
|
||||
|
||||
user, msg = self.__auto_create_user(profile)
|
||||
if user:
|
||||
user = db.session.query(User).filter_by(
|
||||
username=profile['email'], auth_source=OAUTH2).first()
|
||||
current_app.login_manager.logout_view = \
|
||||
OAuth2Authentication.LOGOUT_VIEW
|
||||
return login_user(user), None
|
||||
return False, msg
|
||||
|
||||
def get_user_profile(self):
|
||||
session['oauth2_token'] = self.oauth2_clients[
|
||||
self.oauth2_current_client].authorize_access_token()
|
||||
|
||||
session['pass_enc_key'] = session['oauth2_token']['access_token']
|
||||
|
||||
resp = self.oauth2_clients[self.oauth2_current_client].get(
|
||||
self.oauth2_config[
|
||||
self.oauth2_current_client]['OAUTH2_USERINFO_ENDPOINT'],
|
||||
token=session['oauth2_token']
|
||||
)
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
|
||||
def authenticate(self, form):
|
||||
self.oauth2_current_client = request.form['oauth2_button']
|
||||
redirect_url = url_for(OAUTH2_AUTHORIZE, _external=True)
|
||||
|
||||
if self.oauth2_current_client not in self.oauth2_clients:
|
||||
return False, gettext(
|
||||
"Please set the configuration parameters properly.")
|
||||
return False, self.oauth2_clients[
|
||||
self.oauth2_current_client].authorize_redirect(redirect_url)
|
||||
|
||||
def __auto_create_user(self, resp):
|
||||
if config.OAUTH2_AUTO_CREATE_USER:
|
||||
user = User.query.filter_by(username=resp['email'],
|
||||
auth_source=OAUTH2).first()
|
||||
if not user:
|
||||
return create_user({
|
||||
'username': resp['email'],
|
||||
'email': resp['email'],
|
||||
'role': 2,
|
||||
'active': True,
|
||||
'auth_source': OAUTH2
|
||||
})
|
||||
|
||||
return True, {'username': resp['email']}
|
||||
@@ -10,56 +10,9 @@
|
||||
"""External Authentication Registry."""
|
||||
|
||||
|
||||
from flask_babelex import gettext
|
||||
from abc import ABCMeta
|
||||
from pgadmin.utils.dynamic_registry import create_registry_metaclass
|
||||
|
||||
|
||||
def _decorate_cls_name(module_name):
|
||||
length = len(__package__) + 1
|
||||
|
||||
if len(module_name) > length and module_name.startswith(__package__):
|
||||
return module_name[length:]
|
||||
|
||||
return module_name
|
||||
|
||||
|
||||
class AuthSourceRegistry(ABCMeta):
|
||||
registry = None
|
||||
auth_sources = dict()
|
||||
|
||||
def __init__(self, name, bases, d):
|
||||
|
||||
# Register this type of auth_sources, based on the module name
|
||||
# Avoid registering the BaseAuthentication itself
|
||||
|
||||
AuthSourceRegistry.registry[_decorate_cls_name(d['__module__'])] = self
|
||||
ABCMeta.__init__(self, name, bases, d)
|
||||
|
||||
@classmethod
|
||||
def create(cls, name, **kwargs):
|
||||
|
||||
if name in AuthSourceRegistry.auth_sources:
|
||||
return AuthSourceRegistry.auth_sources[name]
|
||||
|
||||
if name in AuthSourceRegistry.registry:
|
||||
AuthSourceRegistry.auth_sources[name] = \
|
||||
(AuthSourceRegistry.registry[name])(**kwargs)
|
||||
return AuthSourceRegistry.auth_sources[name]
|
||||
|
||||
raise NotImplementedError(
|
||||
gettext(
|
||||
"Authentication source '{0}' has not been implemented."
|
||||
).format(name)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def load_auth_sources(cls):
|
||||
# Initialize the registry only if it has not yet been initialized
|
||||
if AuthSourceRegistry.registry is None:
|
||||
AuthSourceRegistry.registry = dict()
|
||||
|
||||
from importlib import import_module
|
||||
from werkzeug.utils import find_modules
|
||||
|
||||
for module_name in find_modules(__package__, True):
|
||||
import_module(module_name)
|
||||
AuthSourceRegistry = create_registry_metaclass(
|
||||
"AuthSourceRegistry", __package__, decorate_as_module=True
|
||||
)
|
||||
@@ -1,10 +1,19 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import url_for from 'sources/url_for';
|
||||
import userInfo from 'pgadmin.user_management.current_user';
|
||||
import pgConst from 'pgadmin.browser.constants';
|
||||
|
||||
function fetch_ticket() {
|
||||
// Fetch the Kerberos Updated ticket through SPNEGO
|
||||
return fetch(url_for('authenticate.kerberos_update_ticket')
|
||||
return fetch(url_for('kerberos.update_ticket')
|
||||
)
|
||||
.then(function(response){
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
@@ -18,7 +27,7 @@ function fetch_ticket() {
|
||||
function fetch_ticket_lifetime () {
|
||||
// Fetch the Kerberos ticket lifetime left
|
||||
|
||||
return fetch(url_for('authenticate.kerberos_validate_ticket')
|
||||
return fetch(url_for('kerberos.validate_ticket')
|
||||
)
|
||||
.then(
|
||||
function(response){
|
||||
|
||||
@@ -32,7 +32,7 @@ from flask_security.recoverable import reset_password_token_status, \
|
||||
from flask_security.signals import reset_password_instructions_sent
|
||||
from flask_security.utils import config_value, do_flash, get_url, \
|
||||
get_message, slash_url_suffix, login_user, send_mail, logout_user
|
||||
from flask_security.views import _security, _commit, _ctx
|
||||
from flask_security.views import _security, view_commit, _ctx
|
||||
from werkzeug.datastructures import MultiDict
|
||||
|
||||
import config
|
||||
@@ -50,7 +50,8 @@ from pgadmin.utils.master_password import validate_master_password, \
|
||||
set_crypt_key, process_masterpass_disabled
|
||||
from pgadmin.model import User
|
||||
from pgadmin.utils.constants import MIMETYPE_APP_JS, PGADMIN_NODE,\
|
||||
INTERNAL, KERBEROS, LDAP
|
||||
INTERNAL, KERBEROS, LDAP, QT_DEFAULT_PLACEHOLDER, OAUTH2
|
||||
from pgadmin.authenticate import AuthSourceManager
|
||||
|
||||
try:
|
||||
from flask_security.views import default_render_json
|
||||
@@ -342,6 +343,7 @@ class BrowserModule(PgAdminModule):
|
||||
list: a list of url endpoints exposed to the client.
|
||||
"""
|
||||
return [BROWSER_INDEX, 'browser.nodes',
|
||||
'browser.check_corrupted_db_file',
|
||||
'browser.check_master_password',
|
||||
'browser.set_master_password',
|
||||
'browser.reset_master_password',
|
||||
@@ -605,14 +607,8 @@ class BrowserPluginModule(PgAdminModule):
|
||||
|
||||
|
||||
def _get_logout_url():
|
||||
if config.SERVER_MODE and\
|
||||
session['_auth_source_manager_obj']['current_source'] == \
|
||||
KERBEROS:
|
||||
return '{0}?next={1}'.format(url_for(
|
||||
'authenticate.kerberos_logout'), url_for(BROWSER_INDEX))
|
||||
|
||||
return '{0}?next={1}'.format(
|
||||
url_for('security.logout'), url_for(BROWSER_INDEX))
|
||||
url_for(current_app.login_manager.logout_view), url_for(BROWSER_INDEX))
|
||||
|
||||
|
||||
def _get_supported_browser():
|
||||
@@ -746,10 +742,10 @@ def index():
|
||||
if len(config.AUTHENTICATION_SOURCES) == 1\
|
||||
and INTERNAL in config.AUTHENTICATION_SOURCES:
|
||||
auth_only_internal = True
|
||||
auth_source = session['_auth_source_manager_obj'][
|
||||
auth_source = session['auth_source_manager'][
|
||||
'source_friendly_name']
|
||||
|
||||
if session['_auth_source_manager_obj']['current_source'] == KERBEROS:
|
||||
if not config.MASTER_PASSWORD_REQUIRED and 'pass_enc_key' in session:
|
||||
session['allow_save_password'] = False
|
||||
|
||||
response = Response(render_template(
|
||||
@@ -851,7 +847,10 @@ def utils():
|
||||
app_version_int=config.APP_VERSION_INT,
|
||||
pg_libpq_version=pg_libpq_version,
|
||||
support_ssh_tunnel=config.SUPPORT_SSH_TUNNEL,
|
||||
logout_url=_get_logout_url()
|
||||
logout_url=_get_logout_url(),
|
||||
platform=sys.platform,
|
||||
qt_default_placeholder=QT_DEFAULT_PLACEHOLDER,
|
||||
enable_psql=config.ENABLE_PSQL
|
||||
),
|
||||
200, {'Content-Type': MIMETYPE_APP_JS})
|
||||
|
||||
@@ -872,7 +871,8 @@ def app_constants():
|
||||
render_template('browser/js/constants.js',
|
||||
INTERNAL=INTERNAL,
|
||||
LDAP=LDAP,
|
||||
KERBEROS=KERBEROS),
|
||||
KERBEROS=KERBEROS,
|
||||
OAUTH2=OAUTH2),
|
||||
200, {'Content-Type': MIMETYPE_APP_JS}
|
||||
)
|
||||
|
||||
@@ -949,6 +949,19 @@ def form_master_password_response(existing=True, present=False, errmsg=None):
|
||||
})
|
||||
|
||||
|
||||
@blueprint.route("/check_corrupted_db_file",
|
||||
endpoint="check_corrupted_db_file", methods=["GET"])
|
||||
def check_corrupted_db_file():
|
||||
"""
|
||||
Get the corrupted database file path.
|
||||
"""
|
||||
file_location = os.environ['CORRUPTED_DB_BACKUP_FILE'] \
|
||||
if 'CORRUPTED_DB_BACKUP_FILE' in os.environ else ''
|
||||
# reset the corrupted db file path in env.
|
||||
os.environ['CORRUPTED_DB_BACKUP_FILE'] = ''
|
||||
return make_json_response(data=file_location)
|
||||
|
||||
|
||||
@blueprint.route("/master_password", endpoint="check_master_password",
|
||||
methods=["GET"])
|
||||
def check_master_password():
|
||||
@@ -987,8 +1000,10 @@ def set_master_password():
|
||||
data = json.loads(data)
|
||||
|
||||
# Master password is not applicable for server mode
|
||||
if not config.SERVER_MODE and config.MASTER_PASSWORD_REQUIRED:
|
||||
|
||||
# Enable master password if oauth is used
|
||||
if not config.SERVER_MODE or OAUTH2 in config.AUTHENTICATION_SOURCES \
|
||||
or KERBEROS in config.AUTHENTICATION_SOURCES \
|
||||
and config.MASTER_PASSWORD_REQUIRED:
|
||||
# if master pass is set previously
|
||||
if current_user.masterpass_check is not None and \
|
||||
data.get('button_click') and \
|
||||
@@ -1025,7 +1040,7 @@ def set_master_password():
|
||||
existing=True,
|
||||
present=False,
|
||||
)
|
||||
elif not get_crypt_key()[0]:
|
||||
elif not get_crypt_key()[1]:
|
||||
error_message = None
|
||||
if data.get('button_click') and data.get('password') == '':
|
||||
# If user attempted to enter a blank password, then throw error
|
||||
@@ -1117,7 +1132,8 @@ if hasattr(config, 'SECURITY_CHANGEABLE') and config.SECURITY_CHANGEABLE:
|
||||
|
||||
if form.validate_on_submit():
|
||||
try:
|
||||
change_user_password(current_user, form.new_password.data)
|
||||
change_user_password(current_user._get_current_object(),
|
||||
form.new_password.data)
|
||||
except SOCKETErrorException as e:
|
||||
# Handle socket errors which are not covered by SMTPExceptions.
|
||||
logging.exception(str(e), exc_info=True)
|
||||
@@ -1143,7 +1159,7 @@ if hasattr(config, 'SECURITY_CHANGEABLE') and config.SECURITY_CHANGEABLE:
|
||||
has_error = True
|
||||
|
||||
if request.json is None and not has_error:
|
||||
after_this_request(_commit)
|
||||
after_this_request(view_commit)
|
||||
do_flash(*get_message('PASSWORD_CHANGE'))
|
||||
|
||||
old_key = get_crypt_key()[1]
|
||||
@@ -1309,9 +1325,15 @@ if hasattr(config, 'SECURITY_RECOVERABLE') and config.SECURITY_RECOVERABLE:
|
||||
has_error = True
|
||||
|
||||
if not has_error:
|
||||
after_this_request(_commit)
|
||||
after_this_request(view_commit)
|
||||
auth_obj = AuthSourceManager(form, [INTERNAL])
|
||||
session['_auth_source_manager_obj'] = auth_obj.as_dict()
|
||||
|
||||
do_flash(*get_message('PASSWORD_RESET'))
|
||||
login_user(user)
|
||||
auth_obj = AuthSourceManager(form, [INTERNAL])
|
||||
session['auth_source_manager'] = auth_obj.as_dict()
|
||||
|
||||
return redirect(get_url(_security.post_reset_view) or
|
||||
get_url(_security.post_login_view))
|
||||
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
import sys
|
||||
from flask_babelex import gettext
|
||||
from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\
|
||||
PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_TABS_SETTINGS, \
|
||||
PREF_LABEL_OPTIONS
|
||||
PREF_LABEL_OPTIONS, QT_DEFAULT_PLACEHOLDER
|
||||
from flask_security import current_user
|
||||
import config
|
||||
|
||||
LOCK_LAYOUT_LEVEL = {
|
||||
@@ -468,7 +470,7 @@ def register_browser_preferences(self):
|
||||
self.qt_tab_title = self.preference.register(
|
||||
'tab_settings', 'qt_tab_title_placeholder',
|
||||
gettext("Query tool tab title"),
|
||||
'text', '%DATABASE%/%USERNAME%@%SERVER%',
|
||||
'text', QT_DEFAULT_PLACEHOLDER,
|
||||
category_label=PREF_LABEL_DISPLAY,
|
||||
help_str=gettext(
|
||||
'Supported placeholders are %DATABASE%, %USERNAME%, and %SERVER%. '
|
||||
@@ -504,17 +506,27 @@ def register_browser_preferences(self):
|
||||
)
|
||||
)
|
||||
|
||||
ope_new_tab_options = [
|
||||
{'label': gettext('Query Tool'), 'value': 'qt'},
|
||||
{'label': gettext('Debugger'), 'value': 'debugger'},
|
||||
{'label': gettext('Schema Diff'), 'value': 'schema_diff'},
|
||||
{'label': gettext('ERD Tool'), 'value': 'erd_tool'}]
|
||||
|
||||
# Allow psq tool to open in new browser tab if ENABLE_PSQL is set to True
|
||||
if config.ENABLE_PSQL:
|
||||
ope_new_tab_options.append(
|
||||
{'label': gettext('PSQL Tool'), 'value': 'psql_tool'})
|
||||
|
||||
self.open_in_new_tab = self.preference.register(
|
||||
'tab_settings', 'new_browser_tab_open',
|
||||
gettext("Open in new browser tab"), 'select2', None,
|
||||
category_label=PREF_LABEL_OPTIONS,
|
||||
options=[{'label': gettext('Query Tool'), 'value': 'qt'},
|
||||
{'label': gettext('Debugger'), 'value': 'debugger'},
|
||||
{'label': gettext('Schema Diff'), 'value': 'schema_diff'},
|
||||
{'label': gettext('ERD Tool'), 'value': 'erd_tool'}],
|
||||
help_str=gettext('Select Query Tool, Debugger, or Schema Diff from '
|
||||
'the drop-down to set open in new browser tab for '
|
||||
'that particular module.'),
|
||||
options=ope_new_tab_options,
|
||||
help_str=gettext(
|
||||
'Select Query Tool, Debugger, Schema Diff, ERD Tool '
|
||||
'or PSQL Tool from the drop-down to set '
|
||||
'open in new browser tab for that particular module.'
|
||||
),
|
||||
select2={
|
||||
'multiple': True, 'allowClear': False,
|
||||
'tags': True, 'first_empty': False,
|
||||
@@ -523,3 +535,18 @@ def register_browser_preferences(self):
|
||||
'placeholder': gettext('Select open new tab...')
|
||||
}
|
||||
)
|
||||
|
||||
# Set PSQL tool tab title if ENABLE_PSQL is set to True
|
||||
if config.ENABLE_PSQL:
|
||||
self.psql_tab_title = self.preference.register(
|
||||
'tab_settings', 'psql_tab_title_placeholder',
|
||||
gettext("PSQL tool tab title"),
|
||||
'text', '%DATABASE%/%USERNAME%@%SERVER%',
|
||||
category_label=PREF_LABEL_DISPLAY,
|
||||
help_str=gettext(
|
||||
'Supported placeholders are %DATABASE%, %USERNAME%, '
|
||||
'and %SERVER%. Users can provide any string with or without'
|
||||
' placeholders of their choice. The blank title will be revert'
|
||||
' back to the default title with placeholders.'
|
||||
)
|
||||
)
|
||||
@@ -34,6 +34,7 @@ from pgadmin.utils.constants import UNAUTH_REQ, MIMETYPE_APP_JS, \
|
||||
SERVER_CONNECTION_CLOSED
|
||||
from sqlalchemy import or_
|
||||
from pgadmin.utils.preferences import Preferences
|
||||
from .... import socketio as sio
|
||||
|
||||
|
||||
def has_any(data, keys):
|
||||
@@ -1499,6 +1500,13 @@ class ServerNode(PGChildNodeView):
|
||||
|
||||
# Release Connection
|
||||
manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
|
||||
# Check if any psql terminal is running for the current disconnecting
|
||||
# server. If any terminate the psql tool connection.
|
||||
if 'sid_soid_mapping' in current_app.config and str(sid) in \
|
||||
current_app.config['sid_soid_mapping']:
|
||||
if str(sid) in current_app.config['sid_soid_mapping']:
|
||||
for i in current_app.config['sid_soid_mapping'][str(sid)]:
|
||||
sio.emit('disconnect-psql', namespace='/pty', to=i)
|
||||
|
||||
status = manager.release()
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__1_$%{}[]()&*^!@""'`\/#" SET DEFAULT 'changed default value';
|
||||
|
||||
GRANT SELECT("col__1_$%{}[]()&*^!@""'`\/#") ON testschema."table_2_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
@@ -0,0 +1,11 @@
|
||||
-- Column: testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__1_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__1_$%{}[]()&*^!@""'`\/#" text COLLATE pg_catalog."default" DEFAULT 'changed default value'::text;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
|
||||
GRANT SELECT("col__1_$%{}[]()&*^!@""'`\/#") ON testschema."table_2_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__2_$%{}[]()&*^!@""'`\/#" TYPE time(6) with time zone ;
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__2_$%{}[]()&*^!@""'`\/#" SET NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment modification';
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Column: testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__2_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__2_$%{}[]()&*^!@""'`\/#" time(6) with time zone NOT NULL DEFAULT now();
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment modification';
|
||||
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__3_$%{}[]()&*^!@""'`\/#"
|
||||
SET (n_distinct=2);
|
||||
@@ -0,0 +1,13 @@
|
||||
-- Column: testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__3_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__3_$%{}[]()&*^!@""'`\/#" integer[] NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'comment';
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__3_$%{}[]()&*^!@""'`\/#"
|
||||
SET (n_distinct=2);
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_2_$%{}[]()&*^!@""'`\/#" character varying(50, None) COLLATE pg_catalog."C" DEFAULT None;
|
||||
ADD COLUMN "col_2_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_6_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 10 CACHE 1 );
|
||||
ADD COLUMN "col_6_$%{}[]()&*^!@""'`\/#" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 10 CACHE 1 );
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_6_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'demo comments';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_1_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL DEFAULT 1;
|
||||
ADD COLUMN "col_1_$%{}[]()&*^!@""'`\/#" bigint NOT NULL DEFAULT 1;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_3_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL GENERATED ALWAYS AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
ADD COLUMN "col_3_$%{}[]()&*^!@""'`\/#" bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_5_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
ADD COLUMN "col_5_$%{}[]()&*^!@""'`\/#" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_5_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__1_$%{}[]()&*^!@""'`\/#" text DEFAULT 'xyz';
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Column: testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__1_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__1_$%{}[]()&*^!@""'`\/#" text COLLATE pg_catalog."default" DEFAULT 'xyz'::text;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__2_$%{}[]()&*^!@""'`\/#" time(4) with time zone DEFAULT now();
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Column: testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__2_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__2_$%{}[]()&*^!@""'`\/#" time(4) with time zone DEFAULT now();
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
@@ -0,0 +1,9 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__3_$%{}[]()&*^!@""'`\/#" integer[] NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'comment';
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__3_$%{}[]()&*^!@""'`\/#"
|
||||
SET (n_distinct=1);
|
||||
@@ -0,0 +1,13 @@
|
||||
-- Column: testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__3_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__3_$%{}[]()&*^!@""'`\/#" integer[] NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'comment';
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__3_$%{}[]()&*^!@""'`\/#"
|
||||
SET (n_distinct=1);
|
||||
@@ -26,8 +26,8 @@
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": null,
|
||||
"attprecision": null,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "1"
|
||||
@@ -138,10 +138,9 @@
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "50",
|
||||
"attprecision": null,
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": null
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_char.sql",
|
||||
"expected_msql_file": "create_column_char.msql"
|
||||
@@ -211,8 +210,8 @@
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": null,
|
||||
"attprecision": null,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"attidentity": "a",
|
||||
@@ -398,8 +397,8 @@
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": null,
|
||||
"attprecision": null,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"attidentity": "d",
|
||||
@@ -468,8 +467,8 @@
|
||||
"description": "demo comments",
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": null,
|
||||
"attprecision": null,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attidentity": "d",
|
||||
"seqincrement": "1",
|
||||
"seqstart": "1",
|
||||
@@ -526,6 +525,174 @@
|
||||
"data": {
|
||||
"name": "col_6_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Column with text & default value",
|
||||
"endpoint": "NODE-column.obj",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql",
|
||||
"data": {
|
||||
"name": "col__1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"cltype": "text",
|
||||
"attacl": [],
|
||||
"description": "test comment",
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attidentity": "a",
|
||||
"colconstype": "n",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "'xyz'"
|
||||
},
|
||||
"expected_sql_file": "create_column_text_with_default_value.sql",
|
||||
"expected_msql_file": "create_column_text_with_default_value.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter Column with text & update default value",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql_id",
|
||||
"data": {
|
||||
"name": "col__1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"defval": "'changed default value'",
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_text_with_default_value.sql",
|
||||
"expected_msql_file": "alter_column_text_with_default_value.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop Column with identity (ALWAYS)",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"data": {
|
||||
"name": "col__1_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Column with time with time zone & default value using function",
|
||||
"endpoint": "NODE-column.obj",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql",
|
||||
"data": {
|
||||
"name": "col__2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"cltype": "time with time zone",
|
||||
"attacl": [],
|
||||
"description": "test comment",
|
||||
"min_val_attlen": 0,
|
||||
"max_val_attlen": 6,
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "4",
|
||||
"attprecision": null,
|
||||
"attidentity": "a",
|
||||
"colconstype": "n",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "now()"
|
||||
},
|
||||
"expected_sql_file": "create_column_timestamp_with_default_value_using_function.sql",
|
||||
"expected_msql_file": "create_column_timestamp_with_default_value_using_function.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter Column with time with time zone & update length",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql_id",
|
||||
"data": {
|
||||
"name": "col__2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attlen": "6",
|
||||
"attnotnull": true,
|
||||
"description": "test comment modification"
|
||||
},
|
||||
"expected_sql_file": "alter_column_timestamp_with_default_value_using_function.sql",
|
||||
"expected_msql_file": "alter_column_timestamp_with_default_value_using_function.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop Column with identity (ALWAYS)",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"data": {
|
||||
"name": "col__2_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Column with interger_array and options",
|
||||
"endpoint": "NODE-column.obj",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql",
|
||||
"data": {
|
||||
"name": "col__3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"cltype": "integer[]",
|
||||
"attacl": [],
|
||||
"description": "comment",
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attidentity": "a",
|
||||
"colconstype": "n",
|
||||
"attoptions": [
|
||||
{
|
||||
"name": "n_distinct",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_with_interger_array_and_options.sql",
|
||||
"expected_msql_file": "create_column_with_interger_array_and_options.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter Column with interger_array and options",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql_id",
|
||||
"data": {
|
||||
"name": "col__3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attoptions": {
|
||||
"changed": [
|
||||
{
|
||||
"name": "n_distinct",
|
||||
"value": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_with_interger_array_and_options.sql",
|
||||
"expected_msql_file": "alter_column_with_interger_array_and_options.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop Column with identity (ALWAYS)",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"data": {
|
||||
"name": "col__3_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,7 +2,7 @@ ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
RENAME "col_2_$%{}[]()&*^!@""'`\/#" TO "new_col_2_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "new_col_2_$%{}[]()&*^!@""'`\/#" TYPE character(None) COLLATE pg_catalog."C";
|
||||
ALTER COLUMN "new_col_2_$%{}[]()&*^!@""'`\/#" TYPE character COLLATE pg_catalog."C";
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "new_col_2_$%{}[]()&*^!@""'`\/#" SET STATISTICS 5;
|
||||
|
||||
@@ -12,4 +12,4 @@ ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."new_col_2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for alter';
|
||||
|
||||
GRANT INSERT("new_col_2_$%{}[]()&*^!@""'`\/#"), SELECT("new_col_2_$%{}[]()&*^!@""'`\/#"), REFERENCES("new_col_2_$%{}[]()&*^!@""'`\/#") ON testschema."table_3_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
GRANT INSERT("new_col_2_$%{}[]()&*^!@""'`\/#"), SELECT("new_col_2_$%{}[]()&*^!@""'`\/#"), REFERENCES("new_col_2_$%{}[]()&*^!@""'`\/#") ON testschema."table_3_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__1_$%{}[]()&*^!@""'`\/#" SET DEFAULT 'changed default value';
|
||||
|
||||
GRANT SELECT("col__1_$%{}[]()&*^!@""'`\/#") ON testschema."table_3_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
@@ -0,0 +1,11 @@
|
||||
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__1_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__1_$%{}[]()&*^!@""'`\/#" text COLLATE pg_catalog."default" DEFAULT 'changed default value'::text;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
|
||||
GRANT SELECT("col__1_$%{}[]()&*^!@""'`\/#") ON testschema."table_3_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__2_$%{}[]()&*^!@""'`\/#" TYPE time(6) with time zone ;
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__2_$%{}[]()&*^!@""'`\/#" SET NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment modification';
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__2_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__2_$%{}[]()&*^!@""'`\/#" time(6) with time zone NOT NULL DEFAULT now();
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment modification';
|
||||
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__3_$%{}[]()&*^!@""'`\/#"
|
||||
SET (n_distinct=2);
|
||||
@@ -0,0 +1,13 @@
|
||||
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__3_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__3_$%{}[]()&*^!@""'`\/#" integer[] NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'comment';
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__3_$%{}[]()&*^!@""'`\/#"
|
||||
SET (n_distinct=2);
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_2_$%{}[]()&*^!@""'`\/#" character varying(50, None) COLLATE pg_catalog."C" DEFAULT None;
|
||||
ADD COLUMN "col_2_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_1_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL DEFAULT 1;
|
||||
ADD COLUMN "col_1_$%{}[]()&*^!@""'`\/#" bigint NOT NULL DEFAULT 1;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_4_$%{}[]()&*^!@""'`\/#" bigint(None, None) GENERATED ALWAYS AS (1 + 2 + 3) STORED;
|
||||
ADD COLUMN "col_4_$%{}[]()&*^!@""'`\/#" bigint GENERATED ALWAYS AS (1 + 2 + 3) STORED;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_4_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_8_$%{}[]()&*^!@""'`\/#" bigint(None, None) GENERATED ALWAYS AS (dummy1 + dummy2) STORED;
|
||||
ADD COLUMN "col_8_$%{}[]()&*^!@""'`\/#" bigint GENERATED ALWAYS AS (dummy1 + dummy2) STORED;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_8_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_3_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL GENERATED ALWAYS AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
ADD COLUMN "col_3_$%{}[]()&*^!@""'`\/#" bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_9_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
ADD COLUMN "col_9_$%{}[]()&*^!@""'`\/#" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col_9_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__1_$%{}[]()&*^!@""'`\/#" text DEFAULT 'xyz';
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__1_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__1_$%{}[]()&*^!@""'`\/#" text COLLATE pg_catalog."default" DEFAULT 'xyz'::text;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__2_$%{}[]()&*^!@""'`\/#" time(4) with time zone DEFAULT now();
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__2_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__2_$%{}[]()&*^!@""'`\/#" time(4) with time zone DEFAULT now();
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'test comment';
|
||||
@@ -0,0 +1,9 @@
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__3_$%{}[]()&*^!@""'`\/#" integer[] NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'comment';
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__3_$%{}[]()&*^!@""'`\/#"
|
||||
SET (n_distinct=1);
|
||||
@@ -0,0 +1,13 @@
|
||||
-- Column: testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__3_$%{}[]()&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__3_$%{}[]()&*^!@""'`\/#" integer[] NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_3_$%{}[]()&*^!@""'`\/#"."col__3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'comment';
|
||||
|
||||
ALTER TABLE testschema."table_3_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__3_$%{}[]()&*^!@""'`\/#"
|
||||
SET (n_distinct=1);
|
||||
@@ -22,15 +22,15 @@
|
||||
"data": {
|
||||
"name": "col_1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"cltype":"bigint",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":true,
|
||||
"attlen":null,
|
||||
"attprecision":null,
|
||||
"attoptions":[],
|
||||
"seclabels":[],
|
||||
"defval":"1"
|
||||
"cltype": "bigint",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "1"
|
||||
},
|
||||
"expected_sql_file": "create_column_int.sql",
|
||||
"expected_msql_file": "create_column_int.msql"
|
||||
@@ -45,8 +45,37 @@
|
||||
"attnum": 1,
|
||||
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for alter",
|
||||
"cltype":"real",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"w","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"cltype": "real",
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "w",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_int.sql",
|
||||
"expected_msql_file": "alter_column_int.msql"
|
||||
@@ -60,7 +89,26 @@
|
||||
"data": {
|
||||
"attnum": 1,
|
||||
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attacl":{"changed":[{"grantee":"postgres", "grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false}]}]}
|
||||
"attacl": {
|
||||
"changed": [
|
||||
{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_alt_privilege.sql",
|
||||
"expected_msql_file": "alter_column_alt_privilege.msql"
|
||||
@@ -83,16 +131,15 @@
|
||||
"data": {
|
||||
"name": "col_2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"cltype":"character varying",
|
||||
"cltype": "character varying",
|
||||
"collspcname": "pg_catalog.\"C\"",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":false,
|
||||
"attlen":"50",
|
||||
"attprecision":null,
|
||||
"attoptions":[],
|
||||
"seclabels":[],
|
||||
"defval":null
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "50",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_char.sql",
|
||||
"expected_msql_file": "create_column_char.msql"
|
||||
@@ -106,12 +153,36 @@
|
||||
"data": {
|
||||
"attnum": 2,
|
||||
"name": "new_col_2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attlen": null,
|
||||
"attlen": "",
|
||||
"attstattarget": "5",
|
||||
"attstorage": "p",
|
||||
"description": "Comment for alter",
|
||||
"cltype":"character",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"cltype": "character",
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_char.sql",
|
||||
"expected_msql_file": "alter_column_char.msql"
|
||||
@@ -134,22 +205,22 @@
|
||||
"data": {
|
||||
"name": "col_3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"cltype":"bigint",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":true,
|
||||
"attlen":null,
|
||||
"attprecision":null,
|
||||
"attoptions":[],
|
||||
"seclabels":[],
|
||||
"attidentity":"a",
|
||||
"seqincrement":"1",
|
||||
"seqstart":"1",
|
||||
"seqmin":"1",
|
||||
"seqmax":"99999",
|
||||
"seqcache":"10",
|
||||
"seqcycle":true,
|
||||
"colconstype":"i"
|
||||
"cltype": "bigint",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"attidentity": "a",
|
||||
"seqincrement": "1",
|
||||
"seqstart": "1",
|
||||
"seqmin": "1",
|
||||
"seqmax": "99999",
|
||||
"seqcache": "10",
|
||||
"seqcycle": true,
|
||||
"colconstype": "i"
|
||||
},
|
||||
"expected_sql_file": "create_column_int_identity.sql",
|
||||
"expected_msql_file": "create_column_int_identity.msql"
|
||||
@@ -164,7 +235,31 @@
|
||||
"attnum": 3,
|
||||
"name": "new_col_3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for alter",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_identity.sql",
|
||||
"expected_msql_file": "alter_column_identity.msql"
|
||||
@@ -200,17 +295,17 @@
|
||||
"data": {
|
||||
"name": "col_4_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"cltype":"bigint",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":false,
|
||||
"attlen":null,
|
||||
"attprecision":null,
|
||||
"attidentity":"a",
|
||||
"colconstype":"g",
|
||||
"genexpr":"1 + 2 + 3",
|
||||
"attoptions":[],
|
||||
"seclabels":[]
|
||||
"cltype": "bigint",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attidentity": "a",
|
||||
"colconstype": "g",
|
||||
"genexpr": "1 + 2 + 3",
|
||||
"attoptions": [],
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_int_generated.sql",
|
||||
"expected_msql_file": "create_column_int_generated.msql"
|
||||
@@ -225,7 +320,31 @@
|
||||
"attnum": 4,
|
||||
"name": "new_col_4_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for alter",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_generated.sql",
|
||||
"expected_msql_file": "alter_column_generated.msql"
|
||||
@@ -248,17 +367,22 @@
|
||||
"data": {
|
||||
"name": "col_5_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"min_val":0,
|
||||
"max_val":1000,
|
||||
"cltype":"numeric",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":true,
|
||||
"attlen":"10",
|
||||
"attprecision":"5",
|
||||
"attidentity":"a",
|
||||
"attoptions":[{"name":"n_distinct","value":"1"}],
|
||||
"seclabels":[]
|
||||
"min_val": 0,
|
||||
"max_val": 1000,
|
||||
"cltype": "numeric",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "10",
|
||||
"attprecision": "5",
|
||||
"attidentity": "a",
|
||||
"attoptions": [
|
||||
{
|
||||
"name": "n_distinct",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_numeric.sql",
|
||||
"expected_msql_file": "create_column_numeric.msql"
|
||||
@@ -272,10 +396,39 @@
|
||||
"data": {
|
||||
"name": "new_col_5_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attnum": 5,
|
||||
"attlen":"15",
|
||||
"attprecision":"6",
|
||||
"attlen": "15",
|
||||
"attprecision": "6",
|
||||
"description": "Comment for alter",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"w","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "w",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_numeric.sql",
|
||||
"expected_msql_file": "alter_column_numeric.msql"
|
||||
@@ -288,7 +441,7 @@
|
||||
"msql_endpoint": "NODE-column.msql_id",
|
||||
"data": {
|
||||
"attnum": 3,
|
||||
"attlen":""
|
||||
"attlen": ""
|
||||
},
|
||||
"expected_sql_file": "alter_column_remove_length.sql",
|
||||
"expected_msql_file": "alter_column_remove_length.msql"
|
||||
@@ -302,7 +455,6 @@
|
||||
"name": "new_col_5_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Dummy Column (Integer/Numeric type)",
|
||||
@@ -312,15 +464,15 @@
|
||||
"data": {
|
||||
"name": "dummy1",
|
||||
"description": "Comment for create",
|
||||
"cltype":"bigint",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":true,
|
||||
"attlen":null,
|
||||
"attprecision":null,
|
||||
"attoptions":[],
|
||||
"seclabels":[],
|
||||
"defval":"1"
|
||||
"cltype": "bigint",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -332,15 +484,15 @@
|
||||
"data": {
|
||||
"name": "dummy2",
|
||||
"description": "Comment for create",
|
||||
"cltype":"bigint",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":true,
|
||||
"attlen":null,
|
||||
"attprecision":null,
|
||||
"attoptions":[],
|
||||
"seclabels":[],
|
||||
"defval":"1"
|
||||
"cltype": "bigint",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -352,17 +504,17 @@
|
||||
"data": {
|
||||
"name": "col_8_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"cltype":"bigint",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":false,
|
||||
"attlen":null,
|
||||
"attprecision":null,
|
||||
"attidentity":"a",
|
||||
"colconstype":"g",
|
||||
"genexpr":"dummy1 + dummy2",
|
||||
"attoptions":[],
|
||||
"seclabels":[]
|
||||
"cltype": "bigint",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attidentity": "a",
|
||||
"colconstype": "g",
|
||||
"genexpr": "dummy1 + dummy2",
|
||||
"attoptions": [],
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_int_generated_with_existing_columns.sql",
|
||||
"expected_msql_file": "create_column_int_generated_with_existing_columns.msql"
|
||||
@@ -376,9 +528,33 @@
|
||||
"data": {
|
||||
"attnum": 8,
|
||||
"name": "new_col_8_$%{}[]()&*^!@\"'`\\/#",
|
||||
"genexpr":"dummy1 - dummy2",
|
||||
"genexpr": "dummy1 - dummy2",
|
||||
"description": "Comment for alter",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_generated_with_existing_columns.sql",
|
||||
"expected_msql_file": "alter_column_generated_with_existing_columns.msql"
|
||||
@@ -392,7 +568,6 @@
|
||||
"name": "new_col_8_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Column with identity (Generated by default)",
|
||||
@@ -402,22 +577,22 @@
|
||||
"data": {
|
||||
"name": "col_9_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"cltype":"bigint",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":true,
|
||||
"attlen":null,
|
||||
"attprecision":null,
|
||||
"attoptions":[],
|
||||
"seclabels":[],
|
||||
"attidentity":"d",
|
||||
"seqincrement":"1",
|
||||
"seqstart":"1",
|
||||
"seqmin":"1",
|
||||
"seqmax":"99999",
|
||||
"seqcache":"10",
|
||||
"seqcycle":true,
|
||||
"colconstype":"i"
|
||||
"cltype": "bigint",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"attidentity": "d",
|
||||
"seqincrement": "1",
|
||||
"seqstart": "1",
|
||||
"seqmin": "1",
|
||||
"seqmax": "99999",
|
||||
"seqcache": "10",
|
||||
"seqcycle": true,
|
||||
"colconstype": "i"
|
||||
},
|
||||
"expected_sql_file": "create_column_int_identity_by_default.sql",
|
||||
"expected_msql_file": "create_column_int_identity_by_default.msql"
|
||||
@@ -432,11 +607,11 @@
|
||||
"attnum": 9,
|
||||
"name": "new_col_9_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for alter",
|
||||
"seqincrement":"2",
|
||||
"seqmax":"200",
|
||||
"seqcache":"2",
|
||||
"seqcycle":true,
|
||||
"seqmin":"1"
|
||||
"seqincrement": "2",
|
||||
"seqmax": "200",
|
||||
"seqcache": "2",
|
||||
"seqcycle": true,
|
||||
"seqmin": "1"
|
||||
},
|
||||
"expected_sql_file": "alter_column_identity_by_default.sql",
|
||||
"expected_msql_file": "alter_column_identity_by_default.msql"
|
||||
@@ -534,6 +709,174 @@
|
||||
"data": {
|
||||
"name": "col_6_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Column with text & default value",
|
||||
"endpoint": "NODE-column.obj",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql",
|
||||
"data": {
|
||||
"name": "col__1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"cltype": "text",
|
||||
"attacl": [],
|
||||
"description": "test comment",
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attidentity": "a",
|
||||
"colconstype": "n",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "'xyz'"
|
||||
},
|
||||
"expected_sql_file": "create_column_text_with_default_value.sql",
|
||||
"expected_msql_file": "create_column_text_with_default_value.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter Column with text & update default value",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql_id",
|
||||
"data": {
|
||||
"name": "col__1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"defval": "'changed default value'",
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_text_with_default_value.sql",
|
||||
"expected_msql_file": "alter_column_text_with_default_value.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop Column with identity (ALWAYS)",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"data": {
|
||||
"name": "col__1_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Column with time with time zone & default value using function",
|
||||
"endpoint": "NODE-column.obj",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql",
|
||||
"data": {
|
||||
"name": "col__2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"cltype": "time with time zone",
|
||||
"attacl": [],
|
||||
"description": "test comment",
|
||||
"min_val_attlen": 0,
|
||||
"max_val_attlen": 6,
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "4",
|
||||
"attprecision": null,
|
||||
"attidentity": "a",
|
||||
"colconstype": "n",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "now()"
|
||||
},
|
||||
"expected_sql_file": "create_column_timestamp_with_default_value_using_function.sql",
|
||||
"expected_msql_file": "create_column_timestamp_with_default_value_using_function.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter Column with time with time zone & update length",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql_id",
|
||||
"data": {
|
||||
"name": "col__2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attlen": "6",
|
||||
"attnotnull": true,
|
||||
"description": "test comment modification"
|
||||
},
|
||||
"expected_sql_file": "alter_column_timestamp_with_default_value_using_function.sql",
|
||||
"expected_msql_file": "alter_column_timestamp_with_default_value_using_function.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop Column with identity (ALWAYS)",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"data": {
|
||||
"name": "col__2_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Column with interger_array and options",
|
||||
"endpoint": "NODE-column.obj",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql",
|
||||
"data": {
|
||||
"name": "col__3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"cltype": "integer[]",
|
||||
"attacl": [],
|
||||
"description": "comment",
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attidentity": "a",
|
||||
"colconstype": "n",
|
||||
"attoptions": [
|
||||
{
|
||||
"name": "n_distinct",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_with_interger_array_and_options.sql",
|
||||
"expected_msql_file": "create_column_with_interger_array_and_options.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter Column with interger_array and options",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"msql_endpoint": "NODE-column.msql_id",
|
||||
"data": {
|
||||
"name": "col__3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attoptions": {
|
||||
"changed": [
|
||||
{
|
||||
"name": "n_distinct",
|
||||
"value": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_with_interger_array_and_options.sql",
|
||||
"expected_msql_file": "alter_column_with_interger_array_and_options.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop Column with identity (ALWAYS)",
|
||||
"endpoint": "NODE-column.obj_id",
|
||||
"sql_endpoint": "NODE-column.sql_id",
|
||||
"data": {
|
||||
"name": "col__3_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_1_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_2_$%{}[]()&*^!@""'`\/#" character varying(50, None) COLLATE pg_catalog."C" DEFAULT None;
|
||||
ADD COLUMN "col_2_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
|
||||
|
||||
COMMENT ON COLUMN testschema."table_1_$%{}[]()&*^!@""'`\/#"."col_2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_1_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_1_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL DEFAULT 1;
|
||||
ADD COLUMN "col_1_$%{}[]()&*^!@""'`\/#" bigint NOT NULL DEFAULT 1;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_1_$%{}[]()&*^!@""'`\/#"."col_1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -22,15 +22,15 @@
|
||||
"data": {
|
||||
"name": "col_1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"cltype":"bigint",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":true,
|
||||
"attlen":null,
|
||||
"attprecision":null,
|
||||
"attoptions":[],
|
||||
"seclabels":[],
|
||||
"defval":"1"
|
||||
"cltype": "bigint",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "1"
|
||||
},
|
||||
"expected_sql_file": "create_column_int.sql",
|
||||
"expected_msql_file": "create_column_int.msql"
|
||||
@@ -45,8 +45,37 @@
|
||||
"attnum": 1,
|
||||
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for alter",
|
||||
"cltype":"real",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"w","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"cltype": "real",
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "w",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_int.sql",
|
||||
"expected_msql_file": "alter_column_int.msql"
|
||||
@@ -60,7 +89,26 @@
|
||||
"data": {
|
||||
"attnum": 1,
|
||||
"name": "new_col_1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attacl":{"changed":[{"grantee":"postgres", "grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false}]}]}
|
||||
"attacl": {
|
||||
"changed": [
|
||||
{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_alt_privilege.sql",
|
||||
"expected_msql_file": "alter_column_alt_privilege.msql"
|
||||
@@ -83,16 +131,15 @@
|
||||
"data": {
|
||||
"name": "col_2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"cltype":"character varying",
|
||||
"cltype": "character varying",
|
||||
"collspcname": "pg_catalog.\"C\"",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":false,
|
||||
"attlen":"50",
|
||||
"attprecision":null,
|
||||
"attoptions":[],
|
||||
"seclabels":[],
|
||||
"defval":null
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "50",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_char.sql",
|
||||
"expected_msql_file": "create_column_char.msql"
|
||||
@@ -110,8 +157,32 @@
|
||||
"attstattarget": "5",
|
||||
"attstorage": "p",
|
||||
"description": "Comment for alter",
|
||||
"cltype":"character",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"cltype": "character",
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_char.sql",
|
||||
"expected_msql_file": "alter_column_char.msql"
|
||||
@@ -125,7 +196,6 @@
|
||||
"name": "new_col_2_$%{}[]()&*^!@\"'`\\/#"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Column (Numeric type with Length Precision & Variables)",
|
||||
@@ -135,17 +205,22 @@
|
||||
"data": {
|
||||
"name": "col_3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"description": "Comment for create",
|
||||
"min_val":0,
|
||||
"max_val":1000,
|
||||
"cltype":"numeric",
|
||||
"attacl":[],
|
||||
"is_primary_key":false,
|
||||
"attnotnull":true,
|
||||
"attlen":"10",
|
||||
"attprecision":"5",
|
||||
"attidentity":"a",
|
||||
"attoptions":[{"name":"n_distinct","value":"1"}],
|
||||
"seclabels":[]
|
||||
"min_val": 0,
|
||||
"max_val": 1000,
|
||||
"cltype": "numeric",
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": "10",
|
||||
"attprecision": "5",
|
||||
"attidentity": "a",
|
||||
"attoptions": [
|
||||
{
|
||||
"name": "n_distinct",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_numeric.sql",
|
||||
"expected_msql_file": "create_column_numeric.msql"
|
||||
@@ -159,10 +234,39 @@
|
||||
"data": {
|
||||
"name": "new_col_3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"attnum": 3,
|
||||
"attlen":"15",
|
||||
"attprecision":"6",
|
||||
"attlen": "15",
|
||||
"attprecision": "6",
|
||||
"description": "Comment for alter",
|
||||
"attacl":{"added":[{"grantee":"PUBLIC","grantor":"postgres","privileges":[{"privilege_type":"a","privilege":true,"with_grant":false},{"privilege_type":"r","privilege":true,"with_grant":false},{"privilege_type":"w","privilege":true,"with_grant":false},{"privilege_type":"x","privilege":true,"with_grant":false}]}]}
|
||||
"attacl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "a",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "r",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "w",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
},
|
||||
{
|
||||
"privilege_type": "x",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_column_numeric.sql",
|
||||
"expected_msql_file": "alter_column_numeric.msql"
|
||||
@@ -175,7 +279,7 @@
|
||||
"msql_endpoint": "NODE-column.msql_id",
|
||||
"data": {
|
||||
"attnum": 3,
|
||||
"attlen":""
|
||||
"attlen": ""
|
||||
},
|
||||
"expected_sql_file": "alter_column_remove_length.sql",
|
||||
"expected_msql_file": "alter_column_remove_length.msql"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
RENAME "col__1_$%{}[]()&*^!@""'`\/#" TO "col__1_$%{}[]&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__1_$%{}[]&*^!@""'`\/#" SET DEFAULT 'changed default value'::text;
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ALTER COLUMN "col__1_$%{}[]&*^!@""'`\/#" DROP NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]&*^!@""'`\/#"
|
||||
IS 'test comment modify';
|
||||
|
||||
GRANT SELECT("col__1_$%{}[]&*^!@""'`\/#") ON testschema."table_2_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
@@ -0,0 +1,11 @@
|
||||
-- Column: testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]&*^!@""'`\/#"
|
||||
|
||||
-- ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#" DROP COLUMN "col__1_$%{}[]&*^!@""'`\/#";
|
||||
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col__1_$%{}[]&*^!@""'`\/#" text COLLATE pg_catalog."C" DEFAULT 'changed default value'::text;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col__1_$%{}[]&*^!@""'`\/#"
|
||||
IS 'test comment modify';
|
||||
|
||||
GRANT SELECT("col__1_$%{}[]&*^!@""'`\/#") ON testschema."table_2_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_2_$%{}[]()&*^!@""'`\/#" character varying(50, None) COLLATE pg_catalog."C" DEFAULT None;
|
||||
ADD COLUMN "col_2_$%{}[]()&*^!@""'`\/#" character varying(50) COLLATE pg_catalog."C";
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_2_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_6_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 10 CACHE 1 );
|
||||
ADD COLUMN "col_6_$%{}[]()&*^!@""'`\/#" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 10 CACHE 1 );
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_6_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'demo comments';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_1_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL DEFAULT 1;
|
||||
ADD COLUMN "col_1_$%{}[]()&*^!@""'`\/#" bigint NOT NULL DEFAULT 1;
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_1_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_3_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL GENERATED ALWAYS AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
ADD COLUMN "col_3_$%{}[]()&*^!@""'`\/#" bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_3_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -1,5 +1,5 @@
|
||||
ALTER TABLE testschema."table_2_$%{}[]()&*^!@""'`\/#"
|
||||
ADD COLUMN "col_5_$%{}[]()&*^!@""'`\/#" bigint(None, None) NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
ADD COLUMN "col_5_$%{}[]()&*^!@""'`\/#" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( CYCLE INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 99999 CACHE 10 );
|
||||
|
||||
COMMENT ON COLUMN testschema."table_2_$%{}[]()&*^!@""'`\/#"."col_5_$%{}[]()&*^!@""'`\/#"
|
||||
IS 'Comment for create';
|
||||
IS 'Comment for create';
|
||||
@@ -26,8 +26,8 @@
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": null,
|
||||
"attprecision": null,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": "1"
|
||||
@@ -138,10 +138,9 @@
|
||||
"is_primary_key": false,
|
||||
"attnotnull": false,
|
||||
"attlen": "50",
|
||||
"attprecision": null,
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"defval": null
|
||||
"seclabels": []
|
||||
},
|
||||
"expected_sql_file": "create_column_char.sql",
|
||||
"expected_msql_file": "create_column_char.msql"
|
||||
@@ -211,8 +210,8 @@
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": null,
|
||||
"attprecision": null,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"attidentity": "a",
|
||||
@@ -398,8 +397,8 @@
|
||||
"attacl": [],
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": null,
|
||||
"attprecision": null,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attoptions": [],
|
||||
"seclabels": [],
|
||||
"attidentity": "d",
|
||||
@@ -468,8 +467,8 @@
|
||||
"description": "demo comments",
|
||||
"is_primary_key": false,
|
||||
"attnotnull": true,
|
||||
"attlen": null,
|
||||
"attprecision": null,
|
||||
"attlen": "",
|
||||
"attprecision": "",
|
||||
"attidentity": "d",
|
||||
"seqincrement": "1",
|
||||
"seqstart": "1",
|
||||
|
||||