liquid_feedback_frontend
view model/member.lua @ 10:72c5e0ee7c98
Version beta6
Bugfixes:
- Security fix: Every user was able to change the discussion URL of an initiative
- Creation of new issues in areas without default policies is now possible
- Members can now be sorted in different ways
- No error when trying to compare a draft with itself
- Added missing local statement to variable initialization in app/main/delegation/new.lua
- CSS flaw in initiative action bar fixed
New features:
- Possiblity to invite other users to become initiator
- Revokation of initiatives implemented
- Number of suggestions, supporters, etc. is shown on corresponding tabs of initiative view
- Members can now be sorted by account creation (default sorting is "newest first")
- Configuration option to create an automatic discussion link for all issues
- First draft of global timeline feature (not accessible via link yet)
- Custom stylesheet URL for users marked as developers
In area listing the number of closed issues is shown too
Renamed "author" field of initiative to "last author"
Removed wrongly included file app/main/member/_show_thumb.lua.orig in the distribution
Help texts updated
Bugfixes:
- Security fix: Every user was able to change the discussion URL of an initiative
- Creation of new issues in areas without default policies is now possible
- Members can now be sorted in different ways
- No error when trying to compare a draft with itself
- Added missing local statement to variable initialization in app/main/delegation/new.lua
- CSS flaw in initiative action bar fixed
New features:
- Possiblity to invite other users to become initiator
- Revokation of initiatives implemented
- Number of suggestions, supporters, etc. is shown on corresponding tabs of initiative view
- Members can now be sorted by account creation (default sorting is "newest first")
- Configuration option to create an automatic discussion link for all issues
- First draft of global timeline feature (not accessible via link yet)
- Custom stylesheet URL for users marked as developers
In area listing the number of closed issues is shown too
Renamed "author" field of initiative to "last author"
Removed wrongly included file app/main/member/_show_thumb.lua.orig in the distribution
Help texts updated
| author | bsw | 
|---|---|
| date | Sun Jan 10 12:00:00 2010 +0100 (2010-01-10) | 
| parents | 0ee1e0c42d4c | 
| children | 77d58efe99fd | 
 line source
     1 Member = mondelefant.new_class()
     2 Member.table = 'member'
     4 Member:add_reference{
     5   mode          = "1m",
     6   to            = "MemberHistory",
     7   this_key      = 'id',
     8   that_key      = 'member_id',
     9   ref           = 'history_entries',
    10   back_ref      = 'member'
    11 }
    13 Member:add_reference{
    14   mode          = '1m',
    15   to            = "MemberImage",
    16   this_key      = 'id',
    17   that_key      = 'member_id',
    18   ref           = 'images',
    19   back_ref      = 'member'
    20 }
    22 Member:add_reference{
    23   mode          = '1m',
    24   to            = "Contact",
    25   this_key      = 'id',
    26   that_key      = 'member_id',
    27   ref           = 'contacts',
    28   back_ref      = 'member',
    29   default_order = '"other_member_id"'
    30 }
    32 Member:add_reference{
    33   mode          = '1m',
    34   to            = "Contact",
    35   this_key      = 'id',
    36   that_key      = 'member_id',
    37   ref           = 'foreign_contacts',
    38   back_ref      = 'other_member',
    39   default_order = '"member_id"'
    40 }
    42 Member:add_reference{
    43   mode          = '1m',
    44   to            = "Session",
    45   this_key      = 'id',
    46   that_key      = 'member_id',
    47   ref           = 'sessions',
    48   back_ref      = 'member',
    49   default_order = '"ident"'
    50 }
    52 Member:add_reference{
    53   mode          = '1m',
    54   to            = "Draft",
    55   this_key      = 'id',
    56   that_key      = 'author_id',
    57   ref           = 'drafts',
    58   back_ref      = 'author',
    59   default_order = '"id"'
    60 }
    62 Member:add_reference{
    63   mode          = '1m',
    64   to            = "Suggestion",
    65   this_key      = 'id',
    66   that_key      = 'author_id',
    67   ref           = 'suggestions',
    68   back_ref      = 'author',
    69   default_order = '"id"'
    70 }
    72 Member:add_reference{
    73   mode          = '1m',
    74   to            = "Membership",
    75   this_key      = 'id',
    76   that_key      = 'member_id',
    77   ref           = 'memberships',
    78   back_ref      = 'member',
    79   default_order = '"area_id"'
    80 }
    82 Member:add_reference{
    83   mode          = '1m',
    84   to            = "Interest",
    85   this_key      = 'id',
    86   that_key      = 'member_id',
    87   ref           = 'interests',
    88   back_ref      = 'member',
    89   default_order = '"id"'
    90 }
    92 Member:add_reference{
    93   mode          = '1m',
    94   to            = "Initiator",
    95   this_key      = 'id',
    96   that_key      = 'member_id',
    97   ref           = 'initiators',
    98   back_ref      = 'member'
    99 }
   101 Member:add_reference{
   102   mode          = '1m',
   103   to            = "Supporter",
   104   this_key      = 'id',
   105   that_key      = 'member_id',
   106   ref           = 'supporters',
   107   back_ref      = 'member'
   108 }
   110 Member:add_reference{
   111   mode          = '1m',
   112   to            = "Opinion",
   113   this_key      = 'id',
   114   that_key      = 'member_id',
   115   ref           = 'opinions',
   116   back_ref      = 'member',
   117   default_order = '"id"'
   118 }
   120 Member:add_reference{
   121   mode          = '1m',
   122   to            = "Delegation",
   123   this_key      = 'id',
   124   that_key      = 'truster_id',
   125   ref           = 'outgoing_delegations',
   126   back_ref      = 'truster',
   127   default_order = '"id"'
   128 }
   130 Member:add_reference{
   131   mode          = '1m',
   132   to            = "Delegation",
   133   this_key      = 'id',
   134   that_key      = 'trustee_id',
   135   ref           = 'incoming_delegations',
   136   back_ref      = 'trustee',
   137   default_order = '"id"'
   138 }
   140 Member:add_reference{
   141   mode          = '1m',
   142   to            = "DirectVoter",
   143   this_key      = 'id',
   144   that_key      = 'member_id',
   145   ref           = 'direct_voter',
   146   back_ref      = 'member',
   147   default_order = '"issue_id"'
   148 }
   150 Member:add_reference{
   151   mode          = '1m',
   152   to            = "Vote",
   153   this_key      = 'id',
   154   that_key      = 'member_id',
   155   ref           = 'vote',
   156   back_ref      = 'member',
   157   default_order = '"issue_id", "initiative_id"'
   158 }
   160 Member:add_reference{
   161   mode                  = 'mm',
   162   to                    = "Member",
   163   this_key              = 'id',
   164   that_key              = 'id',
   165   connected_by_table    = 'contact',
   166   connected_by_this_key = 'member_id',
   167   connected_by_that_key = 'other_member_id',
   168   ref                   = 'saved_members',
   169 }
   171 Member:add_reference{
   172   mode                  = 'mm',
   173   to                    = "Member",
   174   this_key              = 'id',
   175   that_key              = 'id',
   176   connected_by_table    = 'contact',
   177   connected_by_this_key = 'other_member_id',
   178   connected_by_that_key = 'member_id',
   179   ref                   = 'saved_by_members',
   180 }
   182 Member:add_reference{
   183   mode                  = 'mm',
   184   to                    = "Area",
   185   this_key              = 'id',
   186   that_key              = 'id',
   187   connected_by_table    = 'membership',
   188   connected_by_this_key = 'member_id',
   189   connected_by_that_key = 'area_id',
   190   ref                   = 'areas'
   191 }
   193 Member:add_reference{
   194   mode                  = 'mm',
   195   to                    = "Issue",
   196   this_key              = 'id',
   197   that_key              = 'id',
   198   connected_by_table    = 'interest',
   199   connected_by_this_key = 'member_id',
   200   connected_by_that_key = 'issue_id',
   201   ref                   = 'issues'
   202 }
   204 Member:add_reference{
   205   mode                  = 'mm',
   206   to                    = "Initiative",
   207   this_key              = 'id',
   208   that_key              = 'id',
   209   connected_by_table    = 'initiator',
   210   connected_by_this_key = 'member_id',
   211   connected_by_that_key = 'initiative_id',
   212   ref                   = 'initiated_initiatives'
   213 }
   215 Member:add_reference{
   216   mode                  = 'mm',
   217   to                    = "Initiative",
   218   this_key              = 'id',
   219   that_key              = 'id',
   220   connected_by_table    = 'supporter',
   221   connected_by_this_key = 'member_id',
   222   connected_by_that_key = 'initiative_id',
   223   ref                   = 'supported_initiatives'
   224 }
   226 function Member.object:set_password(password)
   227   local hash = os.crypt(
   228     password,
   229     "$1$" .. multirand.string(
   230       8,
   231       "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"
   232     )
   233   )
   234   assert(hash, "os.crypt failed")
   235   self.password = hash
   236 end
   238 function Member.object:check_password(password)
   239   if type(password) == "string" and type(self.password) == "string" then
   240     return os.crypt(password, self.password) == self.password
   241   else
   242     return false
   243   end
   244 end
   246 function Member.object_get:published_contacts()
   247   return Member:new_selector()
   248     :join('"contact"', nil, '"contact"."other_member_id" = "member"."id"')
   249     :add_where{ '"contact"."member_id" = ?', self.id }
   250     :add_where("public")
   251     :exec()
   252 end
   254 function Member:by_login_and_password(login, password)
   255   local selector = self:new_selector()
   256   selector:add_where{'"login" = ?', login }
   257   selector:add_where('"active"')
   258   selector:optional_object_mode()
   259   local member = selector:exec()
   260   if member and member:check_password(password) then
   261     return member
   262   else
   263     return nil
   264   end
   265 end
   267 function Member:by_login(login)
   268   local selector = self:new_selector()
   269   selector:add_where{'"login" = ?', login }
   270   selector:optional_object_mode()
   271   return selector:exec()
   272 end
   274 function Member:by_name(name)
   275   local selector = self:new_selector()
   276   selector:add_where{'"name" = ?', name }
   277   selector:optional_object_mode()
   278   return selector:exec()
   279 end
   281 function Member:get_search_selector(search_string)
   282   return self:new_selector()
   283     :add_field( {'"highlight"("member"."name", ?)', search_string }, "name_highlighted")
   284     :add_where{ '"member"."text_search_data" @@ "text_search_query"(?)', search_string }
   285     :add_where("active")
   286 end
   288 function Member.object:set_notify_email(notify_email)
   289   local expiry = db:query("SELECT now() + '7 days'::interval as expiry", "object").expiry
   290   self.notify_email_unconfirmed = notify_email
   291   self.notify_email_secret = multirand.string( 24, "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" )
   292   self.notify_email_secret_expiry = expiry
   293   local content = slot.use_temporary(function()
   294     slot.put(_"Hello " .. self.name .. ",\n\n")
   295     slot.put(_"Please confirm your email address by clicking the following link:\n\n")
   296     slot.put(config.absolute_base_url .. "index/confirm_notify_email.html?secret=" .. self.notify_email_secret .. "\n\n")
   297     slot.put(_"If this link is not working, please open following url in your web browser:\n\n")
   298     slot.put(config.absolute_base_url .. "index/confirm_notify_email.html\n\n")
   299     slot.put(_"On that page please enter the confirmation code:\n\n")
   300     slot.put(self.notify_email_secret .. "\n\n")
   301   end)
   302   local success = net.send_mail{
   303     envelope_from = config.mail_envelope_from,
   304     from          = config.mail_from,
   305     reply_to      = config.mail_reply_to,
   306     to            = self.notify_email_unconfirmed,
   307     subject       = config.mail_subject_prefix .. _"Email confirmation request",
   308     content_type  = "text/plain; charset=UTF-8",
   309     content       = content
   310   }
   311   return success
   312 end
