• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / Zope / 4565856981

pending completion
4565856981

push

github

GitHub
Implement code change suggestions from CodeQL scanning (#1112)

4269 of 6879 branches covered (62.06%)

Branch coverage included in aggregate %.

31 of 31 new or added lines in 5 files covered. (100.0%)

27047 of 31353 relevant lines covered (86.27%)

0.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Zope2/utilities/mkwsgiinstance.py
1
##############################################################################
2
#
3
# Copyright (c) 2002 Zope Foundation and Contributors.
4
#
5
# This software is subject to the provisions of the Zope Public License,
6
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
7
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10
# FOR A PARTICULAR PURPOSE
11
#
12
##############################################################################
13

14
"""%(program)s:  Create a Zope WSGI instance home.
×
15

16
usage:  %(program)s [options]
17

18
Options:
19
-h/--help -- print this help text
20
-d/--dir  -- the dir in which the instance home should be created
21
-u/--user NAME:PASSWORD -- set the user name and password of the initial user
22
-s/--skelsrc -- the dir from which skeleton files should be copied
23
-p/--python -- the Python interpreter to use
24

25
When run without arguments, this script will ask for the information
26
necessary to create a Zope WSGI instance home.
27
"""
28

29
import getopt
×
30
import os
×
31
import subprocess
×
32
import sys
×
33
from configparser import ParsingError
×
34
from configparser import RawConfigParser
×
35

36
from AuthEncoding import pw_encrypt
×
37

38
from . import copyzopeskel
×
39

40

41
def main():
×
42
    try:
×
43
        opts, args = getopt.getopt(
×
44
            sys.argv[1:],
45
            "hu:d:s:p:",
46
            ["help", "user=", "dir=", "skelsrc=", "python="]
47
        )
48
    except getopt.GetoptError as msg:
×
49
        usage(sys.stderr, msg)
×
50
        sys.exit(2)
×
51

52
    script_path = os.path.abspath(os.path.dirname(sys.argv[0]))
×
53
    user = None
×
54
    password = None
×
55
    skeltarget = None
×
56
    skelsrc = None
×
57
    python = None
×
58

59
    if check_buildout(script_path):
×
60
        python = os.path.join(script_path, 'zopepy')
×
61

62
    for opt, arg in opts:
×
63
        if opt in ("-d", "--dir"):
×
64
            skeltarget = os.path.abspath(os.path.expanduser(arg))
×
65
            if not skeltarget:
×
66
                usage(sys.stderr, "dir must not be empty")
×
67
                sys.exit(2)
×
68
        if opt in ("-s", "--skelsrc"):
×
69
            skelsrc = os.path.abspath(os.path.expanduser(arg))
×
70
            if not skelsrc:
×
71
                usage(sys.stderr, "skelsrc must not be empty")
×
72
                sys.exit(2)
×
73
        if opt in ("-p", "--python"):
×
74
            python = os.path.abspath(os.path.expanduser(arg))
×
75
            if not os.path.exists(python) and os.path.isfile(python):
×
76
                usage(sys.stderr, "The Python interpreter does not exist.")
×
77
                sys.exit(2)
×
78
        if opt in ("-h", "--help"):
×
79
            usage(sys.stdout)
×
80
            sys.exit()
×
81
        if opt in ("-u", "--user"):
×
82
            if not arg:
×
83
                usage(sys.stderr, "user must not be empty")
×
84
                sys.exit(2)
×
85
            if ":" not in arg:
×
86
                usage(sys.stderr, "user must be specified as name:password")
×
87
                sys.exit(2)
×
88
            user, password = arg.split(":", 1)
×
89

90
    if not skeltarget:
×
91
        # interactively ask for skeltarget and initial user name/passwd.
92
        # cant set custom instancehome in interactive mode, we default
93
        # to skeltarget.
94
        skeltarget = instancehome = os.path.abspath(
×
95
            os.path.expanduser(get_skeltarget())
96
        )
97

98
    instancehome = skeltarget
×
99
    if skelsrc is None:
×
100
        # default to using stock Zope skeleton source
101
        skelsrc = os.path.join(os.path.dirname(__file__), "skel")
×
102

103
    inituser = os.path.join(instancehome, "inituser")
×
104
    if not (user or os.path.exists(inituser)):
×
105
        user, password = get_inituser()
×
106

107
    # we need to distinguish between python.exe and pythonw.exe under
108
    # Windows.  Zope is always run using 'python.exe' (even for services),
109
    # however, it may be installed via pythonw.exe (as a sub-process of an
110
    # installer).  Thus, sys.executable may not be the executable we use.
111
    # We still provide both PYTHON and PYTHONW, but PYTHONW should never
112
    # need be used.
113
    if python is None:
×
114
        python = sys.executable
×
115

116
    psplit = os.path.split(python)
×
117
    exedir = os.path.join(*psplit[:-1])
×
118
    pythonexe = os.path.join(exedir, 'python.exe')
×
119
    pythonwexe = os.path.join(exedir, 'pythonw.exe')
×
120

121
    if os.path.isfile(pythonwexe) and \
×
122
       os.path.isfile(pythonexe) and \
123
       python in [pythonwexe, pythonexe]:
124
        # we're using a Windows build with both python.exe and pythonw.exe
125
        # in the same directory
126
        PYTHON = pythonexe
×
127
        PYTHONW = pythonwexe
×
128
    else:
129
        # we're on UNIX or we have a nonstandard Windows setup
130
        PYTHON = PYTHONW = python
×
131

132
    zope2path = get_zope2path(PYTHON)
×
133

134
    kw = {
×
135
        "PYTHON": PYTHON,
136
        "PYTHONW": PYTHONW,
137
        "INSTANCE_HOME": instancehome,
138
        "ZOPE_SCRIPTS": script_path,
139
        "ZOPE2PATH": zope2path,
140
    }
141

142
    copyzopeskel.copyskel(skelsrc, skeltarget, None, None, **kw)
×
143
    if user and password:
×
144
        write_inituser(inituser, user, password)
×
145

146

147
def usage(stream, msg=None):
×
148
    if msg:
×
149
        stream.write(msg)
×
150
        stream.write('\n')
×
151

152
    program = os.path.basename(sys.argv[0])
×
153
    stream.write(__doc__ % {"program": program})
×
154

155

156
def get_skeltarget():
×
157
    print('Please choose a directory in which you\'d like to install')
×
158
    print('Zope "instance home" files such as database files, configuration')
×
159
    print('files, etc.\n')
×
160
    while 1:
161
        skeltarget = input("Directory: ").strip()
×
162
        if skeltarget == '':
×
163
            print('You must specify a directory')
×
164
            continue
×
165
        else:
166
            break
×
167
    return skeltarget
×
168

169

170
def get_inituser():
×
171
    import getpass
×
172
    print('Please choose a username and password for the initial user.')
×
173
    print('These will be the credentials you use to initially manage')
×
174
    print('your new Zope instance.\n')
×
175
    user = input("Username: ").strip()
×
176
    if user == '':
×
177
        return None, None
×
178
    while 1:
179
        passwd = getpass.getpass("Password: ")
×
180
        verify = getpass.getpass("Verify password: ")
×
181
        if verify == passwd:
×
182
            break
×
183
        else:
184
            passwd = verify = ''
×
185
            print("Password mismatch, please try again...")
×
186
    return user, passwd
×
187

188

189
def write_inituser(fn, user, password):
×
190
    try:  # Try safest encryption first
×
191
        pw = pw_encrypt(password, 'BCRYPT')
×
192
    except ValueError:  # bcrypt is not available
×
193
        pw = pw_encrypt(password, 'SHA256')
×
194

195
    if isinstance(user, str):
×
196
        user = user.encode('UTF-8')
×
197

198
    with open(fn, "wb") as fp:
×
199
        fp.write(user + b':' + pw + b'\n')
×
200
    os.chmod(fn, 0o644)
×
201

202

203
def check_buildout(script_path):
×
204
    """ Are we running from within a buildout which supplies 'zopepy'?
205
    """
206
    buildout_cfg = os.path.join(os.path.dirname(script_path), 'buildout.cfg')
×
207
    if os.path.exists(buildout_cfg):
×
208
        parser = RawConfigParser()
×
209
        try:
×
210
            parser.read(buildout_cfg)
×
211
            return 'zopepy' in parser.sections()
×
212
        except ParsingError:
×
213
            # zc.buildout uses its own parser and it allows syntax that
214
            # ConfigParser does not like. Here's one really stupid workaround.
215
            # The alternative is using the zc.buildout parser, which would
216
            # introduce a hard dependency.
217
            zope_py = os.path.join(os.path.dirname(script_path),
×
218
                                   'bin', 'zopepy')
219
            if os.path.isfile(zope_py) and os.access(zope_py, os.X_OK):
×
220
                return True
×
221

222

223
def get_zope2path(python):
×
224
    """ Get Zope2 path from selected Python interpreter.
225
    """
226
    zope2file = ''
×
227
    try:
×
228
        output = subprocess.check_output(
×
229
            [python, '-c', 'import Zope2; print(Zope2.__file__)'],
230
            universal_newlines=True,  # makes Python 3 return text, not bytes
231
            stderr=subprocess.PIPE)
232
        zope2file = output.strip()
×
233
    except subprocess.CalledProcessError:
×
234
        # fall back to current Python interpreter
235
        import Zope2
×
236
        zope2file = Zope2.__file__
×
237
    return os.path.abspath(os.path.dirname(os.path.dirname(zope2file)))
×
238

239

240
if __name__ == "__main__":
×
241
    main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc