CMS Integration

mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Sun, 2004-09-05 19:42

This topic is primarily for valiant, bharat and myself to discuss core G2 changes to better support CMS integrations.
Feel free to join in the discussion, especially if you see anything we're doing that may not work well with the particular CMS you'd like to use with G2.
This topic has a lot of info on valiant's efforts at integrating with Xaraya.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Sun, 2004-09-05 20:05

valiant, I've started the core changes with main.php. With the changes I just committed to cvs you should be able to do this from your Xaraya module:

define('G2_EMBED_URI', 'index.php?module=gallery2');
require( {path} . 'main.php' );

After this code executes first check the value of $isDone. If true then G2 has already printed the output (for a redirect or an immediate view) and you should instruct the CMS not to send any additional output. If false then the variables $headHtml and $bodyHtml have the G2 content. Nothing to separate out header elements or links/menu commands yet, but this is a start.
The code also sets the _baseFile value for the UrlGenerator to the specified value. I haven't yet updated GalleryUrlGenerator to work with a baseFile that has a ? in it..

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Sun, 2004-09-05 21:56

i like it!
only one remark:
- add G2 / G2mod as a prefix to all variables: isDone -> G2isDone, etc.

@User management:
We need to decide whether we go for the "loose integration" or for the "tight integration". Parallel database user / group / map tables or make G2 use the tables of the CMS.
In short: If we make G2 use the tables of the CMS, we'll have to translate all db queries and replace some UserGroupHelper functions, that's what I've done. But we still need to find a way to do it the right way, perhaps with events etc.
The loose intergration method needs less changes, just the authentication in init.php will need an event to check if the user is logged in and a few other things.
But if we go for this parallel user management method, we'll have to deal with redundant data (user table in CMS / user table in G2) which can get out of sync.
So we would need to create events for "user changes user data" and perhaps for 1, 2 other things.
The problem is that the CMS needs these events too, but not all CMS support events.
- Xaraya has a hook (& an event) system and the devs would create all needed hooks if they not already exist as they would ease the integration of all 3rd party applications.
- typo3 has hooks too, but the current design how user data is changed is flawed (says e. baschny). i'm discussing it in the typo3 dev newsgroup
- mambo: don't know much about mambo. just started a thread in their forum, but didn't get an answer yet.
- tikipro (spiderr) should support something like function hooks for the auth/user system.
- postnuke: not yet investigated.
- phpnuke: AFAIK phpnuke doesn't even have a true group system. you're automatically a group member, if you have enough (each group has a threshold point number) points (that you earned by posting news, etc.) . So phpnuke would rely on G2 group management.

I'd prefer the loose integration. Less changes needed and it would be a show case how to integrate 3rd party application with ease. And we don't have to export all users from CMS to G2 when someone decides to use G2 standalone again.
I kinda think I could convince most CMS devs that these user events/hooks are something they need.
But without postnuke/typo3/mambo supporting this functionality, we'll have to implement it the way I hacked it: sql query translation, etc.

So, I keep getting in touch with CMS devs and trying to convince them.
What do you think? Should I forget this "loose integration" idea as it actually is no problem for us to do it with query translation etc.?

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Mon, 2004-09-06 05:41

I've committed changes to GalleryUrlGenerator to work if baseFile has a ? in it.
I just used strpos/substr in getCurrentUrlDir, but FYI the function preg_quote does the same as your preg_addslashes.

I too like loose integration. If possible we should remove/hide the overlapping admin functions in G2 so we only have to duplicate CMS changes into G2 db, and not have to worry about syncing the other direction.

 
bharat
bharat's picture

Joined: 2002-05-21
Posts: 7994
Posted: Mon, 2004-09-06 17:57
Quote:
- add G2 / G2mod as a prefix to all variables: isDone -> G2isDone, etc.

I'd suggest that we put all the output into a $g2Data array instead so that we can have as much return data as we want with a minimal namespace footprint. We've been burned in the past by ill-conceived portals putting important information in commonly named variables like "$index" so let's just avoid that problem altogether.

I'm also in favor of loose integration. I know that, for example, the PNphpBB2 module for Postnuke does something similar where it syncs in new member information when they first use the module. I think that every integration is probably going to have a module for the CMS and a module for G2 so it's fair to let the module for the CMS do the synchronization and use whatever means the CMS makes available to us.

Anyway, it sounds like you guys have this under control! I'm excited to see where the leads. I'll be on vacation for a week but I'll try to check in when I get net access while I'm on the road.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Mon, 2004-09-06 19:19
Quote:
I'd suggest that we put all the output into a $g2Data array instead so that we can have as much return data as we want with a minimal namespace footprint.

Good idea.. I've made this change.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Mon, 2004-09-06 21:37

Parallel to the G2/xaraya integration we should create a list of primitives that all CMS (and G2) should implement.

