activesp 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +25 -0
 - data/README.rdoc +105 -0
 - data/Rakefile +35 -6
 - data/VERSION +1 -1
 - data/lib/activesp.rb +27 -0
 - data/lib/activesp/associations.rb +76 -0
 - data/lib/activesp/base.rb +93 -7
 - data/lib/activesp/caching.rb +32 -3
 - data/lib/activesp/connection.rb +53 -16
 - data/lib/activesp/content_type.rb +50 -1
 - data/lib/activesp/field.rb +48 -2
 - data/lib/activesp/file.rb +71 -0
 - data/lib/activesp/folder.rb +72 -9
 - data/lib/activesp/ghost_field.rb +70 -1
 - data/lib/activesp/group.rb +46 -7
 - data/lib/activesp/item.rb +252 -23
 - data/lib/activesp/list.rb +284 -81
 - data/lib/activesp/permission_set.rb +39 -4
 - data/lib/activesp/persistent_caching.rb +61 -1
 - data/lib/activesp/role.rb +49 -8
 - data/lib/activesp/root.rb +67 -3
 - data/lib/activesp/site.rb +110 -20
 - data/lib/activesp/url.rb +27 -0
 - data/lib/activesp/user.rb +39 -1
 - data/lib/activesp/util.rb +198 -40
 - metadata +42 -16
 
| 
         @@ -1,3 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2010 XAOP bvba
         
     | 
| 
      
 2 
     | 
    
         
            +
            # 
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person
         
     | 
| 
      
 4 
     | 
    
         
            +
            # obtaining a copy of this software and associated documentation
         
     | 
| 
      
 5 
     | 
    
         
            +
            # files (the "Software"), to deal in the Software without
         
     | 
| 
      
 6 
     | 
    
         
            +
            # restriction, including without limitation the rights to use,
         
     | 
| 
      
 7 
     | 
    
         
            +
            # copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 8 
     | 
    
         
            +
            # copies of the Software, and to permit persons to whom the
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Software is furnished to do so, subject to the following
         
     | 
| 
      
 10 
     | 
    
         
            +
            # conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 13 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 16 
     | 
    
         
            +
            # 
         
     | 
| 
      
 17 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
         
     | 
| 
      
 18 
     | 
    
         
            +
            # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 19 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
         
     | 
| 
      
 20 
     | 
    
         
            +
            # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
         
     | 
| 
      
 21 
     | 
    
         
            +
            # 
         
     | 
| 
      
 22 
     | 
    
         
            +
            # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
         
     | 
| 
      
 23 
     | 
    
         
            +
            # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
         
     | 
| 
      
 24 
     | 
    
         
            +
            # OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       1 
26 
     | 
    
         
             
            module ActiveSP
         
     | 
| 
       2 
27 
     | 
    
         | 
| 
       3 
28 
     | 
    
         
             
              class PermissionSet
         
     | 
| 
         @@ -6,22 +31,32 @@ module ActiveSP 
     | 
|
| 
       6 
31 
     | 
    
         | 
| 
       7 
32 
     | 
    
         
             
                attr_reader :scope
         
     | 
| 
       8 
33 
     | 
    
         | 
| 
      
 34 
     | 
    
         
            +
                # @private
         
     | 
| 
       9 
35 
     | 
    
         
             
                def initialize(scope)
         
     | 
| 
       10 
36 
     | 
    
         
             
                  @scope = scope
         
     | 
| 
       11 
37 
     | 
    
         
             
                end
         
     | 
| 
       12 
38 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                 
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                end
         
     | 
| 
       16 
     | 
    
         
            -
                
         
     | 
| 
      
 39 
     | 
    
         
            +
                # See {Base#key}
         
     | 
| 
      
 40 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
       17 
41 
     | 
    
         
             
                def key
         
     | 
| 
       18 
42 
     | 
    
         
             
                  encode_key("P", [@scope.key])
         
     | 
| 
       19 
43 
     | 
    
         
             
                end
         
     | 
| 
       20 
44 
     | 
    
         | 
| 
      
 45 
     | 
    
         
            +
                # Returns the permissions in this permission set as an array of hashes with :accessor mapping to a user,
         
     | 
| 
      
 46 
     | 
    
         
            +
                # group or role and :mask mapping to the permission as an integer
         
     | 
| 
      
 47 
     | 
    
         
            +
                # @return [Array<Hash{:accessor, :permission => User, Group, Role, Integer}>]
         
     | 
| 
      
 48 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 49 
     | 
    
         
            +
                #   set.permissions #=> [{:accessor=>#<ActiveSP::User login_name=SHAREPOINT\system>, :mask=>134287360}]
         
     | 
| 
      
 50 
     | 
    
         
            +
                def permissions
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @scope.send(:permissions)
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
                
         
     | 
| 
      
 54 
     | 
    
         
            +
                # @private
         
     | 
| 
       21 
55 
     | 
    
         
             
                def to_s
         
     | 
| 
       22 
56 
     | 
    
         
             
                  "#<ActiveSP::PermissionSet scope=#{@scope}>"
         
     | 
| 
       23 
57 
     | 
    
         
             
                end
         
     | 
| 
       24 
58 
     | 
    
         | 
| 
      
 59 
     | 
    
         
            +
                # @private
         
     | 
| 
       25 
60 
     | 
    
         
             
                alias inspect to_s
         
     | 
| 
       26 
61 
     | 
    
         | 
| 
       27 
62 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1,7 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2010 XAOP bvba
         
     | 
| 
      
 2 
     | 
    
         
            +
            # 
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person
         
     | 
| 
      
 4 
     | 
    
         
            +
            # obtaining a copy of this software and associated documentation
         
     | 
| 
      
 5 
     | 
    
         
            +
            # files (the "Software"), to deal in the Software without
         
     | 
| 
      
 6 
     | 
    
         
            +
            # restriction, including without limitation the rights to use,
         
     | 
| 
      
 7 
     | 
    
         
            +
            # copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 8 
     | 
    
         
            +
            # copies of the Software, and to permit persons to whom the
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Software is furnished to do so, subject to the following
         
     | 
| 
      
 10 
     | 
    
         
            +
            # conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 13 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 16 
     | 
    
         
            +
            # 
         
     | 
| 
      
 17 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
         
     | 
| 
      
 18 
     | 
    
         
            +
            # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 19 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
         
     | 
| 
      
 20 
     | 
    
         
            +
            # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
         
     | 
