;       Licensed to the Apache Software Foundation (ASF) under one
;       or more contributor license agreements.  See the NOTICE file
;       distributed with this work for additional information
;       regarding copyright ownership.  The ASF licenses this file
;       to you under the Apache License, Version 2.0 (the
;       "License"); you may not use this file except in compliance
;       with the License.  You may obtain a copy of the License at
;
;         http://www.apache.org/licenses/LICENSE-2.0
;
;       Unless required by applicable law or agreed to in writing,
;       software distributed under the License is distributed on an
;       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
;       KIND, either express or implied.  See the License for the
;       specific language governing permissions and limitations
;       under the License.


;
; Allura configuration
;
; Default config values are shown in this file.
; Commented-out configurations are examples that you can use if you want.
;
; Logging configuration is at the end of the file (starting at [loggers])
;
; There are many settings you should change for your site (name, domain, secret keys, etc)
; More settings should be changed for good performance in a production site (no autoreload, no debugging, etc)
;
; You may copy this file to make a new configuration file (e.g. production.ini)
; Or inherit from this file by starting your .ini file like this:
;    [app:main]
;    use = config:development.ini#main
; Then just use the new file name instead of development.ini for any paster commands you run.


[DEFAULT]
; this section is for a few settings that are shared with error handling middleware

; WARNING: *THE LINE BELOW MUST BE CHANGED ON A PRODUCTION ENVIRONMENT*
; Debug mode will enable the interactive debugging tool, allowing ANYONE to
; execute malicious code after an exception is raised.
debug = true
; If you want to receive an email for every unhandled HTTP 500 error, set your email address here:
;email_to = you@yourdomain.com
error_email_from = paste@localhost

; SMTP settings for outgoing mail
smtp_tls = false
smtp_ssl = false
;smtp_user = some_user
;smtp_password = some_password
smtp_timeout = 10
smtp_server = localhost
smtp_port = 8826
; Reply-To and From address often used in email notifications:
forgemail.return_path = noreply@localhost


;
; Settings for `paster serve` command
;
[server:main]
use = egg:Paste#http
host = 0.0.0.0
port = 8080


;
; The main allura settings
;
[app:main]
use = egg:Allura

; Change this to your website's name
site_name = Allura
; Change these to your website's domain
domain = localhost
; Change this to your website's full URL
; Make sure the csp.form_action_urls match to the base_url
base_url = http://localhost:8080

; Change this to configure your image path and redirect link
; for the logo
; NOTE: specify your static.url_base before config this
; Save your picture in images folder
; Example: ../<static_path>/images/<logo_path>
; In default configuration you can place images under
; `Allura/allura/public/nf/images/` and specify file name below
; logo.link = /
; logo.path = sf10a.png
; logo.width = 125 (in px)
; logo.height = 18 (in px)

; Used to uniquify references to static resources, can be a timestamp or any unique value
; This should be updated each time you deploy (or make significant changes, like new tools, new css)
build_key=1276635823

; Used by Turbogears in some cases.  Not particularly relevant for Allura.
cache_dir = %(here)s/data

; Template cache settings
; See http://jinja.pocoo.org/docs/api/#jinja2.Environment
jinja_cache_size = -1
;jinja_bytecode_cache_type = filesystem
;jinja_bytecode_cache_type = memcached
;memcached_host =

; Docs at http://beaker.readthedocs.org/en/latest/configuration.html#session-options
; and http://beaker.readthedocs.org/en/latest/modules/session.html#beaker.session.CookieSession
; and https://github.com/brondsem/beaker-session-jwt#additional-config-options
session.key = allura
session.httponly = true
; set this to true if you use HTTPS
session.secure = false
; CHANGE THIS VALUE FOR YOUR SITE.  Can be a comma-separated list to allow for key rotation
session.jwt_secret_keys = 330c2e698fcadfe46524b57223656404a47a9d80d76f8afb4cae34657247a1ea

;
; Settings for global navigation
;
; Override this to specify your custom navigation links
global_nav = [{"title": "Site Home", "url": "/"}]

; Google Analytics account for tracking
;ga.account = UA-XXXXX-X

; Project registration system.  Only local is available, unless you write a custom one for custom integration.
registration.method = local
theme = allura
; The responsive theme is a work in progress.  See also "disable_entry_points.allura.theme.override = responsive" in this file
;theme = responsive

; These are the sizes of project icons that may be requested.  They will be saved to the database.
; If your theme is going to support other sizes, update this list.
; If you remove sizes, you can clean up space in mongodb with e.g: `db.fs.remove({category:/^icon-84/}, {multi:true})`
; 48 is the historical default size
; user icons use:
;      16 in scm commits, wiki authors, etc
;      32 in nested comments
;      48 in standard comments
; and then 1.5x and 2x versions of all
; 90px for new large project icons, and 1.5x 2x 3x versions
project_icon_sizes = 16 24 32 48 64 72 90 96 128 135 180 270

