go to post Eduard Lebedyuk · Feb 26, 2016 I stand somewhat corrected do $System.Process.Terminate() In %ZSTART(or ZAUTHENTICATE for that matter) does solve my problem. Seems like overkill, though. Really wanted just to return status.
go to post Eduard Lebedyuk · Feb 26, 2016 Exactly, what I want is two-factor authorisation but with my own authentication infrastructure for a second factor.
go to post Eduard Lebedyuk · Feb 26, 2016 Additional check is calling external device to provide rfid/biometric/whatever authentication on the user logged in to provide additional security level. Yes, application approach seems to be better.
go to post Eduard Lebedyuk · Feb 26, 2016 Tried both your suggestions, observed no change in authentication behaviour.
go to post Eduard Lebedyuk · Feb 24, 2016 I need to perform additional check during Cache user authorization. Is there any way to do that?
go to post Eduard Lebedyuk · Feb 24, 2016 How much does a standart 1-2cpu/1GB RAM/32Gb SSD virtual server with linux distro costs per month? I was unable to find it on their website.
go to post Eduard Lebedyuk · Feb 23, 2016 Great!RSS feed by tag works in Thunderbird. Main RSS feed still shows as invalid.Some thoughts about email integration:Replace the icon with a simple envelope icon - which is more recognizable. I can easily recognize the first three icons, but the last one I incorrectly accociate with msn logo After clicking on a "share via email bullton" I'm being redirected to a new page where I can send a message from communityportal@intersystems.com. I think you can raise convertion by using a simple mailto link (so default mail client pops up with a predefined topic and message instead of the new page) - so the person sharing the post can share from his own email account.
go to post Eduard Lebedyuk · Feb 21, 2016 1. They must be granted to either application or user 2. Only resources of Service, Application and User type could be used there. %DB are database resources 3. SMP -> Menu -> View Roles -> Choose the role "webapp-admin" -> General Tab -> Priveleges -> Add -> choose the resoure -> OK -> Save Repeat for webapp-user 4. Like this: Parameter RESOURCE = "ResourceName1:Permission,ResourceName2,ResourceName3:Permission"; Where Permission is one of: READ, WRITE, USE If Permission is skipped (see ResourceName2) then USE permission is checked.
go to post Eduard Lebedyuk · Feb 19, 2016 Here's an aggregation rss feed which combines the Community Portal RSS and InterSystems StackOverFlow RSS tags. It's available here and works with Thunderbird.
go to post Eduard Lebedyuk · Feb 19, 2016 Have you thought about uploading this projects on GitHub?UPD. Nevermind, seen your message about GitHub in another topic.
go to post Eduard Lebedyuk · Feb 19, 2016 If you paste table from somewhere else, when creating a post, sometimes borders may be undisplayed. To fix that switch into HTML view (via "Disable rich-text" button) and find the beginning of your table definition. It would look somewhat like that: <table class="confluenceTable"> And replace it with: <table border="1" cellpadding="1" cellspacing="1">
go to post Eduard Lebedyuk · Feb 18, 2016 I had a similar problem. The task was to write custom logging system, which would automatically store current method argument values. Here's how I done it. First the the persistent log class (relevant parts): Class App.Log Extends %Persistent { /// Replacement for missing values Parameter Null = "Null"; /// Type of event Property EventType As %String(MAXLEN = 10, VALUELIST = ",NONE,FATAL,ERROR,WARN,INFO,STAT,DEBUG,RAW") [ InitialExpression = "INFO" ]; /// Name of class, where event happened Property ClassName As %String(MAXLEN = 256); /// Name of method, where event happened Property MethodName As %String(MAXLEN = 128); /// Line of int code Property Source As %String(MAXLEN = 2000); /// Cache user Property UserName As %String(MAXLEN = 128) [ InitialExpression = {$Username} ]; /// Arguments' values passed to method Property Arguments As %String(MAXLEN = 32000, TRUNCATE = 1); /// Date and time Property TimeStamp As %TimeStamp [ InitialExpression = {$zdt($h, 3, 1)} ]; /// User message Property Message As %String(MAXLEN = 32000, TRUNCATE = 1); /// User IP address Property ClientIPAddress As %String(MAXLEN = 32) [ InitialExpression = {..GetClientAddress()} ]; /// Add new log event /// Use via $$$LogEventTYPE(). ClassMethod AddRecord(ClassName As %String = "", MethodName As %String = "", Source As %String = "", EventType As %String = "", Arguments As %String = "", Message As %String = "") { Set record = ..%New() Set record.Arguments = Arguments Set record.ClassName = ClassName Set record.EventType = EventType Set record.Message = Message Set record.MethodName = MethodName Set record.Source = Source Do record.%Save() } } And here's macros for client code: #define StackPlace $st($st(-1),"PLACE") #define CurrentClass ##Expression($$$quote(%classname)) #define CurrentMethod ##Expression($$$quote(%methodname)) #define MethodArguments ##Expression(##class(App.Log).GetMethodArguments(%classname,%methodname)) #define LogEvent(%type, %message) Do ##class(App.Log).AddRecord($$$CurrentClass,$$$CurrentMethod,$$$StackPlace,%type,$$$MethodArguments,%message) #define LogNone(%message) $$$LogEvent("NONE", %message) #define LogError(%message) $$$LogEvent("ERROR", %message) #define LogFatal(%message) $$$LogEvent("FATAL", %message) #define LogWarn(%message) $$$LogEvent("WARN", %message) #define LogInfo(%message) $$$LogEvent("INFO", %message) #define LogStat(%message) $$$LogEvent("STAT", %message) #define LogDebug(%message) $$$LogEvent("DEBUG", %message) #define LogRaw(%message) $$$LogEvent("RAW", %message) Now, how that works in client code? Let's say there is a class: Include App.LogMacro Class App.Use [ CompileAfter = App.Log ] { /// Do ##class(App.Use).Test() ClassMethod Test(a As %Integer = 1, ByRef b = 2) { $$$LogWarn("Message") } } In the int code, the $$$LogWarn macro would be transformed into: Do ##class(App.Log).AddRecord("App.Use","Test",$st($st(-1),"PLACE"),"WARN","a="_$g(a,"Null")_"; b="_$g(b,"Null")_";", "Message") And after execution a new record would be added to App.Log table (note, that the method was called with default params - if it was called with other values they would be saved, as this logging system gets arguments values at runtime): There is also some additional functionality, such as objects serializationinto json and context restoration at a later date, but that does not pertrain to the current discussion. Anyway, the main idea is that at compile time we have a macro that: Gets method arguments list from %Dictionary.CompiledMethodFor each argument decides on a strategy on how to get it's value at runtimeWrites source code that would implement value get at runtimeBuilds code to get all method arguments valuesInserts this code into method Relevant methods (in App.Log): /// Entry point to get method arguments string ClassMethod GetMethodArguments(ClassName As %String, MethodName As %String) As %String { Set list = ..GetMethodArgumentsList(ClassName,MethodName) Set string = ..ArgumentsListToString(list) Return string } /// Get a list of method arguments ClassMethod GetMethodArgumentsList(ClassName As %String, MethodName As %String) As %List { Set result = "" Set def = ##class(%Dictionary.CompiledMethod).%OpenId(ClassName _ "||" _ MethodName) If ($IsObject(def)) { Set result = def.FormalSpecParsed } Return result } /// Convert list of method arguments to string ClassMethod ArgumentsListToString(List As %List) As %String { Set result = "" For i=1:1:$ll(List) { Set result = result _ $$$quote($s(i>1=0:"",1:"; ") _ $lg($lg(List,i))_"=") _ ..GetArgumentValue($lg($lg(List,i)),$lg($lg(List,i),2)) _$S(i=$ll(List)=0:"",1:$$$quote(";")) } Return result } ClassMethod GetArgumentValue(Name As %String, ClassName As %Dictionary.CacheClassname) As %String { If $ClassMethod(ClassName, "%Extends", "%RegisteredObject") { // it's an object Return "_##class(App.Log).SerializeObject("_Name _ ")_" } Else { // it's a datatype Return "_$g(" _ Name _ ","_$$$quote(..#Null)_")_" } } The project is open-sourced and availible on GitHub (to use import all classes from App package into any namespace).
go to post Eduard Lebedyuk · Feb 17, 2016 I modified your code like this: Class test.DummyClass Extends %RegisteredObject { Property notanumber As %String; Property aboolean As %Boolean; /// do ##class(test.DummyClass).Test() ClassMethod Test() { set dummy = ..%New() set dummy.notanumber = "28001" set dummy.aboolean = 1 do ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(dummy,,,"aelotw") } } Terminal output: >do ##class(test.DummyClass).Test() { "notanumber":"28001", "aboolean":true }
go to post Eduard Lebedyuk · Feb 17, 2016 It can be done in 2016.1 FT, see this post. To do it in older versions, inherit from system classes. Alternatively you can define a persistent class with properties of required types and transform it into json. P.S. As a hack: JSON consumer can sometimes accept 1/0 in place of true/false, so you can try to use this values.
go to post Eduard Lebedyuk · Feb 16, 2016 Modify your query like this: SELECT COUNT(DISTINCT $EXTRACT(Criteria, 1, 490)) AS Relevance FROM HS_IHE_ATNA_Repository.Aggregation WHERE EventType = 'CROSS GATEWAY QUERY' Only symbols 1 to 490 would be used for comparison in DISTINCT condition, also see $EXTRACT docs.