| 
      
 21 
     | 
    
         
            +
            # 
         
     | 
| 
      
 22 
     | 
    
         
            +
            # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
         
     | 
| 
      
 23 
     | 
    
         
            +
            # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
         
     | 
| 
      
 24 
     | 
    
         
            +
            # OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       1 
26 
     | 
    
         
             
            module ActiveSP
         
     | 
| 
       2 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
              # @private
         
     | 
| 
       3 
29 
     | 
    
         
             
              module PersistentCaching
         
     | 
| 
       4 
30 
     | 
    
         | 
| 
      
 31 
     | 
    
         
            +
              private
         
     | 
| 
      
 32 
     | 
    
         
            +
                
         
     | 
| 
       5 
33 
     | 
    
         
             
                def persistent(&blk)
         
     | 
| 
       6 
34 
     | 
    
         
             
                  class << self ; self ; end.instance_eval do
         
     | 
| 
       7 
35 
     | 
    
         
             
                    alias_method :old_new, :new
         
     | 
| 
         @@ -18,6 +46,7 @@ module ActiveSP 
     | 
|
| 
       18 
46 
     | 
    
         | 
| 
       19 
47 
     | 
    
         
             
              end
         
     | 
| 
       20 
48 
     | 
    
         | 
| 
      
 49 
     | 
    
         
            +
              # @private
         
     | 
| 
       21 
50 
     | 
    
         
             
              class PersistentCache
         
     | 
| 
       22 
51 
     | 
    
         | 
| 
       23 
52 
     | 
    
         
             
                def initialize
         
     | 
| 
         @@ -38,11 +67,42 @@ module ActiveSP 
     | 
|
| 
       38 
67 
     | 
    
         | 
| 
       39 
68 
     | 
    
         
             
              module PersistentCachingConfig
         
     | 
| 
       40 
69 
     | 
    
         | 
| 
      
 70 
     | 
    
         
            +
                # Configures the scope of the persistent cache. The default scope of the cache
         
     | 
| 
      
 71 
     | 
    
         
            +
                # is the {Connection} object, i.e., each connection has its own cache. For example
         
     | 
| 
      
 72 
     | 
    
         
            +
                # you can use this to make thread local caches. Note that the cache is not actually
         
     | 
| 
      
 73 
     | 
    
         
            +
                # thread safe at this point so this may not be such a bad idea.
         
     | 
| 
      
 74 
     | 
    
         
            +
                #
         
     | 
| 
      
 75 
     | 
    
         
            +
                # Caching in ActiveSP at the moment is very aggressive. What this means that everything
         
     | 
| 
      
 76 
     | 
    
         
            +
                # you ever accessed will be cached. You can override the cache for a particular object
         
     | 
| 
      
 77 
     | 
    
         
            +
                # by calling {Base#reload} on it. One advantage of this caching strategy is that every time
         
     | 
| 
      
 78 
     | 
    
         
            +
                # you access an object in SharePoint, it is guaranteed to be the same object in Ruby as
         
     | 
| 
      
 79 
     | 
    
         
            +
                # well, irrespective of how you obtained a reference to that object. This eliminates a
         
     | 
| 
      
 80 
     | 
    
         
            +
                # whole slew of issues, but you need to be aware of this.
         
     | 
| 
      
 81 
     | 
    
         
            +
                #
         
     | 
| 
      
 82 
     | 
    
         
            +
                # This method expects a block to which a new cache object is passed. The idea is that
         
     | 
| 
      
 83 
     | 
    
         
            +
                # you store this cache object in a place that reflects the scope of your cache. If you
         
     | 
| 
      
 84 
     | 
    
         
            +
                # already had a cache object stored for you current scope, you do not do anything with
         
     | 
| 
      
 85 
     | 
    
         
            +
                # the cache object. The cache object that the block returns is the cache that will be used.
         
     | 
| 
      
 86 
     | 
    
         
            +
                # Note that the block is called everytime ActiveSP needs the cache, so make it as
         
     | 
| 
      
 87 
     | 
    
         
            +
                # efficient as possible. The example below illustrates how you can use the ||= operator
         
     | 
| 
      
 88 
     | 
    
         
            +
                # for this to get a thread local cache.
         
     | 
| 
      
 89 
     | 
    
         
            +
                #
         
     | 
| 
      
 90 
     | 
    
         
            +
                # You can use this block to return a cache of your own. A cache is only expected to have
         
     | 
| 
      
 91 
     | 
    
         
            +
                # a lookup method to which the cache key is passed (do not assume it is an integer or a
         
     | 
| 
      
 92 
     | 
    
         
            +
                # string because it is not) as parameter and is expected to return the value for that
         
     | 
| 
      
 93 
     | 
    
         
            +
                # key. In case of a cache miss, the method should yield to retrieve the value, store it
         
     | 
| 
      
 94 
     | 
    
         
            +
                # with the given key and return the value. You can use this to plug in a cache that has
         
     | 
| 
      
 95 
     | 
    
         
            +
                # a limited size, or that uses weak references to clean up the cache. The latter suggestion
         
     | 
| 
      
 96 
     | 
    
         
            +
                # is a lot safer than the former!
         
     | 
| 
      
 97 
     | 
    
         
            +
                #
         
     | 
| 
      
 98 
     | 
    
         
            +
                # @example How to configure caching strategy
         
     | 
| 
      
 99 
     | 
    
         
            +
                #   c = ActiveSP::Connection.new(:login => l, :password => p, :root => r)
         
     | 
| 
      
 100 
     | 
    
         
            +
                #   c.configure_persistent_cache { |cache| Thread.current[:sp_cache] ||= cache }
         
     | 
| 
       41 
101 
     | 
    
         
             
                def configure_persistent_cache(&blk)
         
     | 
| 
       42 
102 
     | 
    
         
             
                  @last_persistent_cache_object = PersistentCache.new
         
     | 
| 
       43 
103 
     | 
    
         
             
                  class << self ; self ; end.send(:define_method, :persistent_cache) do
         
     | 
| 
       44 
104 
     | 
    
         
             
                    cache = blk.call(@last_persistent_cache_object)
         
     | 
| 
       45 
     | 
    
         
            -
                    @last_persistent_cache_object = PersistentCache.new  
     | 
| 
      
 105 
     | 
    
         
            +
                    @last_persistent_cache_object = PersistentCache.new if cache == @last_persistent_cache_object
         
     | 