TODO (documentation):
@User/Group management and authentication:
idea: both, the CMS and G2, act as if they were standalone. only difference: each time the state of the CMS user/session changes (login, logout, user/session data change), the registered CMS function initiates the update of the G2 user/session. vice versa if G2 has some user properties that are not in the CMS.
- CMS: hook (event, registration of) for function that is triggered each time a user account / group data changes ((insert/)update/delete)
- G2: API to update user/group data
- CMS: hook (event, registration of) for function that is triggered each time a session state changes (login, logout)
- G2: API to start/stop/update session
- CMS: hook (event, registration of) for function that is triggered each time a session variable gets updated (i.e. prefered language)
- G2: function to translate CMS language code to G2 language code, executed when the language preference in the CMS gets changed
- G2: hook (event, registration of) for function that is triggered each time user/group data changes (i.e. user attributes not present in the CMS) (optional)
- CMS: API to update user/group data (optional)
- G2: function/API to export users/groups, run only once when the G2 CMS module gets activated
- CMS: import API, (create user/groups/assign user to groups)
- G2: register a auth function if the CMS doesn't implement login/logout aka session start/stop hooks, this function would check the state of the CMS session and update the G2 session accordingly. (this kind of solution is not preferable.)
@templating and output:
idea: let G2 generate it's output w/o the html header. then put this returned html into a CMS template.
- G2: switch between direct output and return of HTML. if embedded, return html. html for <head> and <body> is returned in separate variables.
- CMS: output buffering (ob) vs. return HTML: G2 supports return of HTML, no ob needed. if G2 sets a flag $isDone = true, G2 has already sent it's output to the browser. in this case the CMS should not output anything and call exit immediately. otherwise: put the returned html in a CMS template.
- (CMS / G2) module: filter the returned <head> html for css-links, javascript and page title. or: G2: supply these things separately.
- CMS: API to add css-links, javascript, set page title dynamically
- G2: change all generated link urls to match the CMS url format
- G2: disable register/login links/forms
- G2: disable menu links
- G2: save menu links (label, url)
- CMS: API to add menu links/items dynamically
- G2: GalleryUrlGenerator should create direct (non CMS) links for DownloadItem links. as the auth of G2 is based on cookies it's completely independent of the CMS and the downloads are as fast as if G2 was standalone.
@search plugin:
- CMS: search plugin API (part of the CMS module, queries with G2 API)
- G2: GUI-less search API, returns search results

Note: Mostly the "API" of CMS/G2 needs to be accessible from the other application directly, i.e. by xml-rpc or just boot the other application and call the appropriate API function.
some things are supported by G2 anyway, i just added them for completness.

i'm quite sure that i forgot some things, so this list may change. all list items need documentation and the xaraya/G2 integration will serve as an example how the implementation could look like.

ps: i lost my post due to a phpbb session time out (i should know by now), quite frustrating!

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Tue, 2004-09-07 16:02

Wow valiant, that's a long list.. I'll go over it in more detail later.

For now: I've updated GalleryUtilities::convertPathToUrl as you suggested, basing off DOCUMENT_ROOT instead of G2 basedir so it still works when embedded.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Tue, 2004-09-07 18:08

I'm considering adding embed.php in the g2 dir; the CMS module could require this file and then call methods like GalleryEmbed::login($uid), ::logout(), etc.
I may also put in ::init($uri) and ::handleRequest().. these would replace the G2_EMBED_URI define and require of main.php. I like this better than using a define to pass in info..

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Tue, 2004-09-07 20:41

what are the alternatives?
don't know anything better. i guess creating a second entry point for API requests and the embedded request is the best solution.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Wed, 2004-09-08 16:36

I had to refactor convertPathToUrl again.. we can't use DOCUMENT_ROOT because G2 may be installed somewhere that is accessed via a path alias. In that case G2 may not be under the docroot path.
So now I've added an item in UrlGenerator to store the relative path from the CMS to G2.. ie, if you're accessing http://example.com/cms/index.php?module=g2&.... then you'd pass in '../gallery2/' as the relative path if http://example.com/gallery2/ is your G2 path..

Nearly done with embed.php.. probably will commit tonight or tomorrow.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Thu, 2004-09-09 18:06

valiant, a comment on your suggestion to create direct-G2-urls for DownloadItem requests... if the G2 base dir is not underneath the cms path then a direct G2 request won't get the session cookie so the request may fail if it doesn't have Everybody access. Should we make it a requirement that G2 dir is under the cms?

Example:
example.com/xaraya/index.php
example.com/gallery2/main.php

If you access G2 via xaraya then you'll get a GALLERYSID cookie with path "/xaraya/" so a request to gallery2/main.php won't see the cookie.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Thu, 2004-09-09 18:19

mindless, hmm, you're right.
for now make it a requirement that G2 is under the cms tree. it doesn't hurt that much. if they had the gallery somewhere else, they can use mod_rewrite or a php redirect header. normally, if you integrate a application in a CMS, you redesign your whole homepage anyway.

alternatively, we could set the cookie directory to "/" (make it a config variable which can be set in the G2 module xaraya || cms. hmm, that's better :)

so, no, don't make it a requirement, just set "/" if the user says he wants G2 not in the CMS directory tree.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Thu, 2004-09-09 21:15

valiant, can you show me how to put hooks in xaraya for login/logout and maybe session-expire events?

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Fri, 2004-09-10 00:11

well, (a) I know nothing about xaraya and (b) xaraya doesn't seem to have events for login/logout.... however, the xaraya event system is quite straightforward so I was able to add this to includes/xarUser.php:
Top of xarUser_init()

xarEvt_registerEvent('UserLogin');
xarEvt_registerEvent('UserLogout');

End of xarUserLogIn (before 'return true;')xarEvt_trigger('UserLogin');
End of xarUserLogOut (before 'return true;')xarEvt_trigger('UserLogout');
Then I could define gallery2_eventapi_OnUserLogin and gallery2_eventapi_OnUserLogout in modules/gallery2/xareventapi.php to handle the events.. it works! I changed GalleryEmbed::login() to work by username instead of by id so we don't need uids to line up. I logged in as 'admin' in xaraya and my G2 shows up logged in as admin.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Fri, 2004-09-10 07:03

Nice. It's just that I already asked for those hooks/events in the xaraya dev newsgroup a week ago and somebody thought, most of the hooks/events i need are already there. But I didn't search for them yet.
All in all, we will have to create the hooks/events we need and are not already there. Then we will ask the others of the modules to implement the hooks and the core developers to add the events.
It's always a good idea to keep the event count extremely low. There are only 3 events in xaraya up to now. You should always use hooks if possible.
I'd like to search for these hooks / events and ask the xaraya devs to add the missing ones, but you're too fast ATM :)