; To use a custom image for default user profile avatars, specify a full URL here.  Size 96x96 is best, 48x48 ok
;default_avatar_image =

; Disabled by default for security/privacy reasons.  If enabled, md5 of email addresses will be used publicly to try to load gravatar images
;use_gravatar = true

; For LDAP see https://forge-allura.apache.org/docs/getting_started/installation.html#using-ldap
;auth.method = ldap
auth.method = local
; in days, for the "remember me" checkbox on login
auth.remember_for = 365

; Customize login/logout URLs only if you have some custom authentication set up.
auth.login_url = /auth/
auth.logout_url = /auth/logout
; the login fragement URL shows just the form, not a whole page.  It is used within a login overlay on some pages
auth.login_fragment_url = /auth/login_fragment/
auth.post_logout_url = /

auth.min_password_len = 6
auth.max_password_len = 30

; supported values include argon2, scrypt, bcrypt_sha256, pbkdf2_sha512, sha512_crypt https://passlib.readthedocs.io/en/stable/lib/passlib.hash.html#active-hashes
; argon2 and bcrypt need additional packages, see requirements-optional.txt
; https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#password-hashing-algorithms
; https://passlib.readthedocs.io/en/stable/narr/quickstart.html#choosing-a-hash
auth.password.algorithm = scrypt
; list of previously-used algorithms to support when verifying passwords.  Upon successful login, the password will be rehashed with the current algorithm
auth.password.algorithm.old = allura_sha256
; By default passlib's recommended values will be used for rounds & salts, but they may be too low.
; Override them if needed, to match OWASP.org recommendations for example
; auth.password.rounds =
; auth.password.salt_len =

; password expiration options (disabled if neither is set)
;auth.pwdexpire.days = 1
; show a password change form after login, if last pwd change was before this unix timestamp
;auth.pwdexpire.before = 1401949912
; require password change, if last pwd change was before this unix timestamp
; password can only be changed by the logging-in user if they are "trusted" (e.g. known IP)
; otherwise they must change via email
;auth.force_pwd_change_after = 1734978358

; if using LDAP, also run `pip install python-ldap` in your Allura environment

auth.ldap.server = ldaps://localhost/
auth.ldap.suffix = ou=people,dc=localdomain
auth.ldap.admin_dn = cn=admin,dc=localdomain
auth.ldap.admin_password = secret
auth.ldap.schroot_name = scm
auth.ldap.use_schroot = false
; supported values include ldap_bcrypt, ldap_pbkdf2_sha512, ldap_pbkdf2_sha256, ldap_sha512_crypt https://passlib.readthedocs.io/en/stable/lib/passlib.hash.html#standard-ldap-hashes
; bcrypt needs additional packages, see requirements-optional.txt
; Legacy "2b" and "5" and "6" mean ldap_bcrypt, ldap_sha256_crypt and ldap_sha512_crypt respectively
; https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#password-hashing-algorithms
; https://passlib.readthedocs.io/en/stable/narr/quickstart.html#choosing-a-hash
auth.ldap.password.algorithm = ldap_pbkdf2_sha512
; By default passlib's recommended values will be used for rounds & salts, but they may be too low.
; Override them if needed, to match OWASP.org recommendations for example
; auth.ldap.password.rounds = 6000
; auth.ldap.password.salt_len = 16

; "autoregister" allows users to log in to Allura with an existing LDAP account
; If using ldap, with autoregister, you should also set "allow_user_registration"
; to false below.
; Set "autoregister" to false to require user to register in Allura to create
; the LDAP record and Allura record for the user.
auth.ldap.autoregister = true
; see also user_prefs_storage.ldap.* settings later

auth.allow_user_registration = true
auth.allow_user_to_disable_account = true
auth.allow_edit_prefs = true
auth.allow_password_change = true
auth.allow_user_messages_config = true
auth.allow_birth_date = true
auth.allow_non_primary_email_password_reset = true
auth.require_email_addr = true
; List of social network options to use on user account settings
socialnetworks = Facebook, Linkedin, X, Instagram, Mastodon

; Allow uploading ssh key, optionally set ssh preferences url
auth.allow_upload_ssh_key = false
auth.upload_ssh_url = /auth/preferences/

; In seconds
auth.recovery_hash_expiry_period = 600

; Some pages require users to reconfirm their password.  This controls how long that lasts for
auth.reconfirm.seconds = 120

