github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/tests/system/lib/sharing.rb (about)

     1  class Sharing
     2    attr_accessor :couch_id, :couch_rev, :rules, :members
     3    attr_reader :description, :app_slug
     4  
     5    def self.make_xor_key
     6      random = Random.new.bytes(8)
     7      res = []
     8      random.each_byte do |c|
     9        res << (c & 0xf)
    10        res << (c >> 4)
    11      end
    12      res
    13    end
    14  
    15    def self.xor_id(id, key)
    16      l = key.length
    17      buf = id.bytes.to_a
    18      buf.each_with_index do |c, i|
    19        if 48 <= c && c <= 57
    20          c = (c - 48) ^ key[i%l].ord
    21        elsif 97 <= c && c <= 102
    22          c = (c -  87) ^ key[i%l].ord
    23        elsif 65 <= c && c <= 70
    24          c = (c - 55) ^ key[i%l].ord
    25        else
    26          next
    27        end
    28        if c < 10
    29          buf[i] = c + 48
    30        else
    31          buf[i] = (c - 10) + 97
    32        end
    33      end
    34      buf.pack('c*')
    35    end
    36  
    37    def self.get_sharing_info(inst, sharing_id, doctype)
    38      opts = {
    39        accept: "application/vnd.api+json",
    40        content_type: "application/vnd.api+json",
    41        authorization: "Bearer #{inst.token_for doctype}"
    42      }
    43      res = inst.client["/sharings/#{sharing_id}"].get opts
    44      JSON.parse(res.body)["data"]
    45    end
    46  
    47    def self.get_shared_docs(inst, sharing_id, doctype)
    48      j = get_sharing_info inst, sharing_id, doctype
    49      j.dig "relationships", "shared_docs", "data"
    50    end
    51  
    52    def add_members(inst, contacts)
    53      doctype = @rules[0].doctype
    54      opts = {
    55        accept: "application/vnd.api+json",
    56        content_type: "application/vnd.api+json",
    57        authorization: "Bearer #{inst.token_for doctype}"
    58      }
    59      data = {
    60        data: {
    61          relationships: {
    62            recipients: {
    63              data: contacts.map(&:as_reference)
    64            }
    65          }
    66        }
    67      }
    68      body = JSON.generate data
    69      res = inst.client["/sharings/#{@couch_id}/recipients"].post body, opts
    70      res.code
    71    end
    72  
    73    def add_group(inst, group)
    74      doctype = @rules[0].doctype
    75      opts = {
    76        accept: "application/vnd.api+json",
    77        content_type: "application/vnd.api+json",
    78        authorization: "Bearer #{inst.token_for doctype}"
    79      }
    80      data = {
    81        data: {
    82          relationships: {
    83            recipients: {
    84              data: [group.as_reference]
    85            }
    86          }
    87        }
    88      }
    89      body = JSON.generate data
    90      res = inst.client["/sharings/#{@couch_id}/recipients"].post body, opts
    91      res.code
    92    end
    93  
    94    def remove_group(inst, index)
    95      doctype = @rules[0].doctype
    96      opts = {
    97        authorization: "Bearer #{inst.token_for doctype}"
    98      }
    99      res = inst.client["/sharings/#{@couch_id}/groups/#{index}"].delete opts
   100      res.code
   101    end
   102  
   103    def read_only(inst, index)
   104      opts = {
   105        authorization: "Bearer #{inst.token_for Folder.doctype}"
   106      }
   107      res = inst.client["/sharings/#{@couch_id}/recipients/#{index}/readonly"].post "", opts
   108      res.code
   109    end
   110  
   111    def read_write(inst, index)
   112      opts = {
   113        authorization: "Bearer #{inst.token_for Folder.doctype}"
   114      }
   115      res = inst.client["/sharings/#{@couch_id}/recipients/#{index}/readonly"].delete opts
   116      res.code
   117    end
   118  
   119    def revoke_by_sharer(inst, doctype)
   120      opts = {
   121        authorization: "Bearer #{inst.token_for doctype}"
   122      }
   123      res = inst.client["/sharings/#{@couch_id}/recipients"].delete opts
   124      res.code
   125    end
   126  
   127    def revoke_recipient_by_sharer(inst, doctype, index)
   128      opts = {
   129        authorization: "Bearer #{inst.token_for doctype}"
   130      }
   131      res = inst.client["/sharings/#{@couch_id}/recipients/#{index}"].delete opts
   132      res.code
   133    end
   134  
   135    def revoke_recipient_by_itself(inst, doctype)
   136      opts = {
   137        authorization: "Bearer #{inst.token_for doctype}"
   138      }
   139      res = inst.client["/sharings/#{@couch_id}/recipients/self"].delete opts
   140      res.code
   141    end
   142  
   143    def initialize(opts = {})
   144      @description = opts[:description] || Faker::TvShows::DrWho.catch_phrase
   145      @app_slug = opts[:app_slug] || ""
   146      @rules = []
   147      @members = [] # Owner's instance + recipients contacts
   148    end
   149  
   150    def self.doctype
   151      "io.cozy.sharings"
   152    end
   153  
   154    def as_json_api
   155      recipients = @members.drop 1
   156      {
   157        data: {
   158          doctype: self.class.doctype,
   159          attributes: {
   160            description: @description,
   161            app_slug: @app_slug,
   162            rules: @rules.map(&:as_json),
   163            open_sharing: true
   164          },
   165          relationships: {
   166            recipients: {
   167              data: recipients.map(&:as_reference)
   168            }
   169          }
   170        }
   171      }
   172    end
   173  
   174    def owner
   175      @members.first
   176    end
   177  end