What do we do, if a user browses directly to G2 main.php?
-> We don't want him to register/login/logout.
-> When loading the G2/modules/xaraya module, it should deactivate these options, right?
-> Or disable all direct request when the xaraya module is activated, but the renderShortPath. AFAIK the rendershortPath doesn't load all modules, so it's no problem. just throw an error in the G2 xaraya module when there's no G2_embed defined.

What do we do, if a user doesn't allow cookies?
-> How is this usually solved? By adding the SID to the URL, right?
-> Does G2 add the SID to the url if the user doesn't have cookies enabled? And xaraya?
-> But xaraya won't add the G2 SID to the URL when browsing around in xaraya outside the G2 module. So how should G2 know who the user is without his SID and no cookie?
-> Combination of cookies disabled (+ no SID in url) + browsing directly to G2 main.php. -> throw an error in the G2 xaraya module?

@infinite loops:
I just solved the problem of infinite loops between G2 and the CMS. Imagine the following example:
CMS updates user -> UserUpdateEvent in CMS -> CMS calls registered function for this event
-> function calls 3rdPA API to update user -> 3rdPA updates user -> UserUpdateEvent in 3rdPA
-> 3rdPA calls registered function for this event -> function calls CMS API to update user -> ... endless loop

Solution:
the registered event/hook function func_a of application A checks a global variable before calling the API of the other application. if nothing is set, it is set to i.e. "CMS_to_3rdPA" and so the functions counterpart func_b in the other application B (registered to the analogous event in the other application) will know that the update/synchronization was initiated by the application A and won't close the loop.
this global variable can be implemented as a middleware in oo design, what ever.

i know, you don't want events in G2 that cause G2 to update the CMS. but a) some people might add modules to G2 which change the G2 user, add attributes etc. and b) i want to apply this CMS <-> 3rd party application integration to other applications too.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Fri, 2004-09-10 18:07

I'm just hacking things together on the CMS side to test my G2 changes.. so yes, please update anything I'm doing to be done in a better way.. not sure how xaraya hooks differ from events, but the events we're talking about are relatively infrequent so I think either method should be ok.

@direct access to main.php:
If we do nothing special then G2 can work both as embedded or standalone. When viewing embedded then certain items will be omitted (login/logout,etc) but when viewed standalone they will be there.
If the site admin wants to have G2 only viewable when embedded then we just need a tiny bit of logic in main.php (to not call GalleryMain). Only GalleryInitFirstPass has been called at this point, so the option may need to be in config.php.

@no cookies:
You're right it could be a problem, in a case like: login, browse to non-G2 cms url, browse to G2.. at this point you won't have g2_GALLERYSID in the url so you'll get a new G2 session.
It appears Xaraya doesn't work without cookies, so it won't be a problem with this particular CMS (unless I need to configure something in xaraya....).
Idea: maybe when G2 is embedded it shouldn't use cookies at all! We can find a way to store GALLERYSID in the CMS session, and retrieve that value before calling anything in G2 (parameter to GalleryEmbed::init ?). This would solve the cookie-path problem and also automatically makes the G2 session timeout at the same time as the CMS session.

@infinite loops:
I'd still like to encourage data transfer to be one direction, CMS->G2. G2 modules that expand user data/functionality probably won't be desired in an embedded environment as the CMS most likely has more functionality/modules to offer. Let's get the basics down with single direction sync and get some people using G2 embedded and see if there is demand for sync back to CMS.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Fri, 2004-09-10 19:18

@direct access to main.php:

Quote:
If we do nothing special then G2 can work both as embedded or standalone.

no. if you don't deactivate login/logout/register in standalone when the CMS module is actived, the CMS and G2 get out of sync. i.e. users in G2 exist that are not in the CMS, etc. i definitely don't like that.

@no cookies:

Quote:
Idea: maybe when G2 is embedded it shouldn't use cookies at all! We can find a way to store GALLERYSID in the CMS session

i wanted to prevent any dependency of G2 on CMS. why? i.e. we can't make downloadItem urls direct G2 urls. or would you add the SID to these direct downloadItem urls? that could work. actually, it's a good solution for embedded G2, solves the session timeout problem too as you said.
but still, it's another requirement at the CMS: API to add your own variable to session data.

@session timeout:
right, i wanted to start this topic too. the G2 session could timeout before the CMS session time outs. or one of the cookies gets deleted. or the the CMS session timeouts before the G2 session.
setting both session timeouts to infinity is a bad hack and undesired restriction.
here too, we'd need events in the CMS for session start/update/end, right?

@simplex synchronization:
ok, start with a simple integration, but try to not design things that would prevent us from extending it easily to a duplex synchronization.

edit:

i think we should work out an alternative solution with cookies enabled before we decide for a cookieless embedded G2.
people from the CMS teams will ask why they should add a function to their API to add a variable to the session data. my guess is that not too many CMS already have such a function.
what if G2 uses the same session ID as the CMS?

edit:

@cookie path problem:
is solved (not implemented, but solved), see my other post. just set the cookie path of the G2 cookie to "/" if it's not in the CMS directory tree.

edit:
list of cms and the session set var function:

+ xaraya: xarsessionsetvar(), xarsessiongetvar() (to set & get G2 SID)
- mambo: couldn't find such a function in class mosSession
+ postnuke: should have pnSessionSetVar(), ... (xaraya is a fork of pn)
+/- phpbb: obviously doesn't have this function. but all mods in phpbb are source code hacks and this one is very easy (session.php)
+ typo3: has some session variable functions, i.e. writeUC ($variable='') or getSessionData ($key) and setAndSaveSessionData ($key, $data)
? geeklog
? drupal
? phpnuke
? SPIP
? IPB2

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Sat, 2004-09-11 20:46

@cookie / session timeout:
a cookieless design doesn't work for "G2 not embedded in CMS". i.e. phpbb integration. most will want to keep G2 in it's own folder directly under the document root. lots of people will browse directly to the gallery, without using a link containing the SID.
this plus the requirement for a "add data to session" function relativize the advantage of having solved the session timeout / synchronization problem.