; TOTP stands for Time-based One Time Password
; it is the most common two-factor auth protocol, used with Google Authenticator and other phone apps
auth.multifactor.totp = true
; Length of codes, 6 or 8 is recommended
auth.multifactor.totp.length = 6
; Time window codes are valid, in seconds.  30 is recommended
auth.multifactor.totp.time = 30
; secret key storage location.  "filesystem-googleauth" is another option (compatible with Google Authenticator PAM plugin)
auth.multifactor.totp.service = mongodb
; if using filesystem storage:
auth.multifactor.totp.filesystem.basedir = /var/lib/allura/totp-keys

; recovery code storage location.  "filesystem-googleauth" is another option (compatible with Google Authenticator PAM plugin)
auth.multifactor.recovery_code.service = mongodb
; number of recovery codes to generate per user
auth.multifactor.recovery_code.count = 10
; length of each code.  Must be 8 for compatibility with "filesystem-googleauth" files
auth.multifactor.recovery_code.length = 8

; Optionally enable password hash checks against haveibeenpwned.com during password changes, and disallow any
; that are known to be compromised
auth.hibp_password_check = false

; if auth.hibp_password_check is true and this is also set to true, then a password reset will be forced
; either via the current session if the login ip is "trusted", or via a password reset email if not trusted
auth.hibp_failure_force_pwd_change = true
; if auth.hibp_password_check and auth.hibp_failure_force_pwd_change are true, then this is used to determine if a
; login can be trusted to reset their own ip address.  If set to false, then only the exact same IP can reset a
; HIBP-listed password without going through email
auth.auth.trust_ip_3_octets_match = true

; Enable OAuth2 support
auth.oauth2.enabled = true

; Enable login by email authentication code
auth.email_auth_code.enabled = true

; Reject requests for users who don't have tracked sessions
auth.reject_untracked_sessions = true

user_prefs_storage.method = local
; user_prefs_storage.method = ldap
; If using ldap, you can specify which fields to use for a preference.
; Any fields not specified here will be stored locally in mongo
user_prefs_storage.ldap.fields.display_name = cn

; Limit the number of emails a user can claim.
user_prefs.maximum_claimed_emails = 20

; Disabled tools by default when creating a user profile
; user_prefs.disabled_tools =

; Control the order of sections on the user profile page
user_profile_sections.order = activity, personal-data, skills, social, tools, projects

# append /profile to user profile's urls
user_profile_url_with_profile_path = true

; Control the order of sections on the personal dashboard page
personal_dashboard_sections.order = activity, tickets, merge_requests, projects

; Site admins will be the same as the admins of this project:
site_admin_project = allura
site_admin_project_nbhd = Projects

; Spam filtering service: this can be one or more of: akismet stopforumspam
;spam.method = akismet
; for akismet:
;spam.key =
; for stopforumspam, should be a listed_ip_*_all.txt file
;spam.stopforumspam.ip_addr_file =
;spam.stopforumspam.threshold = 20
; 4 days:
spam.form_post_expiration = 345600

; Phone verification service: Nexmo Verify
; phone.method = nexmo
; phone.api_key =
; phone.api_secret =
; Language to use, if provider supports it.  Values for Nexmo Verify: https://docs.nexmo.com/index.php/verify#localization
; phone.lang = en-us
phone.attempts_limit = 5

; Use phone verification on project registration (false by default)
; project.verify_phone = true

; Webhook timeout in seconds
webhook.timeout = 30
; List of pauses between retries, if hook fails (in seconds)
webhook.retry = 60 120 240
; Limit rate of webhook firing (in seconds, default = 30)
; Option format: webhook.<hook type>.limit,
; all '-' in hook type must be changed to '_'
; e.g. for repo-push webhook:
webhook.repo_push.limit = 30
; Limit max number of hooks that can be created for given project/app
; Option name format: same as above.
; Value format: json dict, where keys are app names (as appears in
; `WebhookSender.triggered_by`) and values are actual limits (default=3), e.g.:
webhook.repo_push.max_hooks = {"git": 3, "hg": 3, "svn": 3}

;; Allow Cross-Origin Resource Sharing (CORS) requests to the REST API
; disabled by default, uncomment the following options to enable:
;cors.enabled = true
;cors.methods = GET HEAD POST PUT DELETE
;cors.headers = Authorization Accept Content-Type
; Allow clients to cache preflight responses for N seconds
; Set to 0 or remove completely to disable
;cors.cache_duration = 86400

; Additional fields for admin project/user search
; Note: whitespace after comma is important!
;search.project.additional_search_fields = private, url, title
;search.user.additional_search_fields = email_addresses

; Additional fields to show in the result of admin project/user search
; Note: whitespace after comma is important!
;search.project.additional_display_fields = private, url, title
;search.user.additional_display_fields = email_addresses

