137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323 | def main(
content_source,
bip_source=DEFAULT_SOURCE,
version=None,
python_package_repository=None,
username=DEFAULT_USERNAME,
password=DEFAULT_PASSWORD,
clear_database=False,
populate_default=True,
):
"""Initializes an empty Neo4j database for Bip.
Creates elementary data in order to make the database
compatible with Bip.
- Default user privileges: admin, user and guest.
- Default user role: internal.
- Default user with admin privilege. If not specified, the username
will be "_admin_" and the password will be "_bip_".
This function must be executed on an **empty database**.
Args:
content_source (str): A valid git url to a content repository.
bip_source (str, optional): A valid git url to a Bip repository.
- Use this parameter if you are using your own fork of Bip.
- The official repository is use if unspecified.
version (str, optional): Version number. Defaults to None.
- It must be an existing model in the `bip_source` repository. Formatted like so `vX.X.X`.
- If left to None, the most recent model found in the bip_source repository is used.
username (str, optional): If set, it will override the default username ("admin")
Must contain only alphanumerical characters, dashes, dots and underscores.
password (str, optional): If set, it will override the default password ("bip")
Returns:
Config: The server config object that has been created.
Raises:
ValueError:
- The database is already populated.
- The username contains forbidden characters
- The server config already exists on the server.
- `content_source` is not a valid Git repository.
- `bip_source` is not a valid Git repository.
- `version` is not found in the `bip_source` repository models.
"""
if clear_database:
link.logger.info("Install: clear database.")
sink.utils.reset_database()
os.environ["_BIP_IGNORE_PERMISSIONS"] = "1"
# Check if the database is empty
if not database.is_empty():
raise ValueError("Impossible to initialize the database if it not empty.")
# Check if username is valid (no special characters)
# Even if this test if made in the user validation,
# we test this before in order to make sure that the user creation
# won't fail after the roles and privileges have been created.
if any(char in username for char in link.user.FORBIDDEN_CHARACTERS):
raise ValueError(
"The username cannot contain special characters apart from the dash, the underscore and the period"
)
# Create default constraints
link.logger.info("Install: create default Neo4j constraints.")
uided_entities = [
"ProjectModel",
"Project",
"ItemModel",
"Item",
"GroupModel",
"Group",
"DocumentModel",
"Document",
"Version",
"TaskModel",
"Task",
"Status",
"User",
"Config",
"PluginSource",
"PluginSettings",
"Plugin",
"MetaModel",
]
for entity in uided_entities:
sink.internal.make_uid_unique(entity)
# Check if server setting exists
try:
link.config.get()
except LookupError:
pass
else:
raise ValueError("This Bip server already has a config")
if not check_git_repo_validity(content_source):
raise ValueError(f"{content_source} is not a valid Git repository")
if not check_git_repo_validity(bip_source):
raise ValueError(f"{bip_source} is not a valid Git repository")
link.logger.info("Install: get client repository latest version tag.")
models = get_remote_tags(bip_source)
versions = sorted(models.keys(), key=lambda v: packaging.version.parse(v))
latest_tag = versions[-1]
if not version:
version = latest_tag
# Create Config
link.logger.info("Install: create Bip config.")
config = link.config.Config()
config.version = version
config.content_source = content_source
config.bip_source = bip_source
config.permissions = DEFAULT_PERMISSIONS
config.python_package_repository = python_package_repository
if python_package_repository:
config.offline = True
# Default options
config.enable_announcement = True
config.announcement_message = "Welcome to Bip!"
config.announcement_level = INFO
config.closable_announcement = True
config.active_project_timeout = 7 # days
config.save()
# Create internal source plugins
# Register core and circle plugins
link.logger.info("Install: register core and circle plugins.")
with open(internal_plugins_path, mode="rb") as file_content:
internal_plugins = yaml.safe_load(file_content)
for url in {**internal_plugins["core"], **internal_plugins["circle"]}.values():
link.plugin.register(url)
# Enable core plugins
link.logger.info("Install: enable core plugins.")
sources = [s for s in link.plugin.get_sources() if s.level == CORE]
for source in sources:
source.enable(version=source.get_latest_version())
# Create privileges
link.logger.info("Install: create default privileges.")
for slug in DEFAULT_PRIVILEGES:
name = slug.capitalize()
link.user.new_privilege(name, slug)
# Create roles
link.logger.info("Install: create default roles.")
for slug in DEFAULT_ROLES:
name = slug.capitalize()
link.user.new_role(name, slug=slug)
# Create user
link.logger.info("Install: create default user.")
link.user.new_user(
username=username,
password=password,
initials=username[:2].upper(),
first_name=username.capitalize(),
last_name=username.capitalize(),
privilege=link.user.get_privilege(slug="administrator"),
role=link.user.get_role(slug="internal"),
)
# Default project
if populate_default:
link.logger.info("Install: create basic project.")
basic_model_descriptor = Path(builtins_directory) / "models" / "basic.yml"
link.meta.register_from_file(basic_model_descriptor)
basic_model = link.project.new_model(
name="Basic project", path_pattern="{self}", slug="basic"
)
model = link.meta.get("basic")
project = link.project.new("Demo project", model, slug="demo", model=basic_model)
os.environ["_BIP_IGNORE_PERMISSIONS"] = "0"
return config
|