so what can we do to synchronize the session (login status, active user)?
solution 1:
- just compare the G2 username (or the id if we sync users by id mapping) with the CMS username.
solution 2:
- set G2 session time = CMS session time (G2 will timeout <= CMS, because the CMS session gets updated more often)
- if G2 session timeouts and G2 wants to end/delete the session, it should check the status of the CMS session
solution 3:
- set G2 session time = infinity and the CMS should do the work
- the CMS has events for start/end session and the registered functions update the G2 session

i'm not sure what i prefer.

 
greyhair

Joined: 2004-09-14
Posts: 18
Posted: Tue, 2004-09-14 03:55

I see that there is some work going into CMS integration. May I get some direction on how to integrate G2 into Xoops.

1. Xoops only uses mysql, would G2 have to also?
2. Which would be the best approach, Xoops user info "dumped" into G2 user database then use G2 to control gallery access??
3. Is there a mechanism to redirect a user if they are not logged in to the G2 that could be mod to say CMS?
4. Would it be easier to use the CMS comment system or G2?
5. Xoops uses smarty for templates, how would the affect G2?

Any help would be appreciated! Even a reply to wait a month or so for the crew to work out the bugz....

Thanks!!

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Tue, 2004-09-14 06:09

greyhair, this topic is about general CMS integration. As a proof of conecept we're integrating G2 in xaraya. But when we are finished, other CMS can and will follow. G2 isn't quite ready for integration with xoops and other CMS, it's the goal of this thread / integration to develop the specifications and code snippets that you can use for the integration with your prefered CMS.
But we would like to hear if xoops has problems with the way we plan to integrate G2.
I encourage you to read what we've already written in this thread (and the linked thread too). Some of your questions are already answered. If we discuss about xaraya, you could replace the term by "CMS", it (should) apply to all CMS.

Answers to your questions:
@1. G2 supports mysql, mysqlt, postgresql (, oracle, more to come)
@2. Both, G2 and xoops, will have a complete list of all users in their own user table. We will export/import users when activating G2 for integration.
@3. When integrated, the G2 login will disappear. There is only the login link/button/form of xoops left. When logging in, you will be logged in into G2 too, automatically.
@4. Easier? Of course not. G2 already has a comment system. Replacing it by the CMS comment system would need a lot of work, i guess.
@5. That's doesn't affect G2. We let G2 generate its content minus the html head tag and put all the contents in a xoops template.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Tue, 2004-09-14 06:20

Just wanted to point out how the permissions would be assigned in an integrated/embedded G2.
Basically, it works exactly like in a standalone G2, all permissions are assigned in G2, you would assign permissions to groups and assign the group memberships to users preferably to minimize the work.
In a CMS environment you would like to administrate the permissions once and for all and all users that sign up, join a group automatically and thereby are granted/revoked all the CMS rights they need.
G2 has groups too. And all groups of the CMS are imported in the G2 database (and vice versa). So all you have to do is administrate the G2 group permissions too and all users that register in the CMS get theirs G2 rights automatically.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Wed, 2004-09-15 15:41

element, on IRC, was asking about WordPress integration.. I took a quick look and came up with the attached plugin. This is display-level integration only, not session-level. I didn't see any hooks in wordpress to make a plugin control the main content of the page, so I made a copy of index.php and replaced the <div id="content">....</div> content with a call into the plugin.
To use this, unzip the attachment in your wordpress dir. Then edit wp-content/plugins/gallery2.php and make sure the relative paths are correct in the require_once and GalleryEmbed::init calls (if you have docroot/wordpress and docroot/gallery2 dirs then they should already be ok). Then apply the diffs to index.php. Finally login to wordpress and activate the gallery2 plugin.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Wed, 2004-09-15 15:52

mindless, it doesn't make a lot sense to start other integrations simultaneously. as long as we discuss all requirements at the CMS, the pros and cons, our integration is quite general.
we'll have to investigate which CMS are compatible with our needs out of the box and for all others we'll have to create work arounds or patches to the core files.

what's next:
- session time out / synchronization discussion and decision
- adodb in G2: some changes needed, as i described in the forum and via email.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Wed, 2004-09-15 19:52

valiant, it doesn't make much sense to not look at lots of different CMS's and see how they work.. right?

@adodb
Xaraya uses a forked adodb. Hopefully we can avoid doing the same just to cope with their hacks.. we can fight their hack with this hack: override newEntity in MysqlDatabaseStorage.class; if $this->_db->hasGenID is false then temporarily set it to true while calling the parent newEntity method, then set it back.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Wed, 2004-09-15 20:37

@adodb $hasGenID:
sounds good. one thing though:
in xaraya/xaradodb/drivers/adodb-mysql.inc.php:

	function GenID($seqname='adodbseq',$startID=1)
	{
		// post-nuke sets hasGenID to false
// XARAYA MODIFICATION - START
		if (!$this->hasGenID) return 0;
// XARAYA MODIFICATION - END

what i don't get, i don't have the time to investigate though, why xaraya works with "$hasGenID = false" and this "return 0;" for the mysql driver.

@other CMS: i just think we should first work out the remaining issues, i.e. session synchronization.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Wed, 2004-09-15 22:44

Xaraya uses a feature of mysql called "auto_increment".. so it gets back zero from GenID() and uses that as the value to insert in the db.. but the auto_increment feature gives it a new id value.

Quote:
@other CMS: i just think we should first work out the remaining issues, i.e. session synchronization.

That's why I didn't do anything beyond display-level integration.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Wed, 2004-09-15 23:24

@no-cookies
How do any of your 3 solutions solve this case:
1) cookies disabled
2) browse to cms (not g2)
3) login, browse a few cms pages (not g2)
4) browse to g2 in cms
In step 4 we need G2 to find the session that was created when the user was logged in in step 3. How will that SID value be remembered after browsing a few non-g2 cms pages? Or are you suggesting the next time we visit g2 we just create a new session and login whatever the current cms user is? (this may lead to lots of session files being created and abandoned, but functionality-wise I guess it could work...)
It doesn't seem to me like requiring the cms session to store some data is a heavy requirement.. what kind of session can't store data? Also, can you explain more how phpbb integration might work? If you're "not embedded" do you still expect the sessions to be in sync?

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Thu, 2004-09-16 07:00