; To make all pages use ssl:   (also set session.secure above)
;force_ssl.pattern = .
; And to permit some URLs to be accessed over http anyway:
;    /_test_vars is used when running `paster shell`
;no_redirect.pattern = ^/nf/\d+/_(ew|static)_/|^/rest/|^/nf/tool_icon_css|^/auth/refresh_repo|^/_test_vars


; Set the locations of some static resources.  ("ew" stands for EasyWidgets library)
;  script_name is the path that is handled by the application
;  url_base is the prefix that references to the static resources should have
; If you use a CDN, put your CDN prefix in the url_base values and icon_base value
ew.script_name = /nf/%(build_key)s/_ew_/
ew.url_base = /nf/%(build_key)s/_ew_/
static.script_name = /nf/%(build_key)s/_static_/
static.url_base = /nf/%(build_key)s/_static_/
; static.icon_base = https://some.cdn/path

; Expires header for "static" resources served through allura (e.g. icons, attachments, /nf/tool_icon_css)
; 2 weeks:
files_expires_header_secs = 1209600

; EasyWidgets settings
; This CORS header is necessary if serving webfonts via a different domain
ew.extra_headers = [ ('Access-Control-Allow-Origin', '*') ]
; In production, comment this out and it will default to 1 year.  Update build_key whenever you deploy new code, instead.
ew.cache_header_seconds = 0

; If your environment (e.g. behind a server-side proxy) needs to look at an http header to get the actual remote addr
;ip_address_header = X-Forwarded-For

; browser permissions policy header
; Deprecated but still supported by older and new browsers
features_policies = microphone 'none'; geolocation 'none'; camera 'none'; payment 'none'; document-domain 'none'; display 'none'; autoplay 'none'
; Replacement of Feature Policy
permissions_policies = microphone=(), geolocation=(), camera=(), payment=(), document-domain=(), display-capture=(), autoplay=()
; Referrer Policy.  Generally not needed since modern browsers default to strict-origin-when-cross-origin
;referrer_policy = same-origin
; COOP header
cross_origin_opener_policy = same-origin
; CORP header
;cross_origin_resource_policy = same-origin
; COEP header
;cross_origin_embedder_policy = require-corp

; SCM settings for local development
; If you set up services for Git, SVN, or Hg that run on https://, ssh://, git:// etc, you can show corresponding
; checkout commands by adding new entries to these lists.   Each one needs a name/key/title as shown below.
; The "key" must correspond to a scm.host.KEY.git or scm.host.KEY.svn setting further below.
scm.clonechoices.git = [{"name": "File", "key": "file", "title": "Filesystem"}]
scm.clonechoices.svn = [{"name": "File", "key": "file", "title": "Filesystem"}]
scm.clonechoices.hg = [{"name": "File", "key": "file", "title": "Filesystem"}]
;scm.clonechoices.git = [{"name": "RW", "key": "rw", "title": "Read/Write"}, {"name": "RO", "key": "ro", "title": "Read Only"}, {"name": "HTTPS", "key": "https", "title": "HTTPS"}]
;scm.clonechoices_anon.git = [{"name": "RO", "key": "ro", "title": "Read Only"}, {"name": "HTTPS", "key": "https_anon", "title": "HTTPS"}]
;scm.clonechoices.svn = [{"name": "RW", "key": "rw", "title": "Read/Write"}, {"name": "RO", "key": "ro", "title": "Read Only"}, {"name": "HTTPS", "key": "https", "title": "HTTPS"}]
;scm.clonechoices_anon.svn = [{"name": "RO", "key": "ro", "title": "Read Only"}, {"name": "HTTPS", "key": "https_anon", "title": "HTTPS"}]
;scm.clonechoices.hg = [{"name": "RW", "key": "rw", "title": "Read/Write"}, {"name": "RO", "key": "ro", "title": "Read Only"}, {"name": "HTTPS", "key": "https", "title": "HTTPS"}]
;scm.clonechoices_anon.hg = [{"name": "RO", "key": "ro", "title": "Read Only"}, {"name": "HTTPS", "key": "https_anon", "title": "HTTPS"}]

scm.host.file.git = /srv/git$path
; remote access varies by configuration.  read/write configs can be set also, like:
;scm.host.rw.git = ssh://$username@localhost:2222/srv/git$path
scm.host.file.hg = /srv/hg$path
scm.host.file.svn = file:///srv/svn$path/