| 
       46 
106 
     | 
    
         
             
                    cache
         
     | 
| 
       47 
107 
     | 
    
         
             
                  end
         
     | 
| 
       48 
108 
     | 
    
         
             
                end
         
     | 
    
        data/lib/activesp/role.rb
    CHANGED
    
    | 
         @@ -1,3 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2010 XAOP bvba
         
     | 
| 
      
 2 
     | 
    
         
            +
            # 
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person
         
     | 
| 
      
 4 
     | 
    
         
            +
            # obtaining a copy of this software and associated documentation
         
     | 
| 
      
 5 
     | 
    
         
            +
            # files (the "Software"), to deal in the Software without
         
     | 
| 
      
 6 
     | 
    
         
            +
            # restriction, including without limitation the rights to use,
         
     | 
| 
      
 7 
     | 
    
         
            +
            # copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 8 
     | 
    
         
            +
            # copies of the Software, and to permit persons to whom the
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Software is furnished to do so, subject to the following
         
     | 
| 
      
 10 
     | 
    
         
            +
            # conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 13 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 16 
     | 
    
         
            +
            # 
         
     | 
| 
      
 17 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
         
     | 
| 
      
 18 
     | 
    
         
            +
            # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 19 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
         
     | 
| 
      
 20 
     | 
    
         
            +
            # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
         
     | 
| 
      
 21 
     | 
    
         
            +
            # 
         
     | 
| 
      
 22 
     | 
    
         
            +
            # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
         
     | 
| 
      
 23 
     | 
    
         
            +
            # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
         
     | 
| 
      
 24 
     | 
    
         
            +
            # OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       1 
26 
     | 
    
         
             
            module ActiveSP
         
     | 
| 
       2 
27 
     | 
    
         | 
| 
       3 
28 
     | 
    
         
             
              class Role < Base
         
     | 
| 
         @@ -7,43 +32,59 @@ module ActiveSP 
     | 
|
| 
       7 
32 
     | 
    
         
             
                include Util
         
     | 
| 
       8 
33 
     | 
    
         
             
                include InSite
         
     | 
| 
       9 
34 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                attr_reader :name
         
     | 
| 
       11 
     | 
    
         
            -
                
         
     | 
| 
       12 
35 
     | 
    
         
             
                persistent { |site, name, *a| [site.connection, [:role, name]] }
         
     | 
| 
      
 36 
     | 
    
         
            +
                # @private
         
     | 
| 
       13 
37 
     | 
    
         
             
                def initialize(site, name)
         
     | 
| 
       14 
38 
     | 
    
         
             
                  @site, @name = site, name
         
     | 
| 
       15 
39 
     | 
    
         
             
                end
         
     | 
| 
       16 
40 
     | 
    
         | 
| 
      
 41 
     | 
    
         
            +
                # See {Base#key}
         
     | 
| 
      
 42 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
       17 
43 
     | 
    
         
             
                def key
         
     | 
| 
       18 
44 
     | 
    
         
             
                  encode_key("R", [@name])
         
     | 
| 
       19 
45 
     | 
    
         
             
                end
         
     | 
| 
       20 
46 
     | 
    
         | 
| 
      
 47 
     | 
    
         
            +
                # Returns the list of users in this role
         
     | 
| 
      
 48 
     | 
    
         
            +
                # @return [User]
         
     | 
| 
       21 
49 
     | 
    
         
             
                def users
         
     | 
| 
       22 
50 
     | 
    
         
             
                  call("UserGroup", "get_user_collection_from_role", "roleName" => @name).xpath("//spdir:User", NS).map do |row|
         
     | 
| 
       23 
51 
     | 
    
         
             
                    attributes = clean_attributes(row.attributes)
         
     | 
| 
       24 
52 
     | 
    
         
             
                    User.new(@site, attributes["LoginName"])
         
     | 
| 
       25 
53 
     | 
    
         
             
                  end
         
     | 
| 
       26 
54 
     | 
    
         
             
                end
         
     | 
| 
       27 
     | 
    
         
            -
                cache :users, :dup =>  
     | 
| 
      
 55 
     | 
    
         
            +
                cache :users, :dup => :always
         
     | 
| 
       28 
56 
     | 
    
         | 
| 
      
 57 
     | 
    
         
            +
                # Returns the list of groups in this role
         
     | 
| 
      
 58 
     | 
    
         
            +
                # @return [Group]
         
     | 
| 
       29 
59 
     | 
    
         
             
                def groups
         
     | 
| 
       30 
60 
     | 
    
         
             
                  call("UserGroup", "get_group_collection_from_role", "roleName" => @name).xpath("//spdir:Group", NS).map do |row|
         
     | 
| 
       31 
61 
     | 
    
         
             
                    attributes = clean_attributes(row.attributes)
         
     | 
| 
       32 
62 
     | 
    
         
             
                    Group.new(@site, attributes["Name"])
         
     | 
| 
       33 
63 
     | 
    
         
             
                  end
         
     | 
| 
       34 
64 
     | 
    
         
             
                end
         
     | 
| 
       35 
     | 
    
         
            -
                cache :groups, :dup =>  
     | 
| 
      
 65 
     | 
    
         
            +
                cache :groups, :dup => :always
         
     | 
| 
      
 66 
     | 
    
         
            +
                
         
     | 
| 
      
 67 
     | 
    
         
            +
                # Returns true. The same method is present on {Group} where it returns false. Roles and groups can generally be
         
     | 
| 
      
 68 
     | 
    
         
            +
                # duck-typed, and this method is there for the rare case where you do need to make the distinction
         
     | 
| 
      
 69 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 70 
     | 
    
         
            +
                def is_role?
         
     | 
| 
      
 71 
     | 
    
         
            +
                  true
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
       36 
73 
     | 
    
         | 
| 
      
 74 
     | 
    
         
            +
                # See {Base#save}
         
     | 
| 
      
 75 
     | 
    
         
            +
                # @return [void]
         
     | 
| 
      
 76 
     | 
    
         
            +
                def save
         
     | 
| 
      
 77 
     | 
    
         
            +
                  p untype_cast_attributes(@site, nil, internal_attribute_types, changed_attributes)
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
                
         
     | 
| 
      
 80 
     | 
    
         
            +
                # @private
         
     | 
| 
       37 
81 
     | 
    
         
             
                def to_s
         
     | 
| 
       38 
