Laura Cavanaugh · Aug 12, 2016 go to post

Yes, yesterday I had the same method in both the child class and th parent class.  It wasn't working in either class, but I think it was because it existed in both.  I have since removed the meothod from the child class, and this is the sig dump:

2
 
0000: 1D 01 06 01 70 55 52 4C 11 01 25 4C 69 62 72 61         ....pURL..%Libra
0010: 72 79 2E 53 74 72 69 6E 67 02 01 02 01 1F 01 08         ry.String.......
0020: 01 73 69 6C 65 6E 74 11 01 25 4C 69 62 72 61 72         .silent..%Librar
0030: 79 2E 53 74 72 69 6E 67 02 01 02 01                     y.String....

Interesting.  Looks like just the two params now, and no doubles.

So, child classes cannot have the same javascript method name as a parent class? Oh wait, there's no overloading in Cache, so perhaps, even though that's more like overriding, it didn't work?

Can we open a discussion on child class properties?  I added some to a mid-level class (it has a parent and a grandparent, and a bunch of children); when I added two properties to it, the grand-parent class was unable to retrieve a property correctly.  When I remove the properties, the grand-parent class is fine. Seems similar to having a method in a parent class with the same name as a method in a child class.

Laura Cavanaugh · Aug 17, 2016 go to post

Yes, but since "there's no %OnNew concept" for a class that extends from %Zen.Component.page, I can't use it.   looks like %OnCreatePage could be used.  Too late for me though.  The code is already written, so I have to work around some things.

Laura Cavanaugh · Aug 29, 2016 go to post

hi Marco,

Looks like that's what we are doing.  We have at least 4 pages in the heirarchy, and the top page inherits from %ZEN.Compone.page.  I'm not sure why it works, but our XDATA is not overwritten by the child classes.  The parent pages have the logo and the menus, etc, that are on all the pages.  Each child class has its own XDATA stuff on it too.

I wanted one more level of page, that contained methods as well, that child pages would use.  These methods would be run on all events, but with the child page's properties, such as "page name", or "table name".  

So for example I wanted a parent page with data entry capabilities to edit dictionaries.  Each child page would contain the dictionary table name and its own Save method, but most of the other methods are the same.

Anyway, it's too late to re-write all the pages; I was just wondering what would be the best way in the future.  

Laura Cavanaugh · Aug 31, 2016 go to post

OK, that's helpful info Eduard.  I can use Security.Applications, but in order to get the properties, such as Path, I need an Application Name.  The question is, what Application name am I actually using?  I was going to use the path in order to find the application.

I think you're right in that the HOMEPAGE  is causing a specific application to be used.  However, as the user switches namespaces, the HOMEPAGE appears like this: /OurAppName/newhomepage.cls.  There's no mention of the namespace.

This could imply that only the one Application called '/OurAppName' is being used, in which case I think a Group By Id could work.  I'll have to think about what you said though.

Thanks,

Laura

Laura Cavanaugh · Aug 31, 2016 go to post

btw, looks like i found the Application in %session.Application.  That gives me the application that the tab is using, at least...

I don't want to share %session Data between tabs.  They are separate entities.  I'd prefer to share logon authentication, however.

Laura Cavanaugh · Sep 1, 2016 go to post

OK.  I know how to switch namespaces.  What I'm trying to achieve is if the user opens another tab or browser, the two sessions share namespace, but I don't want them to.  Change to NamespaceB in one, and the other changes to NamespaceB as well, without the user knowning.

