Class ::nsmcp::FileCredentials (public)
::nx::Class ::nsmcp::FileCredentials
Defined in /usr/local/ns/tcl/nsmcp/lib/credentials.tcl
- Testcases:
- No testcase defined.
Source code: :property authenticator:required :property section:required :property store:required :variable mutex :method init {} {set :mutex [ns_mutex create]} :method names {} { set names [ns_config ${:section} credentials {}] if {[llength $names] != [llength [lsort -unique $names]]} {error "duplicate credential names"} foreach name $names { if {![regexp {^[A-Za-z0-9][A-Za-z0-9_.-]*$} $name]} {error "invalid symbolic credential name"} } return $names } :method prepare {name} { set section ${:section}/credential/$name set path [ns_config $section tokenFile {}] if {[file pathtype $path] ne "absolute" || ![file isfile $path] || ![file readable $path]} { error "credential $name requires a readable absolute tokenFile" } set principal [ns_config $section principal $name] set permissions [ns_config $section permissions {}] if {$principal eq ""} {error "credential $name requires a principal"} llength $permissions set expires [ns_config $section expires 0] if {![string is wideinteger -strict $expires] || ($expires != 0 && $expires <= [clock seconds])} { error "credential $name has an invalid or expired expiry" } set f [open $path rb] try {set raw [read $f 4097]} finally {close $f} if {[string length $raw] > 4096} {error "credential $name has an oversized token file"} set token [string trim $raw "\r\n"] if {[string length $token] < 32 || [string length $token] > 4096 || ![regexp {^[A-Za-z0-9._~+/-]+=*$} $token]} { error "credential $name has an invalid token file" } set digest [ns_crypto::md string -digest sha256 -- $token] return [dict create token $token digest $digest tokenFile $path principal $principal permissions $permissions targets [list [ns_info server]] expires $expires] } :method publish {name prepared} { ${:authenticator} grant [dict get $prepared token] [dict get $prepared principal] [dict get $prepared permissions] [dict get $prepared targets] [dict get $prepared expires] dict unset prepared token nsv_set ${:store} $name $prepared return $prepared } :public method loadAll {} { ns_mutex lock ${:mutex} try { # Validate every file/policy before changing any existing binding. set staged {}; set digests {} foreach name [:names] { set prepared [:prepare $name] set digest [dict get $prepared digest] if {[dict exists $digests $digest]} {error "configured credentials must use distinct tokens"} dict set digests $digest $name dict set staged $name $prepared } foreach name [nsv_array names ${:store}] { ${:authenticator} revoke [dict get [nsv_get ${:store} $name] digest] nsv_unset ${:store} $name } dict for {name prepared} $staged {:publish $name $prepared} return [:describeUnlocked] } finally {ns_mutex unlock ${:mutex}} } :public method load {name} { ns_mutex lock ${:mutex} try { if {$name ni [:names]} {error "unknown configured credential name"} set prepared [:prepare $name] foreach other [nsv_array names ${:store}] { if {$other ne $name && [dict get [nsv_get ${:store} $other] digest] eq [dict get $prepared digest]} { error "configured credentials must use distinct tokens" } } set previous {} if {[nsv_exists ${:store} $name]} {set previous [dict get [nsv_get ${:store} $name] digest]} set metadata [:publish $name $prepared] if {$previous ne "" && $previous ne [dict get $prepared digest]} {${:authenticator} revoke $previous} return $metadata } finally {ns_mutex unlock ${:mutex}} } :public method revoke {name} { ns_mutex lock ${:mutex} try { if {![nsv_exists ${:store} $name]} {error "unknown loaded credential name"} ${:authenticator} revoke [dict get [nsv_get ${:store} $name] digest] } finally {ns_mutex unlock ${:mutex}} } :method describeUnlocked {} { set result {} foreach name [lsort [nsv_array names ${:store}]] { set metadata [nsv_get ${:store} $name] set current [${:authenticator} credentialInfo [dict get $metadata digest]] set status revoked if {$current ne ""} { set status active if {[dict get $current expires] != 0 && [dict get $current expires] <= [clock seconds]} {set status expired} } dict set metadata status $status dict set result $name $metadata } return $result } :public method describe {} { ns_mutex lock ${:mutex} try {return [:describeUnlocked]} finally {ns_mutex unlock ${:mutex}} }XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)