; SCM settings for chroot + ldap configuration.  See Allura/docs/getting_started/scm_host_ssh.rst
;scm.host.ro.git = git://git.localhost$path
;scm.host.rw.git = ssh://$username@localhost:8022/scm-repo$path
;scm.host.ro.hg = http://hg.localhost$path
;scm.host.rw.hg = ssh://$username@localhost:8022/scm-repo$path
;scm.host.ro.svn = http://svn.localhost$path/
;scm.host.rw.svn = svn+ssh://localhost:8022/scm-repo$path/

; SCM settings for https See Allura/docs/getting_started/scm_host.rst
;scm.host.https.git = https://$username@localhost:8022/scm-repo$path
;scm.host.https_anon.git = https://localhost:8022/scm-repo$path
;scm.host.https.hg = https://$username@localhost:8022/scm-repo$path
;scm.host.https_anon.hg = https://localhost:8022/scm-repo$path
;scm.host.https.svn = https://localhost:8022/scm-repo$path/
;scm.host.https_anon.svn = https://localhost:8022/scm-repo$path/

scm.clone.git = git clone $source_url $dest_path
scm.clone.hg = hg clone $source_url $dest_path
scm.clone.ro.svn = svn checkout $source_url $dest_path
scm.clone.https_anon.svn = svn checkout $source_url $dest_path
scm.clone.svn = svn checkout --username=$username $source_url $dest_path