@adodb: thanks for the explanation. this should definitely work.

@no cookies:
a workaround could be a 2-stage link.
in CMS as xaraya, the wrapper (the gallery2 module in xaraya) would look up the G2 session for the current xaraya session and then append it to the url something like that. in other CMS where G2 user/session is synchronized but the G2 pages are not embedded, we would link to embed.php which would translate the CMS SID to a G2 SID.
it's not a great solution, but cookie-less browsing is quite outdated.

Quote:
It doesn't seem to me like requiring the cms session to store some data is a heavy requirement.. what kind of session can't store data?

most CMS sessions save some data, but by far not all allow to store user-defined, dynamic data. i'll investigate further what CMS allow this and what CMS don't, but not before next thursday.
note: if you want to support cookie-less browsing, you'll have to append the CMS SID to all G2 urls too, i.e. domain.com/index.php?module=gallery2?......&g2_SID=sd7ds67ds8&SID=sd8ds76ds68sd8

having G2 use the CMS SID (only the ID) for it's own sessions isn't a viable solution, right? the way the ID is created may and almost certainly differ, the length of the ID may be different (db field), etc. but it would solve session time-out and cookie-less browsing.

@phpbb integration: some may want to keep the two applications standalone, but the user/session should be synced. it should work like a "embedded" CMS integration. we add some functions/hacks to phpbb which call embed.php for syncing the sessions/users, but G2 is called with main.php (if cookies are allowed, else: call embed.php which gets the SID, then redirect to G2-url&SID=...).

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Thu, 2004-09-16 23:30
Quote:
cookie-less browsing is quite outdated

apparently.. neither xaraya nor wordpress works without cookies!

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Fri, 2004-09-17 01:24

Session Management Design

Requirements/Challenges

We can break down the problems we'd like to solve as follows:

  • Session persistence:
    Able to browse in/out of G2 within CMS and maintain both CMS and G2 sessions
  • Session expiration:
    G2 session doesn't expire before CMS session, but old G2 sessions do get cleaned up (preferably when or soon after CMS session expires)
  • Cookie path:
    Work whether or not G2 base dir is under CMS dir
  • Cookies:
    Work with or without cookies; use cookies when possible (don't lose session just because of a manually typed url with no SID)

Solution A

  • All page requests go through CMS (even if G2 is displayed such that it looks standalone)
  • DownloadItem requests may go directly to G2 (G2 SID always in url)
  • Combined session maintained via cookie or url-rewriting by CMS; no G2 cookie!
  • CMS passes its SID to G2 init(); G2 maintains mapping between CMS and G2 SIDs
  • CMS also passes SID key to init() if the CMS works without cookies
  • If cookies are disabled and CMS SID key name was given then G2 UrlGenerator writes CMS SID key/value in url instead of G2 SID
  • Expire SID mapping too when G2 session expires

Pros: meets all requirements
Cons: significantly more embedded-specific logic in G2 core; can't link to standalone G2

Solution B

  • Require cookies to use G2 embedded
  • Any request may to through CMS or directly to G2
  • CMS and G2 each keep own SID cookie; cookie-path for G2 cookie automatically set to deepest past that contains both G2 and CMS dirs (can figure this out from relativePath parameter in UrlGenerator)
  • G2 cookie lifetime = forever (don't know how CMS cookie is set..)

Pros: easier to implement
Cons: cookies required

-------------------------------------------------------------------------------------------------

What do you think? Solution A was the simplest I could come up with that works without cookies.. seems like a lot of hoops to jump through to support those outdated cookieless people :wink: .. If we go with Solution B the only core change is changing the cookie path based on relativePath. Any better alternatives or improvements to these designs?

@session-expiration
We'll need to keep G2 session expiration fairly high so the G2 session doesn't timeout before the CMS session.. an alternative: add GalleryEmbed::keepAlive() that the CMS calls on every request.
Pros: now we can set CMS timeout == G2 timeout
Cons: creates G2 session even for people who browse CMS but never visit G2; runs some extra code on every request.
Maybe I can find a way to make keepAlive not create a new session but only do something if the G2 session already exists...[/]

[/]

[/]

 
bharat
bharat's picture

Joined: 2002-05-21
Posts: 7994
Posted: Fri, 2004-09-17 03:53

Great summary, mindless. You guys are kicking ass.

I like solution B. I'd rather see us go with something simple that works, even if it imposes more requirements. I think that requiring cookies is not unreasonable, especially when the CMS (Xaraya, in this case) requires cookies. Gallery 1.x already requires cookies so pretty much 100% of our user base uses cookies or has no session :-)

When we're embedded, I think we should force the session expiration to the "forever" value and then not allow the site admins to change it (read: get rid of the option in AdminCore). We can then trigger our session expiration based on events (when the CMS session goes away, it triggers our session expiration also -- if possible) or our standard expiration (we expire sessions that don't have a matching CMS session).

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Fri, 2004-09-17 05:29

Just documenting one last idea on no-cookie support..

- CMS passes its SID key and value to init()
- GalleryEmbed returns G2 SID and CMS stores it in its session
- On subsequent requests CMS passes its SID key/value and the G2 SID to init()
- G2 uses SID it is given or creates a new session
- When cookies are in use everything works like Solution B
- When cookies are not used then G2 UrlGenerator writes CMS SID into urls and G2 SID is maintained in CMS session

Pros: works without cookies and doesn't need to keep SID mapping; extra parameters to init() would be optional so CMS's that require cookies wouldn't need to pass anything.
Cons: requires ability to store data in CMS session if you want no-cookie support

I think this is the solution I'd use if we ever want embedded+no-cookie support.. but I'm happy to go with Solution B.

bharat, what do you mean by "our standard expiration (we expire sessions that don't have a matching CMS session)." ? Do you mean from GallerySession::_expireSessions we would have some way to check if the matching CMS session is still around?

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Sat, 2004-09-18 16:57

Something to keep in mind regarding login view: just removing the login link isn't sufficient.. if you attempt to access an item w/o permission (maybe you bookmarked a link while logged in, but don't have access when not logged in) then G2 redirects you to the login view. Maybe we need our CMS module in G2 to affect this logic and redirect to a login screen for the CMS?

 
bharat
bharat's picture