In MgmtPortal, I can change to ENSEMBLE in one tab, but the other tab stays in DEMO.  (However, my processes all think I'm in %SYS becuase the third tab viewing the processes is in %SYS -- bug??)  Watch out - if you try to view a global in DEMO, at first it will think you're in %SYS. Try it (I'm on 2014).

But after that inital hiccup, MgmtPortal allows one tab to switch namespaces without changing the other tab. how? How does one do that using web applications?

Laura Cavanaugh · Sep 1, 2016 go to post

Ok, it's really easy to mess up MgmtPortal; however, I do see the $NAMESPACE=namespace in the URL (at times).  Although not completely consistent (try it - so easy to confuse it), at least it gives you a starting point of where the user thinks  you should be.

Is that the only way mgmt portal knows?  Is it switching namespaces on the other tabs every time you change one tab?  Or is it keeping the tabs' namespaces separate?

Laura Cavanaugh · Sep 1, 2016 go to post

Well, I'm not a web programmer, and I don't know anything about web sockets.  So let's go with "not using".

We do store the namespace in the %session.Data variable.  howver, it's possible to chnage the namespace while on a second tab, and then when you come back and file data, oops, you're filing it into the wrong namespace.  

We'll just have to implement checks with the %session variable, perhaps a URL parameter, and what namespace the user thinks he's in based on a field on the screen.  

In the meantime, I'm going to have to say "no second tabs, even though it can make you feel more productive to work on separate clients/applications at one time".

Sigh.  Thanks.

Laura Cavanaugh · Sep 1, 2016 go to post

And for the future record, it's the %response object, which actually references onPreHTTP() in the Context property.  So yeah, I'll be looking at all that.

Thanks all.

Laura Cavanaugh · Sep 6, 2016 go to post

I'll look into the AJAX thing, thanks.  

We do set an AppTimeout, and upon timeout we ask the user first if he really wants to timeout.  If so, then the session is logged out, not timed out, and the license is released.  But, this is only if the user is good and either accepts the timeout or logs out with the logout link.

If he closes the browser (bad user) then the license is not released.  We have some that have been active for 11 days, and I know they're not being used.

I'll see if I can catch a 'close' just before the tab or browser closes.

Is there a way to tell cache to remove the license if nothing has been done with it in, say, 24 hours?

Laura Cavanaugh · Sep 7, 2016 go to post

I was playing around with that... actually I was looking at the ZEN version "onunloadHandler".  From  the documentation: "This client-side page method, if defined, is called when the client page is about to unload. It is triggered by the page’s HTML onbeforeunload event."

But it was causing a popup to appear when the user is simple navigating around the application -- of dozens of pages.  I assume each page is unloading before the next one appears.

I wonder if I have access to the URL of the next page.

I'm really surprised HTML5 doesn't have something like this yet, to capture a tab/browser close event rather than just an unload.

Anyway, thanks -- I'll see what I can do.

Laura

Laura Cavanaugh · Sep 9, 2016 go to post

Hi Sean,

Yes, there are 241 csp sessions, and all but 9 have timeouts in the past.  I have been working on logouts and sessions, and have changed things in the code, but the default timeout was always 3600 at most (set in the web application), and now it's 45*60 (45 minutes), set in the code.

How do I clean these up?  If I can at least clean them up, I can see if the current logout code will reclaim sessions/licenses.

Laura Cavanaugh · Sep 9, 2016 go to post

Yes, we have had a SessionEvents class, since before I took over logouts and sessions.  

I have since had the user logout with ?CacheLogout=end, which calls OnEndSession in the sessionevents class,  which then calls Do ##class(%ZEN.Controller).OnEndSession() per the documentation.  I do a little cleanup in OnEnsSession, too, but nothing worth noting ( a little temp global cleanup ) (ok, so I just noted it).

Yes, before I took over this, the OnEndSession actually set EndSession = 0; I don't think we knew what to do.

But NOW, wouldn't the Daemon just clean stuff up? 

Say, am I logging out correctly now and ending everything? That is, as log as the user logs out.  If he just closes the browser (you can never really stop them from doing this), what happens to the session and to the license? 

Thanks

Laura

Laura Cavanaugh · Sep 9, 2016 go to post

We set the SessionEvents class programmatically.  When I end a session via management portal, it does not end.  Sometime it sets the Timeout to NOW (UTC time) but it's still in the list of CSP Sessions in mgmt portal.

I can see the application it's using, so I set the SessionEvent class in the web application to our SessionEvent class, (sounds redundant but it's not), then tried to end it again.  It's still there. 

There are some sessions using the web application /isc/studio/usertemplates/ with a timeout of 2016-08-30 17:30:41.

Does the CSP.Daemon try to run our own SessionEvents class? Are there settings for this somewhere?

Thanks,

Laura

Laura Cavanaugh · Sep 9, 2016 go to post

Thanks Sean.  Jonathan at IS did call me today, and we discussed sessions.  I found that I had been timeing users out incorrectly, but that i'm doing it correctly now.

We decided that I would set the Events Class to my session events class for all the web applications that we're using.

The problem is that I did that, but the sessions still dont' seem to be timing out. I began to play with the session object at a terminal window (for future reference, it's the %CSP.Session class, and it's persisten).  I was not able to edit a session object with ID = SessionId, because of an error.  I think this may be causing a lot of problems on our end.  

Yes, IS will have to help with this.

Thanks!

Laura

Laura Cavanaugh · Sep 16, 2016 go to post

nope.  i'm talking about Cache web applications. There are two properties onthe web application page: Loging Cookie, and Session Cookie Path.  The Session cookie path is a path.  We set all of our applications to use the same session cookie path. We do not have the Login Cookie option set.  So, presumably all of our applications use the same (cache) authentication because of the session cookie path.

Jsut wondering what would happed if I check that little Login COokie Path box.

I also see cookies in my browser, with the same session ID as some of my CSP sessions. Wondering what that cookie is.  Not a login cookie?

Thanks,

Laura

Laura Cavanaugh · Sep 19, 2016 go to post

AH.  IF we use cookies, they will be stored in the Session Cookie Path.  We don't, but the Application must use at least the one login cookie to pass authentication between applications.  I can see it in my browser, and it's called CSPSESSIONID +other stuff.  

I'm thinking that this login cookie would be used somehow if the Login Cookie is selected? Or not used?  We don't want that either-- we like the continuity between applications. But, what does happen if the Login Cookie is selected in the web application?

What could we store in a cookie?  Can we possibly find out if a second tab has been opened by using a cookie?

Laura Cavanaugh · Nov 2, 2016 go to post

But what else?  How do you run it?  Do you need to be in a %csp session?

I have the %ALL:

%SYS>w $roles
%All

Attempt to run it as a class method:

%SYS>w ##class(%CSP.Session).LogoutAll("laura1") 
W ##CLASS(%CSP.Session).LogoutAll("laura1")
^
<METHOD DOES NOT EXIST> *LogoutAll,%CSP.Session
%SYS>

Try it with a session object:

%SYS>s session=##CLASS(%CSP.Session).%OpenId("fBOZJihk0C")
 
%SYS>w session.LogoutAll("laura1")
 
 quit $$LogoutAllUserSessions^%SYS.cspServer(username, %request, %response ) }
 ^