; Only needed if different than "base_url" (e.g. if "base_url" isn't reachable from SCM hosts and you need an internal hostname)
;scm.repos.refresh_base_url = http://localhost:8080

scm.repos.root = /srv
scm.repos.tarball.enable = false
scm.repos.tarball.root = /usr/share/nginx/www/
; scm.repos.tarball.tmpdir can be set to hold code checkouts before building the zip file.  Defaults to scm.repos.tarball.root
scm.repos.tarball.url_prefix = http://localhost/
scm.repos.tarball.zip_binary = /usr/bin/zip

; SCM imports (currently just SVN) will retry if it fails
; You can control the number of tries and delay between tries here:
scm.import.retry_count = 3
scm.import.retry_sleep_secs = 5

; When getting a list of valid references (branches/tags) from a repo, you can cache
; the results in mongo based on a threshold. Set `repo_refs_cache_threshold` (in seconds) and the resulting
; lists will be cached and served from cache on subsequent requests until reset by `repo_refresh`.
; Set to 0 to cache all references. Remove entirely to cache nothing.
repo_refs_cache_threshold = .01

; Enabling copy detection will display copies and renames in the commit views
; at the expense of much longer response times. SVN tracks copies by default.
scm.commit.git.detect_copies = true
scm.commit.hg.detect_copies = false

; One-click merge is enabled by default, but can be turned off on for each type of repo
scm.merge.git.disabled = false
scm.merge.hg.disabled = false

; Merge request viewing will fetch git info into existing git repositories. On
; deployments where writes in existing git repos are unwanted, clone to tmp dir
; can be used.
;scm.merge_list.git.use_tmp_dir = true


; Default limit for number of commits to show in a repo log page
scm.view.log.limit = 25

; Default limit for number of commits to show in Commit Browser page
;   If you set this low, you will have more breaks in the graph and more likelihood for incorrect line visualizations
;   Details at https://forge-allura.apache.org/p/allura/tickets/5496/#1b4a
scm.view.commit_browser.limit = 500

; Default limit for when to stop doing syntax highlighting (can take a lot of CPU for large files)
scm.view.max_syntax_highlight_bytes = 500000

; Max size for viewing a file from a repo, can take a lot of template processing (even with syntax highlighting disabled)
scm.view.max_file_bytes = 5000000

; Default limit for when to stop performing a diff (both side-by-side and default)
scm.view.max_diff_bytes = 2000000

; Max size for download a raw file from a repo
scm.download.max_file_bytes = 30000000

; Commit Status Support
scm.commit_statuses = false

; If using the ForgeHg separate extension, scm.hg.hgconfig.SECTION.KEY = VALUE can be used to set options passed
; through to Mercurial itself.  For example to control the .hg/requires storage format to older versions still:
;scm.hg.hgconfig.format.use-share-safe = false

; bulk_export_enabled = true
; If you keep bulk_export_enabled, you should set up your server to securely share bulk_export_path with users somehow
bulk_export_path = /tmp/bulk_export/{nbhd}/{project}
; bulk_export_tmpdir can be set to hold files before building the zip file.  Defaults to use bulk_export_path
bulk_export_filename = {project}-backup-{date:%%Y-%%m-%%d-%%H%%M%%S}.zip
; You will need to specify site-specific instructions here for accessing the exported files.
bulk_export_download_instructions = Sample instructions for {project}

importer_upload_path = /tmp/importer_upload/{nbhd}/{project}

; If you want to allow importing resources from internally resolving hostnames, enable this:
;urlopen_allow_internal_hostnames = false

; To disable any plugin, tool, importer, etc from being available, you can use the disable_entry_points config option.
; Specify the keys and values as they are declared in the tool's "setup.py" file.
; Examples: github-tracker, github-wiki, github-repo
disable_entry_points.allura.importers = trac-tickets
; Examples: github, trac
disable_entry_points.allura.project_importers = trac
disable_entry_points.allura.theme.override = responsive

; Importers specifically, can be left enabled but not linked to.  You have to know the URL to use it.  Example:
;hidden_importers = tt-tickets

; GitHub importer keys.  For github ticket import, it is best to set
; up an app at https://github.com/settings/developers  Use the root URL
; of your Allura instance for both URLs, and enter client values here:
;github_importer.client_id =
;github_importer.client_secret =

; If your site has docs about specific importers, you can add them here and
; they'll appear on the import forms
;doc.url.importers.GitHub = http://...

; If you have specific API documentation for your site, you can change this
doc.url.api = https://forge-allura.apache.org/docs/getting_started/administration.html#public-api

; List of oauth API keys permitted to use special forum import API
; (should be converted to newer importer system)
;oauth.can_import_forum = api-key-1234, fa832r0fdsafd, f23f80sdf32fd


; space-separated list of tool names that are valid options
; for project admins to set for their 'support_page' field
; this field is not used by default in Allura, so this option
; is disabled by default
;support_tool_choices = wiki tickets discussion

; Control how /categories URL can be accessed to edit trove categories (used in project categories and user skills)
; Default: everyone
trovecategories.enableediting = true
; Nobody:
;trovecategories.enableediting = false
; Site admins only:
;trovecategories.enableediting = admin

trovecategories.admin.recommended.license = 188=MIT,401=Apache,679=GPL,680=LGPL,670=AGPL
trovecategories.admin.recommended.os = 655=Windows,309=Mac OSX,201=Linux,728=Android,780=iOS
trovecategories.admin.help.license = For help choosing a license, visit <a href="http://choosealicense.com/">http://choosealicense.com/</a>

; ActivityStream
activitystream.master = mongodb://127.0.0.1:27017
activitystream.database = activitystream
activitystream.activity_collection = activities
activitystream.node_collection = nodes
activitystream.timeline_collection = timelines
activitystream.enabled = true
activitystream.recording.enabled = true
activitystream.ming.auto_ensure_indexes = false

; Ming setup
; These don't necessarily have to be separate databases, they could
; be all in the same database if desired
ming.main.uri = mongodb://127.0.0.1:27017/allura
ming.main.auto_ensure_indexes = False
; the .key values must be a base64-encoded 96-byte key for encrypted fields in mongo
; generate one with: python -c 'import base64, secrets; print(base64.b64encode(secrets.token_bytes(96)).decode())'
; changing it will make existing encrypted data inaccessible until extra steps are taken  https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/manage-keys/
ming.main.encryption.kms_providers.local.key = REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME//////
ming.main.encryption.key_vault_namespace = encryption.dataKeyVault
ming.main.encryption.provider_options.local.key_alt_names = ["datakey1"]
ming.project.uri = mongodb://127.0.0.1:27017/project-data
ming.project.auto_ensure_indexes = False
ming.project.encryption.kms_providers.local.key = REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME//////
ming.project.encryption.key_vault_namespace = encryption.dataKeyVault
ming.project.encryption.provider_options.local.key_alt_names = ["datakey1"]
ming.task.uri = mongodb://127.0.0.1:27017/task
ming.task.auto_ensure_indexes = False
ming.task.encryption.kms_providers.local.key = REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME/THIS/IS/INSECURE/REPLACE/ME//////
ming.task.encryption.key_vault_namespace = encryption.dataKeyVault
ming.task.encryption.provider_options.local.key_alt_names = ["datakey1"]

; A float from 0-1 representing a % of requests to measure timing on.
; Sampled requests will have timing logged to stats.log (can change file in [handler_timermiddleware] logging section)
stats.sample_rate = 1

; Taskd setup
; number of seconds to sleep between checking for new tasks
monq.poll_interval=2

; SOLR setup.  This can be a comma-separated list, to index into multiple locations
solr.server = http://localhost:8983/solr/allura
# auth for solr, if needed.  These can be a list too, to match solr.server
;solr.user =
;solr.pass =
; Alternate server to use just for querying.  Single server, not a list.
;solr.query_server =
;solr.query_user =
;solr.query_pass =
; Shorter timeout for search queries (longer timeout for saving to solr)
solr.short_timeout = 10
; commit on every add/delete?
solr.commit = false
; commit add operations within N ms
solr.commitWithin = 10000
; Use improved data types for labels and custom fields?
; New Allura deployments should leave this set to true. Existing deployments
; should set to false until existing data has been reindexed. Reindexing will
; convert existing label and custom field data to more appropriate solr types.
solr.use_new_types = true

; Incoming email settings.  Used when you run: paster smtp_server development.ini
; address to listen to
forgemail.host = 0.0.0.0
forgemail.port = 8825
; domain suffix for your mail, change this.  You also need to route *.*.*.forgemail.domain to the above host/port via
; your mail and DNS configuration
forgemail.domain = .in.localhost

; Specify the number of projects allowed to be created by a user depending on the age of their user account.
; Keys are number of seconds, values are max number allowed until that time period is reached.
; NOTE: this includes the default user-profile project, so you probably want to set any limits higher by 1.
; This example allows for up to 2 total projects if the account is less than an hour old
; and 6 total projects if the account is less than a day old.  No limits after that.
;project.rate_limits = {"3600": 2, "86400": 6}

; Specify the number of artifacts allowed to be created in a project, depending on the age of the project
; Currently supports only tickets and wiki page creation rate limiting.
; Keys are number of seconds, values are max number allowed until that time period is reached
;forgewiki.rate_limits = {"3600": 100, "172800": 10000}
;forgetracker.rate_limits = {"3600": 100, "172800": 10000}
;forgeblog.rate_limits = {"3600": 100, "172800": 10000}

; Number of different wiki pages, tickets, etc that a user can create or edit, per time period, across all projects
; Keys are number of seconds, values are max number allowed until that time period is reached
; NOTE: wiki pages include the default "Home" page created for the user-project and any other projects created by the user
; NOTE: allura.rate_limits* cover posts to threads across all tools.
;forgewiki.rate_limits_per_user =    {"60": 3, "120": 3, "900": 5, "1800": 7, "3600": 10, "7200": 15, "86400": 20, "604800": 50, "2592000": 200}
;forgetracker.rate_limits_per_user = {"60": 1, "120": 3, "900": 5, "1800": 7, "3600": 10, "7200": 15, "86400": 20, "604800": 50, "2592000": 200}
;forgeblog.rate_limits_per_user =    {"60": 1, "120": 3, "900": 5, "1800": 7, "3600": 10, "7200": 15, "86400": 20, "604800": 50, "2592000": 200}
;allura.rate_limits_per_user =        {"60": 1, "120": 3, "900": 5, "1800": 7, "3600": 10, "7200": 15, "86400": 20, "604800": 50, "2592000": 200}
;forgediscussion.rate_limits_per_user =    {"3600": 1, "86400": 2, "172800": 4, "604800": 10, "2592000": 25}


; set this to "false" if you are deploying to production and want performance improvements
auto_reload_templates = true

; How frequently users can send messages, in seconds
user_message.time_interval = 3600
; Max number of messages that can be sent within that time interval.
user_message.max_messages = 20

; Default number of times to show a sitewide notification
; See https://forge-allura.apache.org/docs/getting_started/administration.html#site-notifications
site_notification.impressions = 0

; When rendering discussion post Markdown to html, if the render takes longer
; than `markdown_cache_threshold` (in seconds), the resulting html will be
; cached and served from cache on subsequent requests. Set to 0 to cache all
; posts. Remove entirely to cache nothing.
markdown_cache_threshold = .1
; markdown text longer than max length will not be converted to html
markdown_render_max_length = 200000
; higher limit for renders that can be cached (defaults to 2x markdown_render_max_length)
;markdown_render_max_length.cached =
; Don't add rel=nofollow to these domains when generating links from Markdown content
;nofollow_exempt_domains =

; when sanitizing HTML generated from markdown and other sources, allow these classes & ids, in addition to the built-in defaults:
;safe_html.classes =
;safe_html.class_prefixes =
;safe_html.id_prefixes =

; By default project admins can soft-delete their projects.
; A soft-deleted project will still be in the database and visible to admins, but not to others.
allow_project_delete = true
allow_project_undelete = true

; Advanced settings for controlling "Last Commit Doc" algorithm used when visiting any repo browse page
lcd_thread_chunk_size = 10
lcd_timeout = 60

; Many URLs support a param like limit=50  This setting controls the max value allowed for that parameter.
; Allowing exceedingly high values may have a performance impact
limit_param_max = 500

; Hide private info (email addresses) in places like commit messages, since they cannot be edited.
hide_private_info = true


;
; Settings for the Blog tool
;
; Enable or disable external RSS feed importing in ForgeBlog tool.
; Default is "false". This feature requires GPL library "html2text". Install it with following command:
;   pip install -e git://github.com/brondsem/html2text.git#egg=html2text
; You will also need to run `paster pull-rss-feeds development.ini` in a cron job to fetch them.
forgeblog.exfeed = false

;
; Settings for the Chat tool
;
forgechat.host = irc.freenode.net
forgechat.port = 6667
ircbot.nick = allurabot

;
; Settings for ShortUrl tool
;
; Override this if you set up an additional shortening mechanism (e.g. custom short domain)
short_url.url_pattern = {base_url}/{nbhd}/{project}/{mount_point}/{short_name}


;
; Settings for UserStats tool
;
userstats.count_lines_of_code = true

;
; Settings for Ticket tracker tool
;
; to avoid race condition, this needs to be a bit longer than the SOLR commitWithin delay.  Values are in minutes
;forgetracker.bin_invalidate_delay = 5
; Minutes to cache saved search "bins" numbers.  0 will disable entirely, so caches are permanent
;forgetracker.bin_cache_expire = 60

;
; CSP Headers
;

; csp.report_uri = https://example.com/r/d/csp/reportOnly
; csp.report_uri_enforce = https://example.com/r/d/csp/enforce


; to enable enforce mode on frame-src
;csp.frame_sources_enforce = true

; frame-src list of valid sources for loading frames
csp.frame_sources = 'self' www.youtube-nocookie.com

; csp.fenced_frame_sources_enforce = true
;csp.fenced_frame_sources = https:

; to enable enforce mode on form-action
; csp.form_actions_enforce = true

; form-action valid sources that can be used as an HTML <form> action
csp.form_action_urls = http://localhost:8080

; to enable enforce mode on script-src
; csp.script_src_enforce = true

csp.script_src = 'self' www.google-analytics.com
csp.script_src.extras = 'unsafe-inline' 'unsafe-eval'

; to enable enforce mode on script-src-attr
;csp.script_src_attr_enforce = true
csp.script_src_attr = 'none'
;
; Settings for comment reactions
;

; If you want to customize emoji list for reactions, uncomment following ini setting and add emoji codes
; as you wish. Supported emoji codes can be found at https://pypi.org/project/emoji/
; reactions.emoji_list = :+1:, :-1:, :smile:, :tada:, :confused:, :heart:


;
; Optional settings for profiling with https://pypi.python.org/pypi/keas.profile
;
[filter-app:profile]
use=egg:keas.profile#profiler
next=main


;
; setup for the taskd background daemon request controller
;
[app:task]
use = main
; TurboGears will use controllers/task.py as root controller
override_root = task



;
; Logging configuration
;
; Add additional loggers, handlers, formatters here
; Uses python's logging config file format
; https://docs.python.org/2/library/logging.config.html#configuration-file-format
;
[loggers]
keys = root, allura, sqlalchemy, paste, ew, taskdstatus, timermiddleware, tmw_details

[handlers]
keys = console, taskdstatus, timermiddleware

[formatters]
keys = generic, timermiddleware

; If you create additional loggers, add them as a key to [loggers]
[logger_root]
level = INFO
handlers = console

[logger_allura]
level = INFO
handlers =
qualname = allura

[logger_sqlalchemy]
level = INFO
handlers =
qualname = sqlalchemy.engine
; "level = INFO" logs SQL queries.
; "level = DEBUG" logs SQL queries and results.
; "level = WARN" logs neither.  (Recommended for production systems.)

[logger_paste]
level = INFO
qualname = paste
handlers =

[logger_ew]
; easy widgets
level = WARN
qualname = ew
handlers =

[logger_tmw_details]
; DEBUG will include every instrumented call in our logging
level = INFO
qualname = timermiddleware
handlers =

[logger_taskdstatus]
level = INFO
qualname = taskdstatus
handlers = taskdstatus

[logger_timermiddleware]
level = INFO
handlers = timermiddleware
qualname = stats
propagate = 0

; If you create additional handlers, add them as a key to [handlers]
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[handler_taskdstatus]
class = handlers.WatchedFileHandler
args = ('taskd_status.log', 'a')
level = NOTSET
formatter = generic

[handler_timermiddleware]
class = handlers.WatchedFileHandler
; if you run 'gunicorn' in allura/Allura/ then that's where this file will be
; you may want to hard-code a specific directory here.
args = ('stats.log', 'a')
level = NOTSET
formatter = timermiddleware

; If you create additional formatters, add them as a key to [formatters]
[formatter_generic]
format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

[formatter_timermiddleware]
format = {"time": "%(asctime)s,%(msecs)03d", "level": "%(levelname)-5.5s", "name": "%(name)s", "message": %(message)s}
datefmt = %Y-%m-%d %H:%M:%S