Joined: 2002-05-21
Posts: 7994
Posted: Sat, 2004-09-18 17:02
mindless wrote:
- CMS passes its SID key and value to init()
- GalleryEmbed returns G2 SID and CMS stores it in its session
- On subsequent requests CMS passes its SID key/value and the G2 SID to init()
- G2 uses SID it is given or creates a new session
- When cookies are in use everything works like Solution B
- When cookies are not used then G2 UrlGenerator writes CMS SID into urls and G2 SID is maintained in CMS session

Pros: works without cookies and doesn't need to keep SID mapping; extra parameters to init() would be optional so CMS's that require cookies wouldn't need to pass anything.
Cons: requires ability to store data in CMS session if you want no-cookie support

That sounds like a much better solution than the earlier two. I think it's reasonable to expect that we'll be able to store session data in the CMS session. I'd be shocked if the CMS doesn't give modules the ability to keep their own session data. Unless it's a lot more effort (and it doesn't sound like a lot to me) I like this solution best.

mindless wrote:
what do you mean by "our standard expiration (we expire sessions that don't have a matching CMS session)." ? Do you mean from GallerySession::_expireSessions we would have some way to check if the matching CMS session is still around?

Yes. I think that there will probably be an API for this, and if there isn't then perhaps we can add one in the module that we write for the CMS because that module is (theoretically) tightly bound to the CMS version so it can look under the covers to validate session ids.

 
bharat
bharat's picture

Joined: 2002-05-21
Posts: 7994
Posted: Sat, 2004-09-18 17:05
mindless wrote:
Something to keep in mind regarding login view: just removing the login link isn't sufficient.. if you attempt to access an item w/o permission (maybe you bookmarked a link while logged in, but don't have access when not logged in) then G2 redirects you to the login view. Maybe we need our CMS module in G2 to affect this logic and redirect to a login screen for the CMS?

Or maybe we could do something clever and interpose our own rewrite logic for view parameters? Ie, when the GalleryUrlGenerator is called upon to redirect to the core:Login view it can intercept that and create a url that takes you to the CMS' login page? I haven't thought through the implications of that yet.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Sat, 2004-09-18 20:26

G2 cookie path now checks relativeG2Path and moves the path up so it will encompass both G2 and CMS app.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Sat, 2004-09-18 22:23

great work mindless, the last solution is pretty much perfect; it works with minimal CMS API if cookies are enabled and with minimal G2 changes if cookies are disabled and both ways merge almost seamless.

@login:
could we define a permission for login/register if it doesn't already exist? may seem strange, but we could just revoke this permission from everyone, if we activate the CMS module. when adding links to the view, you could check for each link if the user has the permission to see the view the url links to. the permission would not only block the link in the html, but also the register/login views too.

ps: i'm reading your posts, but i can't contribute 'till thursday when my exams will be over. [img]http://www.nei.ch/phpBB/images/smiles/bier.gif[/img] @ orthography ;)

 
bharat
bharat's picture

Joined: 2002-05-21
Posts: 7994
Posted: Sun, 2004-09-19 18:02
valiant wrote:
@login:
could we define a permission for login/register if it doesn't already exist? may seem strange, but we could just revoke this permission from everyone, if we activate the CMS module. when adding links to the view, you could check for each link if the user has the permission to see the view the url links to. the permission would not only block the link in the html, but also the register/login views too.

Hm. That's an interesting approach .. I think that it's a little heavy though. I agree that we should probably have a facility for allowing some other part of the code to decide about the capabilities offered by the current G2. My url generator hack would probably work for login/logout but I think that it's a hack that will cause us grief later. Perhaps we should create a new static class called GalleryCapabilities where we can register different types of canXxx() methods and allow the CMS integration to flip bits on and off. For example, the CMS module could say:
GalleryCapabilities::setCanLogin(true);
And in the core code we could check it like this:

if (GalleryCapabilities::canLogin()) {
...
}

etc. etc. We can make lots of different parts of the core switchable this way.

valiant wrote:
ps: i'm reading your posts, but i can't contribute 'till thursday when my exams will be over. [img]http://www.nei.ch/phpBB/images/smiles/bier.gif[/img] @ orthography ;)

Woo hoo! Good luck with the exams!

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Mon, 2004-09-20 16:14

@G2 module for CMS
I'm wondering, do we really need a module in G2? It seems to me we can set everything up in GalleryEmbed::init.. doing some initial synchronizing of users/groups in a module activate() might be nice, but once activated I'm not sure the module would do anything..

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Mon, 2004-09-20 19:04

I've implemented:
-- GalleryCapabilities class, with support for turning off login/logout links and changing the login-redirect url. I did GalleryCapabilities::can('login') instead of ::canLogin() to make it more generic.
-- Session management Solution "B+".. optional parameters are in place for GalleryEmbed::init() and it returns the G2 session id. UrlGenerator uses CMS session key/id when appropriate.

What CMS supports cookieless browsing so we can test this out?

 
bharat
bharat's picture