<UNDEFINED>zLogoutAll+1^%CSP.Session.1 *%request
 

And from a connected session with the user that needs to logout of all sessions:

ERROR #822: Access Denied
%SYS>

So I'll have to connect to the application as a developer in order to kill off sessions that are causing problems.  The user can't wipe them out himself.  I get a "problem session" if the page times out and the user kills the page; this causes the session to hang around until its timeout, and due to our specific setup, he can't log in again until the session times out or a developer kills it from Session Management. I wanted to give the user the ability to wipe out all of his own sessions.

No need to discuss grouping by sessionId or anything like that - we have a very specific setup such that flags are set and the user can't login again if he kills his page. 

Now, how can I intercept this error and call the logout? That would be better...

image of the kill page or wait fromChrome

Thanks,

Laura

Laura Cavanaugh · Nov 4, 2016 go to post

Ooh, fun, thanks.  Can I use it with %ListOfDataTypes too?  I have both returned from methods, and I need to use them in the %session array.  

Laura Cavanaugh · Nov 9, 2016 go to post

But the login page is already the Login page, which forces the user to authenticate first; it also go to the login page upon logout.

I tried this on some random web application; clicking on a bookmark brought me immediately to their login page; I didn't even have to login to get redirected.

Laura Cavanaugh · Nov 9, 2016 go to post

I need some kind of Authenticated flag to check, and if false, use OnPreHTTP to call %response.Redirect... 

Laura Cavanaugh · Jan 17, 2017 go to post

So, I created a new Role, called TaskAdmin.  To this role, I added 3 privs:

%Admin_Task

%DB_CACHESYS

%Development (so user could login to terminal)

I included the only tables I could find in %SYS that are relevant: 

%SYS_Task.Config

%SYS_Task.History

I added my own tables and views that use these tables.

To this role, I added a new user called task_admin, to test a query from the terminal.  i.e. I created a new user, task_admin, and added this single role.