82 
     | 
    
         
             
                  "#<ActiveSP::Role name=#{@name}>"
         
     | 
| 
       39 
83 
     | 
    
         
             
                end
         
     | 
| 
       40 
84 
     | 
    
         | 
| 
      
 85 
     | 
    
         
            +
                # @private
         
     | 
| 
       41 
86 
     | 
    
         
             
                alias inspect to_s
         
     | 
| 
       42 
87 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                def is_role?
         
     | 
| 
       44 
     | 
    
         
            -
                  true
         
     | 
| 
       45 
     | 
    
         
            -
                end
         
     | 
| 
       46 
     | 
    
         
            -
                
         
     | 
| 
       47 
88 
     | 
    
         
             
              private
         
     | 
| 
       48 
89 
     | 
    
         | 
| 
       49 
90 
     | 
    
         
             
                def data
         
     | 
    
        data/lib/activesp/root.rb
    CHANGED
    
    | 
         @@ -1,5 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2010 XAOP bvba
         
     | 
| 
      
 2 
     | 
    
         
            +
            # 
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person
         
     | 
| 
      
 4 
     | 
    
         
            +
            # obtaining a copy of this software and associated documentation
         
     | 
| 
      
 5 
     | 
    
         
            +
            # files (the "Software"), to deal in the Software without
         
     | 
| 
      
 6 
     | 
    
         
            +
            # restriction, including without limitation the rights to use,
         
     | 
| 
      
 7 
     | 
    
         
            +
            # copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 8 
     | 
    
         
            +
            # copies of the Software, and to permit persons to whom the
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Software is furnished to do so, subject to the following
         
     | 
| 
      
 10 
     | 
    
         
            +
            # conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 13 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 16 
     | 
    
         
            +
            # 
         
     | 
| 
      
 17 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
         
     | 
| 
      
 18 
     | 
    
         
            +
            # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 19 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
         
     | 
| 
      
 20 
     | 
    
         
            +
            # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
         
     | 
| 
      
 21 
     | 
    
         
            +
            # 
         
     | 
| 
      
 22 
     | 
    
         
            +
            # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
         
     | 
| 
      
 23 
     | 
    
         
            +
            # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
         
     | 
| 
      
 24 
     | 
    
         
            +
            # OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       1 
26 
     | 
    
         
             
            module ActiveSP
         
     | 
| 
       2 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
              # @private
         
     | 
| 
       3 