Joined: 2002-05-21
Posts: 7994
Posted: Mon, 2004-09-20 19:16
mindless wrote:
@G2 module for CMS
I'm wondering, do we really need a module in G2? It seems to me we can set everything up in GalleryEmbed::init.. doing some initial synchronizing of users/groups in a module activate() might be nice, but once activated I'm not sure the module would do anything..

Hm. Originally I was thinking that we'd have the module so that we could put things like GalleryEmbed::init inside it. But if we've got something generic enough in GalleryEmbed that it works for all CMS, then I guess we don't need a module. If we can get away without it, then I think we should. We can always add one later!

mindless wrote:
I've implemented:
-- GalleryCapabilities class, with support for turning off login/logout links and changing the login-redirect url. I did GalleryCapabilities::can('login') instead of ::canLogin() to make it more generic.

Sounds good. Maybe we should make the strings defines() to minimize typos?

mindless wrote:
-- Session management Solution "B+".. optional parameters are in place for GalleryEmbed::init() and it returns the G2 session id. UrlGenerator uses CMS session key/id when appropriate.

What CMS supports cookieless browsing so we can test this out?

Outstanding! I have no idea what CMS works without cookies, though. I vote that we don't worry about it for now, (since we know that we have a solution) and when we encounter a CMS that works without cookies we can resolve any latent issues that we discover.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Mon, 2004-09-20 20:15

mindless, wow! i wish i could have helped more, but you're almost finished!

@CMS module in G2:
embed should be generic enough for all CMS/integrations. we will certainly add methods to the class for search and session method alternatives perhaps, but it should be generic enough for all kind of integrations.
what we need in this class is a add/update user/group method. or move this to the CMS module as every CMS has different user/group management.
the gallery2 wrapper module functions add/update user/group in the CMS work together with the functions in G2. it's up to us to decide how much work is done in the CMS module and how much is done in the G2 module.
the CMS module will be needed for:
- user/group synchronization on (re)activation
- ?

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Thu, 2004-09-23 14:00

mindless, I'm "back". First things I'll do are
- check your changes to G2, the gallery2 module in xaraya and your xaraya event/hooks. please send me the modified xaraya files if possible.
- analyze xaraya, check what hooks/events are already there, what hooks we need
- prepare a guide to loose CMS <-> third party application integration examplified by G2 and xaraya
- send this guide first to xaraya core developers to get the hooks we need.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Fri, 2004-09-24 15:28

@initial user/group export/import - CMS module activation:
init of activation:
- we need to disable G2, put it in "maintenance mode" or at least disable the user registration controller