This test user, task_admin, can run the SQL shell in the terminal and select * from %SYS_Task.History. (%SYS.Task is a different story!).  So, success.

In order for a real user to see my table, which is a mix of %SYS.Task, %SYS_Task.Histoy, and my own tables, and my own view based on those same tables, I had to add my own tables and views to the role TaskAdmin as well; but it did work finally work.

I also remembered seeing somewhere that embedded SQL  does not check SQL privs, which is maybe why I could see all this table data in the <tablePane> without adding tables. (?) I admit that the user looking at my table data did have %Admin_Task and %DB_CACHESYS privs already (from some role). But the user could not call a query/view that queried %SYS_Task.History directly until I added my own tables.

Yes, I really l mean that about the <tablePane>.  My user had the privs, but not the tables, and yet could see the data in a <tablePane>.  Is this included in embedded SQL?

So, basically I think I got it, and the real user needed my tables/view added to a role; the test user needed the %SYS tables added since he (it) was querying just the %SYS tables.

Thank you for your help!

Laura

Laura Cavanaugh · Feb 8, 2017 go to post

Ah, thank you.  While playing around with ^SECURITY, I had enabled all users EXCEPT UnknownUser (of course), and after checking out the auditing area of ^SECURITY (thanks for that tip), I saw that it was indeed UnknownUser that is trying to log into the management portal.

I did not know about that step, that the CSP gateway has to log in first to serve up a page.  What user is normally used for this?

Thanks,

Laura

Laura Cavanaugh · Feb 9, 2017 go to post

Hi All, Thanks for the help.  I learned a lot, and looked at our actual instances with a more critical eye.  I'll be recommending some changes on them.  I had installed the unlicensed version of 2016 on my computer just for fun, so there were no license issues (but that's something to keep in mind for our other instances).  I had installed 2016 with minimal security, then tried to increase the security to match our development instance.  That was actually successful; it was the disabling of all the other users that messed it up.

Thanks,

Laura

Laura Cavanaugh · Feb 15, 2017 go to post

Well, that helps.  Thanks.  I can't forsee any reason to make it more complicated, unless there is some huge benefit that I'm overlooking? Ah, I was thinking of changing the emails to a list of users, and getting their emails from the user table, so maybe that's a future benefit.

I extended the %Net.MailMessage for one object, and had such a pain of a time stuffing the To prooperty and retrieving it again (it's a list of %String). This time I was thinking a simple %String would be nice, as long as I can use it with SQL, and stuff.

Thanks,

Laura

Laura Cavanaugh · Mar 17, 2017 go to post

John, thanks for the response. I might ask this explicitly in the DC later, but I'll have to look at my notes before I do, as I'm sure I'll get some flak.  Just for informational purposes: we were instructed to restrict our users to a  single tab in our web application.  I know this is not how a web application is supposed to work (according to many users on google groups writing about this sort of thing), but the directive came from above.  I wrote simple logic to check if a user has a session already, and if so, he can't open a second tab. Sometimes, due to a bug, or timeouts on queries, the logic thinks the user has a second session when he does not.   At that point the user can't even log into the application. It's at this point that he'll have to call IT, who will have to call a developer, who can then kill his sessions manually from the management portal.  I was trying to give the users a way to "reset" or "clear" their own sessions (logging in first to a separate page perhaps) so that they can use the application again.  When I first began to look at this, I realized that most of this has to be done in the %SYS namespace; hence the problem, and its relavance to this question about changing their own password.

However, it hasn't been an issue (yet), so it's on my back burner. When it becomes an issue I'm sure I'll be back asing about it.

As always, thanks for the help.

Laura

Laura Cavanaugh · Mar 21, 2017 go to post

Can this be used in the System/Security Management/System-side Security Paramters "password pattern" at all?  I'm trying to find a way to match a user's password to something much more restrictive than "8 to 32 alpha, upper, lower, numeric, OR punctuation". I'd like to require at least one of a few kinds of characters (1 upper, 1 punctuation).  

I have a nice regex for this, but I'm not sure if I can use a regex, or this cool datatype, in the above mentioned System setting.  Any recommendations?

Laura Cavanaugh · May 12, 2017 go to post

And by the way I like the <pre> tag - nice touch.  Can we call ..EscapeHTML or does that require a license/connection?