Difference between revisions of "Developer doc"
(Added short description of configuration API) |
(Merged Security page) |
||
Line 1: | Line 1: | ||
A few things to know about how the code works. Far from complete. | A few things to know about how the code works. Far from complete. | ||
− | = Internationalisation = | + | == Internationalisation == |
i18n in FusionForge is done via the standard Gettext library, with no particular quirks in FusionForge. This makes it a bit unwieldy to use custom/local translations or strings. [[User:Lolando|Lolando]] has a local branch with code to generate a local translation package that can override the official ones. Need to finish it and commit it to trunk. | i18n in FusionForge is done via the standard Gettext library, with no particular quirks in FusionForge. This makes it a bit unwieldy to use custom/local translations or strings. [[User:Lolando|Lolando]] has a local branch with code to generate a local translation package that can override the official ones. Need to finish it and commit it to trunk. | ||
− | = Database access = | + | == Database access == |
Database queries go through the db_query_params() method (db_query() is being deprecated to help get rid of a whole class of potential SQL injection bugs). This is a wrapper around the PostgreSQL database access methods, which passes the variable parts of a query as separate parameters, removing the need for careful escaping and unescaping. To get the full benefits of that, it is important that the query itself be immutable, and all variable parts need to go into separate parameters. For instance, a query counting the groups with a given word in their name or their description should read: | Database queries go through the db_query_params() method (db_query() is being deprecated to help get rid of a whole class of potential SQL injection bugs). This is a wrapper around the PostgreSQL database access methods, which passes the variable parts of a query as separate parameters, removing the need for careful escaping and unescaping. To get the full benefits of that, it is important that the query itself be immutable, and all variable parts need to go into separate parameters. For instance, a query counting the groups with a given word in their name or their description should read: | ||
Line 20: | Line 20: | ||
array (db_int_array_to_any_clause($values))) ; | array (db_int_array_to_any_clause($values))) ; | ||
− | = URLs and links = | + | == URLs and links == |
As described in [[FusionForge/Suggestions/URL relocation]], URLs to pages in the forges should always be generated by the util_make_url() function. This allows to keep the URL scheme in a single point, so that individual pages don't have to know or care whether the forge runs in its own virtualhost, or on SSL, or in a subset of the URL space within a vhost, and so on. | As described in [[FusionForge/Suggestions/URL relocation]], URLs to pages in the forges should always be generated by the util_make_url() function. This allows to keep the URL scheme in a single point, so that individual pages don't have to know or care whether the forge runs in its own virtualhost, or on SSL, or in a subset of the URL space within a vhost, and so on. | ||
Line 26: | Line 26: | ||
util_make_link() can be used to generate links rather than just URLs, with extra parameters to add attributes to the <nowiki><a ...></nowiki> element in the generated HTML. A use case is to add a class for CSS styling. | util_make_link() can be used to generate links rather than just URLs, with extra parameters to add attributes to the <nowiki><a ...></nowiki> element in the generated HTML. A use case is to add a class for CSS styling. | ||
− | = Authentication/Permissions = | + | == Authentication/Permissions == |
The authentication uses an MD5 password stored in the database by default, but a hook allows to override that with a plugin. | The authentication uses an MD5 password stored in the database by default, but a hook allows to override that with a plugin. | ||
Line 36: | Line 36: | ||
There is a specific admin role given to the project admin, each project creator is by default project admin, he can manage roles for other users, give or remove admin role, design new roles, add/remove users of the group he is admin. | There is a specific admin role given to the project admin, each project creator is by default project admin, he can manage roles for other users, give or remove admin role, design new roles, add/remove users of the group he is admin. | ||
− | = Configuration = | + | == System security == |
+ | |||
+ | This describes the concepts of FusionForge that shall ensure security of the underlying server. It describes | ||
+ | * what the different components of FusionForge should do or not do, | ||
+ | * what exceptions currently exist, | ||
+ | * and what technical measures are taken to ensure this. | ||
+ | |||
+ | === Processes === | ||
+ | ==== Web server ==== | ||
+ | * should not write to the filesystem directly | ||
+ | * if any write access is required, only write to <code>/var/lib/gforge</code> | ||
+ | * should only read and write the database | ||
+ | * Technical measures: | ||
+ | ** web server runs as user <code>www-data</code> | ||
+ | ** user <code>www-data</code> has usually no write access anywhere | ||
+ | ** only where required, write access can be granted (explicitly?) by the admin | ||
+ | * Exceptions: ftp upload, some plugins | ||
+ | |||
+ | ==== Cronjobs ==== | ||
+ | * should write only in <code>/var/lib/gforge</code> | ||
+ | * Technical measures: | ||
+ | ** cronjob runs as user <code>root</code> | ||
+ | ** most jobs restrict permissions to user <code>gforge</code> | ||
+ | ** user <code>gforge</code> can only write to <code>/var/lib/gforge</code> | ||
+ | * Exceptions: | ||
+ | ** pluginman: | ||
+ | *** creates links in <code>/opt/gforge/www/plugins</code> | ||
+ | *** creates links in <code>/etc/gforge/plugins</code> | ||
+ | ** configman: | ||
+ | *** modifies <code>/etc/gforge/local.inc</code> | ||
+ | |||
+ | === Directories === | ||
+ | ==== <code>/opt/gforge</code> ==== | ||
+ | * contains source code of FF | ||
+ | * server admin should not have to modify anything here (to simplify updates) | ||
+ | * modified only by FF developers | ||
+ | * Exceptions: | ||
+ | ** Links in <code>/opt/gforge/www/plugins</code> are set up by pluginman | ||
+ | ** Some plugins require modifications | ||
+ | |||
+ | ==== <code>/etc/gforge</code> ==== | ||
+ | * contains configuration files of FF | ||
+ | * modified by server admin | ||
+ | * FF code should not modify anything here (to simplify updates) | ||
+ | * Exceptions: | ||
+ | ** pluginman creates links here | ||
+ | ** configman modifies <code>local.inc</code> | ||
+ | ** setup autogenerates files here (e.g. <code>httpd.conf</code>) | ||
+ | * Technical measures: no write permissions for <code>www-data</code> or <code>gforge</code> | ||
+ | |||
+ | ==== <code>/var/lib/gforge</code> ==== | ||
+ | * contains files required by the current state of FF | ||
+ | * modifed by cronjobs | ||
+ | * Exceptions: | ||
+ | ** ftp upload | ||
+ | ** mediawiki upload | ||
+ | ** Other plugins? | ||
+ | * Technical measures: | ||
+ | ** write permissions for user <code>gforge</code> | ||
+ | ** no write permissions for user <code>www-data</code> | ||
+ | |||
+ | === Potential problems === | ||
+ | * Root cronjob is potentially dangerous | ||
+ | ** Possible solution: run cronjob as user <code>gforge</code>, use <code>sudo</code> when root access is required | ||
+ | ** More control over root jobs by admin | ||
+ | * Configman writes central config file that contains paths etc.! | ||
+ | |||
+ | == Configuration == | ||
Configuration was previously accessed through a mess of global variables. This is being deprecated in favour of a (hopefully) clean API: | Configuration was previously accessed through a mess of global variables. This is being deprecated in favour of a (hopefully) clean API: |
Revision as of 14:35, 26 March 2010
A few things to know about how the code works. Far from complete.
Contents
Internationalisation
i18n in FusionForge is done via the standard Gettext library, with no particular quirks in FusionForge. This makes it a bit unwieldy to use custom/local translations or strings. Lolando has a local branch with code to generate a local translation package that can override the official ones. Need to finish it and commit it to trunk.
Database access
Database queries go through the db_query_params() method (db_query() is being deprecated to help get rid of a whole class of potential SQL injection bugs). This is a wrapper around the PostgreSQL database access methods, which passes the variable parts of a query as separate parameters, removing the need for careful escaping and unescaping. To get the full benefits of that, it is important that the query itself be immutable, and all variable parts need to go into separate parameters. For instance, a query counting the groups with a given word in their name or their description should read:
$res = db_query_params ('SELECT count(*) FROM groups WHERE group_name LIKE $1 OR description LIKE $2', array ($word, $word)) ;
Thus, even if $word comes from a malicious user query, it can't do any harm in the database.
Note that this prevents usage of WHERE foo IN (...) constructs if the number of elements in the set is not constant. Fortunately, we can use an alternative way, with the WHERE foo = ANY($1), with the values built with the db_string_array_to_any_clause() or db_int_array_to_any_clause() methods:
$values = array (1, 2, 5, 8) ; $res = db_query_params ('SELECT foo FROM bar WHERE col = ANY($1)', array (db_int_array_to_any_clause($values))) ;
URLs and links
As described in FusionForge/Suggestions/URL relocation, URLs to pages in the forges should always be generated by the util_make_url() function. This allows to keep the URL scheme in a single point, so that individual pages don't have to know or care whether the forge runs in its own virtualhost, or on SSL, or in a subset of the URL space within a vhost, and so on.
util_make_link() can be used to generate links rather than just URLs, with extra parameters to add attributes to the <a ...> element in the generated HTML. A use case is to add a class for CSS styling.
Authentication/Permissions
The authentication uses an MD5 password stored in the database by default, but a hook allows to override that with a plugin.
The permission model is RBAC, role-based access control. 'Users' are members of any number of 'groups'. Each membership of a user in a group has a 'role', possibly shared by several users in a group. Each role is specific to a group (no cross-group sharing currently), and it has a set of 'role settings' which are permission bits for the members of the role on the tools of the group.
There is a global admin "role" given to all users member of the admin project, there is no premission control on this user that can add/remove all permissions he wants
There is a specific admin role given to the project admin, each project creator is by default project admin, he can manage roles for other users, give or remove admin role, design new roles, add/remove users of the group he is admin.
System security
This describes the concepts of FusionForge that shall ensure security of the underlying server. It describes
- what the different components of FusionForge should do or not do,
- what exceptions currently exist,
- and what technical measures are taken to ensure this.
Processes
Web server
- should not write to the filesystem directly
- if any write access is required, only write to
/var/lib/gforge
- should only read and write the database
- Technical measures:
- web server runs as user
www-data
- user
www-data
has usually no write access anywhere - only where required, write access can be granted (explicitly?) by the admin
- web server runs as user
- Exceptions: ftp upload, some plugins
Cronjobs
- should write only in
/var/lib/gforge
- Technical measures:
- cronjob runs as user
root
- most jobs restrict permissions to user
gforge
- user
gforge
can only write to/var/lib/gforge
- cronjob runs as user
- Exceptions:
- pluginman:
- creates links in
/opt/gforge/www/plugins
- creates links in
/etc/gforge/plugins
- creates links in
- configman:
- modifies
/etc/gforge/local.inc
- modifies
- pluginman:
Directories
/opt/gforge
- contains source code of FF
- server admin should not have to modify anything here (to simplify updates)
- modified only by FF developers
- Exceptions:
- Links in
/opt/gforge/www/plugins
are set up by pluginman - Some plugins require modifications
- Links in
/etc/gforge
- contains configuration files of FF
- modified by server admin
- FF code should not modify anything here (to simplify updates)
- Exceptions:
- pluginman creates links here
- configman modifies
local.inc
- setup autogenerates files here (e.g.
httpd.conf
)
- Technical measures: no write permissions for
www-data
orgforge
/var/lib/gforge
- contains files required by the current state of FF
- modifed by cronjobs
- Exceptions:
- ftp upload
- mediawiki upload
- Other plugins?
- Technical measures:
- write permissions for user
gforge
- no write permissions for user
www-data
- write permissions for user
Potential problems
- Root cronjob is potentially dangerous
- Possible solution: run cronjob as user
gforge
, usesudo
when root access is required - More control over root jobs by admin
- Possible solution: run cronjob as user
- Configman writes central config file that contains paths etc.!
Configuration
Configuration was previously accessed through a mess of global variables. This is being deprecated in favour of a (hopefully) clean API:
- forge_get_config(name [, section]): get value of variable "name" in section "section" (defaults to "core");
- forge_define_config_item(name, section, default): define a new configuration item with given name/section and default value;
- forge_read_config_file(file): read a *.ini file and inject its contents into the configuration.
See also Development environment.