group export/import:
- generate a list of CMS groups and a list of G2 groups (don't display)
- check if there are groups with the same unique_name (for CMS based on unique_name)
- display: "found x groupnames in the CMS that already exist in G2 or vice versa. are these the same groups or do you want to rename the G2 groups? create a groups to update list.
- update the group lists
- treat the special users/groups accordingly: hardcoded anonymous user mapping etc.
- import all groups from the G2->CMS list to the CMS
- import all groups from the CMS->G2 list to G2
- update G2 groups according to the groups to update list

user export/import:
- same procedure for users
- don't include the pending users in the G2->CMS list, create a pending G2 users list.
- pending users (registered, but registration is not finished): ???
-> i'd say: generate email to all pending users: "we're changing our website. please register again at CMS login path." and flush the pending users from the database
- if the CMS doesn't have the same password hash format: email new CMS users (G2->CMS list) to go through the new password procedure.

set configuration according to some module config vars
- GalleryCapabilities::set('login', $var);
- GalleryCapabilities::set('register', false);
- ...
- set a module plugin parameter: G2Embedded = 1 (meaning, the CMS module in G2 is activated and G2 is ready for working in an embedded environment). In the CMS, when installing the G2 wrapper/module, it would first check if G2 is ready for integration. So we probably need to add a function to embed.php to check against this plugin parameter.

when finished:
- logout all users (but the admin who activates the CMS module) (because they need to login via the CMS, and the new cookie path won't match the old one in most configs) = delete their sessions.
- exit maintenance mode

error handling:
we're sending emails and flushing pending users only at the end of the script when all users have been sync'ed. we're not deleting/updating any other data.

@CMS module configuration variables:
- Show Login link (redirecting to CMS login page)
- Show Your Account link
- Show Memberlist link
- Show search link/box (assuming we will integrate G2 search in CMS)
- Allow browsing directly to G2 (without the CMS layout around it)
(setting this to false would mean to reject all G2 requests but the DownloadItem request).
- plus the 'G2Embedded' parameter

@1 single CMS module + export / import plugins vs. for each CMS a module:
- IMO the CMS' module only purpose is its activation code: configuration of G2 and synchronization of users/groups
- the only difference between CMS x and CMS y would be different export / import functions. And possibly different default configurations.
- we could create a first CMS module and copy it for other integrations
- or create a generic CMS module. you'd choose a specific CMS plugin in the CMS module configuration. we'd get rid of the mutual exclusion problem of mutliple CMS modules too.

@embedHead.tpl:
We don't really need embedHead.tpl, parsing for javascript, css and the page title is a dirty hack in my xaraya gallery2 module. what about returning javascript/file, css/fle, page title, meta information by variables?

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Sat, 2004-09-25 18:06

mindless, we got our xaraya events!
I've searched through the xaraya code for hooks/events we could use and which notifications are missing.

we need notifications for:
- login
- logout
ok new role (user, group) (new!=add!=create?)
ok update role
ok addmember
ok removemember
ok delete role (what do we do with deleted and purged users/groups?)

now they added login/logout events nearly exactly like you proposed.
they even give the logged in / logged out userid as an argument with the event, see example below, xarEvt_trigger('UserLogout',$userId); is called in the logout function.

function <module>_eventapi_OnUserLogout($value)
{
    // $value contains the userid in this event
    $user = xarModAPIFunc('roles','user','get',
                          array('uid' => $value));
    // do something with $user['uname'] or whatever
}

Now, we need embed.php functions for the other synchronization hooks too (new user / group, addmember, etc.): for each create a small hook function in xaraya gallery2 and a small function in embed.php.

i'm not sure what we will do with the password for new users ( password changes, got to think about that.

@search integration:
at the same time i'm trying to create a search hook in xaraya. therefore i'll need a emebed.php search function wrapper. that implies some changes to the search module, because i need the search results as a list in php and not as output ready html.

edit:
xaraya thing: i noticed that the addmember, removemember hooks in the roles module don't tell us the user id that has been added/removed from the group, we only know the involved group.
I filed a feature request / bug, IMo they'll add it, it's no additional overhead.
i've sketched the hook functions for gallery2 module, perhaps i'll code them today.

edit:
updated your gallery2_eventapi functions (new: they have an argument, ...).

edit: now that i actually tried to code the hook functions in xaraya, i run into some inadequateness of the roles (user management) module in xaraya. I extended my bug report / feature request...

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Sun, 2004-09-26 18:39

I've added some functions to embed.php:
- function createGalleryUser($args)
- function updateGalleryUser($args)
- function deleteGalleryUser($userName) (not finished, not sure what to do)
- function createGalleryGroup($args)
- function updateGalleryGroup($args)
- function deleteGalleryGroup($groupName)
- function addUserToGroup($userName, $groupName)
- function removeUserFromGroup($userName, $groupName)

I've started to code the search function wrapper in xaraya, but I'm waiting for your comments on the G2 search module change.

I've sketched the xaraya synchronization hook functions, but can't finish them 'til they change some things in the xaraya roles module.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Sun, 2004-09-26 21:55

@groups
Something to keep in mind in our design: I'm not assuming the CMS has a concept of groups.. integration at user level is mandatory, but our apis should allow the integration to manage groups in the CMS or keep group management in G2 (but not both, of course)

@user/group sync
We should do only a very basic sync.. not too much effort in coding a lot of intelligence into it. Generally I think people will begin the integration with an existing CMS and a new G2, or sometimes a new install of both.. it should not be a high priority to support integrating existing CMS with existing G2, both with existing users and groups. same goes with the pending users case..

@registration
I don't plan to do anything special to disable registration or member list; the site admin can disable the modules.

@password changes
Don't matter.. password in G2 is not used and doesn't need to be in sync.

@head
It's not trivial to return separate <head> components (script, style, title, meta.. are there others?) as the G2 template system simply gets header template files from the views; that template can have any content.. Is it a common requirement for the CSS to need the head components all in separate pieces? I wonder why it can't take just a block of html to go in the <head>..

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Sun, 2004-09-26 22:39

@groups
If you use the groups API of the CMS in G2, you'll need to translate queries. You need to be able to access the CMS and the G2 database in the same queries. You need to rewrite usergroup helper classes because certain CMS have a different user api (i.e. in xaraya you can add groups as members to other groups and create a tree of groups and users, if you want to know if a user is in group "all users", you need to check the whole parent tree of the user if there's a group which is called "all users").
etc.
bottom line: keep it seperate, synchronize groups exactly as we synchronize users.

@user/group sync
right, we should start with the basic case, but we will have to support the other cases too. i.e. existing G2 / CMS -> intergrate and embedded G2 -> standalone G2.

@registration
allow registration in an embedded G2 and get out of sync with the CMS? i absolutely dislike this idea. don't allow the owner of the G2 to enable registration / login (without login redirect) when G2 is embedded.

@password changes
case embedded G2 -> standalone G2. if all passwords are stored in G2, it's as simple as it can get.
else: all users have to go though the change password process.
and how do you think would a G2 user table without passwords work when you still enable login?
my embed functions solve it.
if CMS uses the same password hash format, use the hash from the CMS.
if CMS uses other password hash format and is able to give us the password in cleartext, store it md5'ed in G2.
else: create a random password, store it md5'ed in G2. if we go from embed -> standalone G2, all users will have to go through the change password process in this case.

@head
there is only 1 <title> in HTML, only 1 <meta name="DESCRIPTION" (not sure if multiple entries of a name->value pair simply overwrite each other) , you can set more than 1 link element (css), don't know about script section, but i'm quite sure that you are allowed to set more than 1 script / style section in the html head section.
bottom line: can't just paste the complete head section into another head section, at least the <title> element would make our page invalid.

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Thu, 2004-09-30 23:23

@groups
as we discussed on irc, group integration is optional.. if a CMS doesn't have a concept of "groups" then group management can be done in G2. if the CMS does have groups it will be better to integrate at group level, so administration can be done in the CMS.

@session integration
valiant, I know you mentioned this sometime before but I'm just now thinking it through... you had the idea of comparing the cms user and g2 user when a g2 request begins, rather than relying on the g2 session being current (which we're doing now by calling GalleryEmbed::login at cms login time). The advantage of the compare approach is if the user never actually visits a g2 page then no g2 session (or cookie) is created for that user. No need to create and (sometime later) expire those unused sessions. The disadvantage is the added check on every init() call, but I think this is negligible.
Does this seem like the better approach? We won't need the login() hook.. what about logout? Any security concern in not clearing the g2 session when a user logs out?

 
mindless
mindless's picture

Joined: 2004-01-04
Posts: 8601
Posted: Fri, 2004-10-01 03:07

@session integration
discussed with valiant on irc.. I have a modified solution to prevent unneeded g2 sessions and also avoid the active user check on every request:

1) login hook calls GalleryEmbed::login only if a g2 session already exists (ie, login to cms won't create a new g2 session)

2) GalleryEmbed::handleRequest will accept active username as a parameter and if a new g2 session needs to be created it will ensure that username is made active in the g2 session.

If the g2 session already exists we can assume it has the correct active user, whether via #1 or #2 above.

3) logout hook works as it does now, except if there is no g2 session it does nothing