29 
     | 
    
         
             
              NS = {
         
     | 
| 
       4 
30 
     | 
    
         
             
                "sp" => "http://schemas.microsoft.com/sharepoint/soap/",
         
     | 
| 
       5 
31 
     | 
    
         
             
                "z" => "#RowsetSchema",
         
     | 
| 
         @@ -10,34 +36,71 @@ module ActiveSP 
     | 
|
| 
       10 
36 
     | 
    
         | 
| 
       11 
37 
     | 
    
         
             
                extend Caching
         
     | 
| 
       12 
38 
     | 
    
         | 
| 
      
 39 
     | 
    
         
            +
                # Returns the root site as an object of class {Site}
         
     | 
| 
      
 40 
     | 
    
         
            +
                # @return [Site]
         
     | 
| 
       13 
41 
     | 
    
         
             
                def root
         
     | 
| 
       14 
42 
     | 
    
         
             
                  Site.new(self, @root_url)
         
     | 
| 
       15 
43 
     | 
    
         
             
                end
         
     | 
| 
       16 
44 
     | 
    
         
             
                cache :root
         
     | 
| 
       17 
45 
     | 
    
         | 
| 
      
 46 
     | 
    
         
            +
                # Returns the list of users in the system
         
     | 
| 
      
 47 
     | 
    
         
            +
                # @return [Array<User>]
         
     | 
| 
       18 
48 
     | 
    
         
             
                def users
         
     | 
| 
       19 
49 
     | 
    
         
             
                  root.send(:call, "UserGroup", "get_user_collection_from_site").xpath("//spdir:User", NS).map do |row|
         
     | 
| 
       20 
50 
     | 
    
         
             
                    attributes = clean_attributes(row.attributes)
         
     | 
| 
       21 
51 
     | 
    
         
             
                    User.new(root, attributes["LoginName"])
         
     | 
| 
       22 
52 
     | 
    
         
             
                  end
         
     | 
| 
       23 
53 
     | 
    
         
             
                end
         
     | 
| 
       24 
     | 
    
         
            -
                cache :users, :dup =>  
     | 
| 
      
 54 
     | 
    
         
            +
                cache :users, :dup => :always
         
     | 
| 
       25 
55 
     | 
    
         | 
| 
      
 56 
     | 
    
         
            +
                # Returns the user with the given login, or nil when the user does not exist
         
     | 
| 
      
 57 
     | 
    
         
            +
                # @param [String] login The login of the user
         
     | 
| 
      
 58 
     | 
    
         
            +
                # @return [User, nil]
         
     | 
| 
      
 59 
     | 
    
         
            +
                def user(login)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  if user = users_by_login[login]
         
     | 
| 
      
 61 
     | 
    
         
            +
                    user
         
     | 
| 
      
 62 
     | 
    
         
            +
                  elsif data = root.send(:call, "UserGroup", "get_user_info", "userLoginName" => login).xpath("//spdir:User", NS).first
         
     | 
| 
      
 63 
     | 
    
         
            +
                    users_by_login[login] = User.new(root, login, clean_attributes(data))
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
                
         
     | 
| 
      
 67 
     | 
    
         
            +
                # Returns the list of groups in the system
         
     | 
| 
      
 68 
     | 
    
         
            +
                # @return [Array<Group>]
         
     | 
| 
       26 
69 
     | 
    
         
             
                def groups
         
     | 
| 
       27 
70 
     | 
    
         
             
                  root.send(:call, "UserGroup", "get_group_collection_from_site").xpath("//spdir:Group", NS).map do |row|
         
     | 
| 
       28 
71 
     | 
    
         
             
                    attributes = clean_attributes(row.attributes)
         
     | 
| 
       29 
72 
     | 
    
         
             
                    Group.new(root, attributes["Name"])
         
     | 
| 
       30 
73 
     | 
    
         
             
                  end
         
     | 
| 
       31 
74 
     | 
    
         
             
                end
         
     | 
| 
       32 
     | 
    
         
            -
                cache :groups, :dup =>  
     | 
| 
      
 75 
     | 
    
         
            +
                cache :groups, :dup => :always
         
     | 
| 
      
 76 
     | 
    
         
            +
                
         
     | 
| 
      
 77 
     | 
    
         
            +
                def group(name)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  if group = groups_by_name[name]
         
     | 
| 
      
 79 
     | 
    
         
            +
                    group
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
       33 
82 
     | 
    
         | 
| 
      
 83 
     | 
    
         
            +
                # Returns the list of roles in the system
         
     | 
| 
      
 84 
     | 
    
         
            +
                # @return [Array<Role>]
         
     | 
| 
       34 
85 
     | 
    
         
             
                def roles
         
     | 
| 
       35 
86 
     | 
    
         
             
                  root.send(:call, "UserGroup", "get_role_collection_from_web").xpath("//spdir:Role", NS).map do |row|
         
     | 
| 
       36 
87 
     | 
    
         
             
                    attributes = clean_attributes(row.attributes)
         
     | 
| 
       37 
88 
     | 
    
         
             
                    Role.new(root, attributes["Name"])
         
     | 
| 
       38 
89 
     | 
    
         
             
                  end
         
     | 
| 
       39 
90 
     | 
    
         
             
                end
         
     | 
| 
       40 
     | 
    
         
            -
                cache :roles, :dup =>  
     | 
| 
      
 91 
     | 
    
         
            +
                cache :roles, :dup => :always
         
     | 
| 
      
 92 
     | 
    
         
            +
                
         
     | 
| 
      
 93 
     | 
    
         
            +
              private
         
     | 
| 
      
 94 
     | 
    
         
            +
                
         
     | 
| 
      
 95 
     | 
    
         
            +
                def users_by_login
         
     | 
| 
      
 96 
     | 
    
         
            +
                  users.inject({}) { |h, u| h[u.login_name] = u ; h }
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
                cache :users_by_login
         
     | 
| 
      
 99 
     | 
    
         
            +
                
         
     | 
| 
      
 100 
     | 
    
         
            +
                def groups_by_name
         
     | 
| 
      
 101 
     | 
    
         
            +
                  groups.inject({}) { |h, g| h[g.Name] = g ; h }
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
                cache :groups_by_name
         
     | 
| 
       41 
104 
     | 
    
         | 
| 
       42 
105 
     | 
    
         
             
              end
         
     | 
| 
       43 
106 
     | 
    
         | 
| 
         @@ -47,6 +110,7 @@ module ActiveSP 
     | 
|
| 
       47 
110 
     | 
    
         | 
| 
       48 
111 
     | 
    
         
             
              end
         
     | 
| 
       49 
112 
     | 
    
         | 
| 
      
 113 
     | 
    
         
            +
              # @private
         
     | 
| 
       50 
114 
     | 
    
         
             
              module InSite
         
     | 
| 
       51 
115 
     | 
    
         | 
| 
       52 
116 
     | 
    
         
             
              private
         
     | 
    
        data/lib/activesp/site.rb
    CHANGED
    
    | 
         @@ -1,3 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2010 XAOP bvba
         
     | 
| 
      
 2 
     | 
    
         
            +
            # 
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person
         
     | 
| 
      
 4 
     | 
    
         
            +
            # obtaining a copy of this software and associated documentation
         
     | 
| 
      
 5 
     | 
    
         
            +
            # files (the "Software"), to deal in the Software without
         
     | 
| 
      
 6 
     | 
    
         
            +
            # restriction, including without limitation the rights to use,
         
     | 
| 
      
 7 
     | 
    
         
            +
            # copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 8 
     | 
    
         
            +
            # copies of the Software, and to permit persons to whom the
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Software is furnished to do so, subject to the following
         
     | 
| 
      
 10 
     | 
    
         
            +
            # conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            # 
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 13 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 16 
     | 
    
         
            +
            # 
         
     | 
| 
      
 17 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
         
     | 
| 
      
 18 
     | 
    
         
            +
            # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 19 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
         
     | 
| 
      
 20 
     | 
    
         
            +
            # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
         
     | 
| 
      
 21 
     | 
    
         
            +
            # 
         
     | 
| 
      
 22 
     | 
    
         
            +
            # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
         
     | 
| 
      
 23 
     | 
    
         
            +
            # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
         
     | 
| 
      
 24 
     | 
    
         
            +
            # OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       1 
26 
     | 
    
         
             
            module ActiveSP
         
     | 
| 
       2 
27 
     | 
    
         | 
| 
       3 
28 
     | 
    
         
             
              class Site < Base
         
     | 
| 
         @@ -6,51 +31,73 @@ module ActiveSP 
     | 
|
| 
       6 
31 
     | 
    
         
             
                extend PersistentCaching
         
     | 
| 
       7 
32 
     | 
    
         
             
                include Util
         
     | 
| 
       8 
33 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
      
 34 
     | 
    
         
            +
                # The URL of this site
         
     | 
| 
      
 35 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 36 
     | 
    
         
            +
                attr_reader :url
         
     | 
| 
      
 37 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 38 
     | 
    
         
            +
                attr_reader :connection
         
     | 
| 
       10 
39 
     | 
    
         | 
| 
       11 
40 
     | 
    
         
             
                persistent { |connection, url, *a| [connection, [:site, url]] }
         
     | 
| 
      
 41 
     | 
    
         
            +
                # @private
         
     | 
| 
       12 
42 
     | 
    
         
             
                def initialize(connection, url, depth = 0)
         
     | 
| 
       13 
43 
     | 
    
         
             
                  @connection, @url, @depth = connection, url, depth
         
     | 
| 
       14 
44 
     | 
    
         
             
                  @services = {}
         
     | 
| 
       15 
45 
     | 
    
         
             
                end
         
     | 
| 
       16 
46 
     | 
    
         | 
| 
      
 47 
     | 
    
         
            +
                # @private
         
     | 
| 
       17 
48 
     | 
    
         
             
                def relative_url(url = @url)
         
     | 
| 
       18 
49 
     | 
    
         
             
                  url[@connection.root_url.rindex("/") + 1..-1]
         
     | 
| 
       19 
50 
     | 
    
         
             
                end
         
     | 
| 
       20 
51 
     | 
    
         | 
| 
      
 52 
     | 
    
         
            +
                # Returns the containing site, or nil if this is the root site
         
     | 
| 
      
 53 
     | 
    
         
            +
                # @return [Site]
         
     | 
| 
       21 
54 
     | 
    
         
             
                def supersite
         
     | 
| 
       22 
     | 
    
         
            -
                   
     | 
| 
       23 
     | 
    
         
            -
                    Site.new(@connection, File.dirname(@url), @depth - 1)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  unless is_root_site?
         
     | 
| 
      
 56 
     | 
    
         
            +
                    Site.new(@connection, ::File.dirname(@url), @depth - 1)
         
     | 
| 
       24 
57 
     | 
    
         
             
                  end
         
     | 
| 
       25 
58 
     | 
    
         
             
                end
         
     | 
| 
       26 
59 
     | 
    
         
             
                cache :supersite
         
     | 
| 
       27 
60 
     | 
    
         | 
| 
      
 61 
     | 
    
         
            +
                # Returns the root site, or this site if it is the root site
         
     | 
| 
      
 62 
     | 
    
         
            +
                # @return [Site]
         
     | 
| 
       28 
63 
     | 
    
         
             
                def rootsite
         
     | 
| 
       29 
     | 
    
         
            -
                   
     | 
| 
      
 64 
     | 
    
         
            +
                  is_root_site? ? self : supersite.rootsite
         
     | 
| 
       30 
65 
     | 
    
         
             
                end
         
     | 
| 
       31 
66 
     | 
    
         
             
                cache :rootsite
         
     | 
| 
       32 
67 
     | 
    
         | 
| 
      
 68 
     | 
    
         
            +
                # Returns true if this site is the root site
         
     | 
| 
      
 69 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
       33 
70 
     | 
    
         
             
                def is_root_site?
         
     | 
| 
       34 
71 
     | 
    
         
             
                  @depth == 0
         
     | 
| 
       35 
72 
     | 
    
         
             
                end
         
     | 
| 
       36 
73 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                 
     | 
| 
      
 74 
     | 
    
         
            +
                # See {Base#key}
         
     | 
| 
      
 75 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 76 
     | 
    
         
            +
                def key # This documentation is not ideal. The ideal doesn't work out of the box
         
     | 
| 
       38 
77 
     | 
    
         
             
                  encode_key("S", [@url[@connection.root_url.length + 1..-1], @depth])
         
     | 
| 
       39 
78 
     | 
    
         
             
                end
         
     | 
| 
       40 
79 
     | 
    
         | 
| 
      
 80 
     | 
    
         
            +
                # Returns the list of sites below this site. Does not recurse
         
     | 
| 
      
 81 
     | 
    
         
            +
                # @return [Array<List>]
         
     | 
| 
       41 
82 
     | 
    
         
             
                def sites
         
     | 
| 
       42 
83 
     | 
    
         
             
                  result = call("Webs", "get_web_collection")
         
     | 
| 
       43 
84 
     | 
    
         
             
                  result.xpath("//sp:Web", NS).map { |web| Site.new(connection, web["Url"].to_s, @depth + 1) }
         
     | 
| 
       44 
85 
     | 
    
         
             
                end
         
     | 
| 
       45 
     | 
    
         
            -
                cache :sites, :dup =>  
     | 
| 
      
 86 
     | 
    
         
            +
                cache :sites, :dup => :always
         
     | 
| 
       46 
87 
     | 
    
         | 
| 
      
 88 
     | 
    
         
            +
                # Returns the site with the given name. This name is what appears in the URL as name and is immutable. Return nil
         
     | 
| 
      
 89 
     | 
    
         
            +
                # if such a site does not exist
         
     | 
| 
      
 90 
     | 
    
         
            +
                # @param [String] name The name if the site
         
     | 
| 
      
 91 
     | 
    
         
            +
                # @return [Site]
         
     | 
| 
       47 
92 
     | 
    
         
             
                def site(name)
         
     | 
| 
       48 
     | 
    
         
            -
                  result = call("Webs", "get_web", "webUrl" => File.join(@url, name))
         
     | 
| 
      
 93 
     | 
    
         
            +
                  result = call("Webs", "get_web", "webUrl" => ::File.join(@url, name))
         
     | 
| 
       49 
94 
     | 
    
         
             
                  Site.new(connection, result.xpath("//sp:Web", NS).first["Url"].to_s, @depth + 1)
         
     | 
| 
       50 
95 
     | 
    
         
             
                rescue Savon::SOAPFault
         
     | 
| 
       51 
96 
     | 
    
         
             
                  nil
         
     | 
| 
       52 
97 
     | 
    
         
             
                end
         
     | 
| 
       53 
98 
     | 
    
         | 
| 
      
 99 
     | 
    
         
            +
                # Returns the list if lists in this sute. Does not recurse
         
     | 
| 
      
 100 
     | 
    
         
            +
                # @return [Array<List>]
         
     | 
| 
       54 
101 
     | 
    
         
             
                def lists
         
     | 
| 
       55 
102 
     | 
    
         
             
                  result1 = call("Lists", "get_list_collection")
         
     | 
| 
       56 
103 
     | 
    
         
             
                  result2 = call("SiteData", "get_list_collection")
         
     | 
| 
         @@ -66,28 +113,42 @@ module ActiveSP 
     | 
|
| 
       66 
113 
     | 
    
         
             
                    List.new(self, list["ID"].to_s, list["Title"].to_s, clean_attributes(list.attributes), result2_by_id[list["ID"].to_s])
         
     | 
| 
       67 
114 
     | 
    
         
             
                  end
         
     | 
| 
       68 
115 
     | 
    
         
             
                end
         
     | 
| 
       69 
     | 
    
         
            -
                cache :lists, :dup =>  
     | 
| 
      
 116 
     | 
    
         
            +
                cache :lists, :dup => :always
         
     | 
| 
       70 
117 
     | 
    
         | 
| 
      
 118 
     | 
    
         
            +
                # Returns the list with the given name. The name is what appears in the URL as name and is immutable. Returns nil
         
     | 
| 
      
 119 
     | 
    
         
            +
                # if such a list does not exist
         
     | 
| 
      
 120 
     | 
    
         
            +
                # @param [String] name The name of the list
         
     | 
| 
      
 121 
     | 
    
         
            +
                # @return [List]
         
     | 
| 
       71 
122 
     | 
    
         
             
                def list(name)
         
     | 
| 
       72 
     | 
    
         
            -
                  lists.find { |list| File.basename(list. 
     | 
| 
      
 123 
     | 
    
         
            +
                  lists.find { |list| ::File.basename(list.url) == name }
         
     | 
| 
       73 
124 
     | 
    
         
             
                end
         
     | 
| 
       74 
125 
     | 
    
         | 
| 
      
 126 
     | 
    
         
            +
                # Returns the site or list with the given name, or nil if it does not exist
         
     | 
| 
      
 127 
     | 
    
         
            +
                # @param [String] name The name of the site or list
         
     | 
| 
      
 128 
     | 
    
         
            +
                # @return [Site, List]
         
     | 
| 
       75 
129 
     | 
    
         
             
                def /(name)
         
     | 
| 
       76 
130 
     | 
    
         
             
                  list(name) || site(name)
         
     | 
| 
       77 
131 
     | 
    
         
             
                end
         
     | 
| 
       78 
132 
     | 
    
         | 
| 
      
 133 
     | 
    
         
            +
                # Returns the list of content types defined for this site. These include the content types defined on
         
     | 
| 
      
 134 
     | 
    
         
            +
                # containing sites as they are automatically inherited
         
     | 
| 
      
 135 
     | 
    
         
            +
                # @return [Array<ContentType>]
         
     | 
| 
       79 
136 
     | 
    
         
             
                def content_types
         
     | 
| 
       80 
137 
     | 
    
         
             
                  result = call("Webs", "get_content_types", "listName" => @id)
         
     | 
| 
       81 
138 
     | 
    
         
             
                  result.xpath("//sp:ContentType", NS).map do |content_type|
         
     | 
| 
       82 
139 
     | 
    
         
             
                    supersite && supersite.content_type(content_type["ID"]) || ContentType.new(self, nil, content_type["ID"], content_type["Name"], content_type["Description"], content_type["Version"], content_type["Group"])
         
     | 
| 
       83 
140 
     | 
    
         
             
                  end
         
     | 
| 
       84 
141 
     | 
    
         
             
                end
         
     | 
| 
       85 
     | 
    
         
            -
                cache :content_types, :dup =>  
     | 
| 
      
 142 
     | 
    
         
            +
                cache :content_types, :dup => :always
         
     | 
| 
       86 
143 
     | 
    
         | 
| 
      
 144 
     | 
    
         
            +
                # @private
         
     | 
| 
       87 
145 
     | 
    
         
             
                def content_type(id)
         
     | 
| 
       88 
146 
     | 
    
         
             
                  content_types.find { |t| t.id == id }
         
     | 
| 
       89 
147 
     | 
    
         
             
                end
         
     | 
| 
       90 
148 
     | 
    
         | 
| 
      
 149 
     | 
    
         
            +
                # Returns the permission set associated with this site. This returns the permission set of
         
     | 
| 
      
 150 
     | 
    
         
            +
                # the containing site if it does not have a permission set of its own
         
     | 
| 
      
 151 
     | 
    
         
            +
                # @return [PermissionSet]
         
     | 
| 
       91 
152 
     | 
    
         
             
                def permission_set
         
     | 
| 
       92 
153 
     | 
    
         
             
                  if attributes["InheritedSecurity"]
         
     | 
| 
       93 
154 
     | 
    
         
             
                    supersite.permission_set
         
     | 
| 
         @@ -97,27 +158,47 @@ module ActiveSP 
     | 
|
| 
       97 
158 
     | 
    
         
             
                end
         
     | 
| 
       98 
159 
     | 
    
         
             
                cache :permission_set
         
     | 
| 
       99 
160 
     | 
    
         | 
| 
      
 161 
     | 
    
         
            +
                # Returns the list of fields for this site. This includes fields inherited from containing sites
         
     | 
| 
      
 162 
     | 
    
         
            +
                # @return [Array<Field>]
         
     | 
| 
       100 
163 
     | 
    
         
             
                def fields
         
     | 
| 
       101 
164 
     | 
    
         
             
                  call("Webs", "get_columns").xpath("//sp:Field", NS).map do |field|
         
     | 
| 
       102 
165 
     | 
    
         
             
                    attributes = clean_attributes(field.attributes)
         
     | 
| 
       103 
166 
     | 
    
         
             
                    supersite && supersite.field(attributes["ID"].downcase) || Field.new(self, attributes["ID"].downcase, attributes["StaticName"], attributes["Type"], nil, attributes) if attributes["ID"] && attributes["StaticName"]
         
     | 
| 
       104 
167 
     | 
    
         
             
                  end.compact
         
     | 
| 
       105 
168 
     | 
    
         
             
                end
         
     | 
| 
       106 
     | 
    
         
            -
                cache :fields, :dup =>  
     | 
| 
      
 169 
     | 
    
         
            +
                cache :fields, :dup => :always
         
     | 
| 
       107 
170 
     | 
    
         | 
| 
      
 171 
     | 
    
         
            +
                # Returns the result of {Site#fields} hashed by name
         
     | 
| 
      
 172 
     | 
    
         
            +
                # @return [Hash{String => Field}]
         
     | 
| 
       108 
173 
     | 
    
         
             
                def fields_by_name
         
     | 
| 
       109 
174 
     | 
    
         
             
                  fields.inject({}) { |h, f| h[f.attributes["StaticName"]] = f ; h }
         
     | 
| 
       110 
175 
     | 
    
         
             
                end
         
     | 
| 
       111 
     | 
    
         
            -
                cache :fields_by_name, :dup =>  
     | 
| 
      
 176 
     | 
    
         
            +
                cache :fields_by_name, :dup => :always
         
     | 
| 
       112 
177 
     | 
    
         | 
| 
      
 178 
     | 
    
         
            +
                # @private
         
     | 
| 
       113 
179 
     | 
    
         
             
                def field(id)
         
     | 
| 
       114 
180 
     | 
    
         
             
                  fields.find { |f| f.ID == id }
         
     | 
| 
       115 
181 
     | 
    
         
             
                end
         
     | 
| 
       116 
182 
     | 
    
         | 
| 
      
 183 
     | 
    
         
            +
                # See {Base#save}
         
     | 
| 
      
 184 
     | 
    
         
            +
                # @return [void]
         
     | 
| 
      
 185 
     | 
    
         
            +
                def save
         
     | 
| 
      
 186 
     | 
    
         
            +
                  p untype_cast_attributes(self, nil, internal_attribute_types, changed_attributes)
         
     | 
| 
      
 187 
     | 
    
         
            +
                end
         
     | 
| 
      
 188 
     | 
    
         
            +
                
         
     | 
| 
      
 189 
     | 
    
         
            +
                def accessible?
         
     | 
| 
      
 190 
     | 
    
         
            +
                  data
         
     | 
| 
      
 191 
     | 
    
         
            +
                  true
         
     | 
| 
      
 192 
     | 
    
         
            +
                rescue Savon::HTTPError
         
     | 
| 
      
 193 
     | 
    
         
            +
                  false
         
     | 
| 
      
 194 
     | 
    
         
            +
                end
         
     | 
| 
      
 195 
     | 
    
         
            +
                
         
     | 
| 
      
 196 
     | 
    
         
            +
                # @private
         
     | 
| 
       117 
197 
     | 
    
         
             
                def to_s
         
     | 
| 
       118 
198 
     | 
    
         
             
                  "#<ActiveSP::Site url=#{@url}>"
         
     | 
| 
       119 
199 
     | 
    
         
             
                end
         
     | 
| 
       120 
200 
     | 
    
         | 
| 
      
 201 
     | 
    
         
            +
                # @private
         
     | 
| 
       121 
202 
     | 
    
         
             
                alias inspect to_s
         
     | 
| 
       122 
203 
     | 
    
         | 
| 
       123 
204 
     | 
    
         
             
              private
         
     | 
| 
         @@ -136,17 +217,25 @@ module ActiveSP 
     | 
|
| 
       136 
217 
     | 
    
         
             
                end
         
     | 
| 
       137 
218 
     | 
    
         | 
| 
       138 
219 
     | 
    
         
             
                def data
         
     | 
| 
      
 220 
     | 
    
         
            +
                  # Looks like you can't call this as a non-admin. To investigate further
         
     | 
| 
       139 
221 
     | 
    
         
             
                  call("SiteData", "get_web")
         
     | 
| 
      
 222 
     | 
    
         
            +
                rescue Savon::HTTPError
         
     | 
| 
      
 223 
     | 
    
         
            +
                  # This can fail when you don't have access to this site
         
     | 
| 
      
 224 
     | 
    
         
            +
                  call("Webs", "get_web", "webUrl" => ".")
         
     | 
| 
       140 
225 
     | 
    
         
             
                end
         
     | 
| 
       141 
226 
     | 
    
         
             
                cache :data
         
     | 
| 
       142 
227 
     | 
    
         | 
| 
       143 
228 
     | 
    
         
             
                def attributes_before_type_cast
         
     | 
| 
       144 
     | 
    
         
            -
                  element = data.xpath("//sp:sWebMetadata", NS).first
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
      
 229 
     | 
    
         
            +
                  if element = data.xpath("//sp:sWebMetadata", NS).first
         
     | 
| 
      
 230 
     | 
    
         
            +
                    result = {}
         
     | 
| 
      
 231 
     | 
    
         
            +
                    element.children.each do |ch|
         
     | 
| 
      
 232 
     | 
    
         
            +
                      result[ch.name] = ch.inner_text
         
     | 
| 
      
 233 
     | 
    
         
            +
                    end
         
     | 
| 
      
 234 
     | 
    
         
            +
                    result
         
     | 
| 
      
 235 
     | 
    
         
            +
                  else
         
     | 
| 
      
 236 
     | 
    
         
            +
                    element = data.xpath("//sp:Web", NS).first
         
     | 
| 
      
 237 
     | 
    
         
            +
                    clean_attributes(element.attributes)
         
     | 
| 
       148 
238 
     | 
    
         
             
                  end
         
     | 
| 
       149 
     | 
    
         
            -
                  result
         
     | 
| 
       150 
239 
     | 
    
         
             
                end
         
     | 
| 
       151 
240 
     | 
    
         
             
                cache :attributes_before_type_cast
         
     | 
| 
       152 
241 
     | 
    
         | 
| 
         @@ -176,19 +265,20 @@ module ActiveSP 
     | 
|
| 
       176 
265 
     | 
    
         
             
                end
         
     | 
| 
       177 
266 
     | 
    
         | 
| 
       178 
267 
     | 
    
         
             
                def permissions
         
     | 
| 
       179 
     | 
    
         
            -
                  result = call("Permissions", "get_permission_collection", "objectName" => File.basename(@url), "objectType" => "Web")
         
     | 
| 
      
 268 
     | 
    
         
            +
                  result = call("Permissions", "get_permission_collection", "objectName" => ::File.basename(@url), "objectType" => "Web")
         
     | 
| 
       180 
269 
     | 
    
         
             
                  result.xpath("//spdir:Permission", NS).map do |row|
         
     | 
| 
       181 
270 
     | 
    
         
             
                    accessor = row["MemberIsUser"][/true/i] ? User.new(rootsite, row["UserLogin"]) : Group.new(rootsite, row["GroupName"])
         
     | 
| 
       182 
271 
     | 
    
         
             
                    { :mask => Integer(row["Mask"]), :accessor => accessor }
         
     | 
| 
       183 
272 
     | 
    
         
             
                  end
         
     | 
| 
       184 
273 
     | 
    
         
             
                end
         
     | 
| 
       185 
     | 
    
         
            -
                cache :permissions, :dup =>  
     | 
| 
      
 274 
     | 
    
         
            +
                cache :permissions, :dup => :always
         
     | 
| 
       186 
275 
     | 
    
         | 
| 
      
 276 
     | 
    
         
            +
                # @private
         
     | 
| 
       187 
277 
     | 
    
         
             
                class Service
         
     | 
| 
       188 
278 
     | 
    
         | 
| 
       189 
279 
     | 
    
         
             
                  def initialize(site, name)
         
     | 
| 
       190 
280 
     | 
    
         
             
                    @site, @name = site, name
         
     | 
| 
       191 
     | 
    
         
            -
                    @client = Savon::Client.new(File.join(site.url, "_vti_bin", name + ".asmx?WSDL"))
         
     | 
| 
      
 281 
     | 
    
         
            +
                    @client = Savon::Client.new(::File.join(URI.escape(site.url), "_vti_bin", name + ".asmx?WSDL"))
         
     | 
| 
       192 
282 
     | 
    
         
             
                    @client.request.ntlm_auth(site.connection.login, site.connection.password) if site.connection.login
         
     | 
| 
       193 
283 
     | 
    
         
             
                  end
         
     | 
| 
       194 
284 
     | 
    
         |