Skip to content

Commit

Permalink
Merge branch 'release-1.21' into develop
Browse files Browse the repository at this point in the history
* release-1.21:
  [#794] Easyread: print out the meta viewport tag
  [#796] Skittlish Dreams: mobile style
  [#795] Negatives: mobile style
  [#793] Drifting: mobile style
  [#792] Brittle: mobile style
  [#791] Blanket: mobile changes
  [#790] Bases: make mobile friendly
  [#789] Abstractia: mobile-friendly
  [#722] Only include the meta viewport tag conditionally:
  [#723] Reset control strip font size back to absolute 11px
  [#722] Adjust the small-screen-mode boundary from 60em to 30em
  [#724] Don't show module jump link on one-column on desktop as well
  Rename (new) success_ml to DW::Controller->render_success
  (Bug 177) only give access to users who have siteadmin:sendmail priv
  (Bug 177) finished basic /admin/sendmail page
  • Loading branch information
afuna committed Jul 14, 2014
2 parents dcc0cae + 1dca4ac commit bb3f4b0
Show file tree
Hide file tree
Showing 44 changed files with 834 additions and 402 deletions.
18 changes: 18 additions & 0 deletions bin/upgrading/update-db-general.pl
Original file line number Diff line number Diff line change
Expand Up @@ -3173,6 +3173,24 @@
)
EOC

register_tablecreate("siteadmin_email_history", <<'EOC');
CREATE TABLE siteadmin_email_history (
msgid INT UNSIGNED NOT NULL,
remoteid INT UNSIGNED NOT NULL,
time_sent INT UNSIGNED NOT NULL, #unixtime
account VARCHAR(255) NOT NULL,
sendto VARCHAR(255) NOT NULL,
subject VARCHAR(255) NOT NULL,
request INT UNSIGNED,
message MEDIUMTEXT NOT NULL,
notes MEDIUMTEXT,
PRIMARY KEY (msgid),
INDEX (account),
INDEX (sendto)
)
EOC

# FIXME: add alt text, etc. mediaprops?
register_tablecreate("media", <<'EOC');
CREATE TABLE `media` (
Expand Down
156 changes: 156 additions & 0 deletions cgi-bin/DW/Controller/Admin/SendMail.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#!/usr/bin/perl
#
# DW::Controller::SendMail
#
# Admin page for sending emails from site accounts.
#
# Authors:
# Jen Griffin <kareila@livejournal.com>
#
# Copyright (c) 2012-2014 by Dreamwidth Studios, LLC.
#
# This program is free software; you may redistribute it and/or modify it under
# the same terms as Perl itself. For a copy of the license, please reference
# 'perldoc perlartistic' or 'perldoc perlgpl'.
#

package DW::Controller::Admin::SendMail;

use strict;

use DW::Controller;
use DW::Routing;
use DW::Template;
use DW::Controller::Admin;

my @privs = qw(siteadmin:sendmail);

DW::Controller::Admin->register_admin_page( '/',
path => 'sendmail/',
ml_scope => '/admin/sendmail/index.tt',
privs => \@privs,
);

DW::Routing->register_string( "/admin/sendmail/index", \&index_controller );
#add these later
#DW::Routing->register_string( "/admin/sendmail/lookup", \&lookup_controller );
#DW::Routing->register_string( "/admin/sendmail/forms", \&form_controller );

sub index_controller {
my ( $ok, $rv ) = controller( privcheck => \@privs, form_auth => 1 );
return $rv unless $ok;
my $remote = $rv->{remote};

my $r = DW::Request->get;

# form processing
if ( $r->did_post ) {
my $args = $r->post_args;
return error_ml( '/admin/sendmail/index.tt.error.noacct' )
unless my $account = LJ::trim( $args->{account} );
return error_ml( '/admin/sendmail/index.tt.error.norcpt' )
unless my $sendto = LJ::trim( $args->{sendto} );
return error_ml( '/admin/sendmail/index.tt.error.nomsg' )
unless my $message = LJ::trim( $args->{message} );
return error_ml( '/admin/sendmail/index.tt.error.nosubj' )
unless my $subject = LJ::trim( $args->{subject} );

my $support_req = LJ::trim( $args->{request} );
return error_ml( '/admin/sendmail/index.tt.error.badreq' )
if $support_req && $support_req !~ /^\d+$/;
return error_ml( '/admin/sendmail/index.tt.error.badacct' )
unless exists $LJ::SENDMAIL_ACCOUNTS{$account};
return error_ml( '/admin/sendmail/index.tt.error.nomulti' )
if $sendto =~ /,/;

my $u;

# make sure we're sending to either a valid user or something
# that looks reasonably like an email address.
if ( $sendto !~ /^[^@]+@[^.]+\./ ) {
# doesn't look like an email address; do a username lookup
$u = LJ::load_user( $sendto );
return error_ml( '/admin/sendmail/index.tt.error.badrcpt' )
unless defined $u;
$sendto = $u->id; # log userid instead of username
}

# these fields are unconstrained
my $teamnotes = LJ::trim( $args->{notes} );
my $reqsubj = $args->{reqsubj} ? 1 : 0;

if ( $reqsubj && $support_req ) {
$subject = "[\#$support_req] $subject";
}

# now that we have the data, send the message.
# 1. insert data into siteadmin_email_history table
my $msgid = LJ::alloc_global_counter('N');
my $dbh = LJ::get_db_writer();
$dbh->do( "INSERT INTO siteadmin_email_history (msgid, remoteid," .
" time_sent, account, sendto, subject, request, message, " .
" notes) VALUES (?,?,?,?,?,?,?,?,?)", undef,
$msgid, $remote->id, time, $account, $sendto, $subject,
$support_req, $message, $teamnotes )
or return error_ml( '/admin/sendmail/index.tt.error.sendfailed' );

# 2. construct the message and send it to the user(s)
# (this block adapted from bin/worker/paidstatus)
my $send = { from => "$account\@$LJ::DOMAIN",
fromname => $LJ::SITENAME,
subject => $subject,
body => $message,
};
my $sent = 0;

if ( $u && $u->is_community ) {
# send an email to every maintainer
my $maintus = LJ::load_userids( $u->maintainer_userids );
foreach my $maintu ( values %$maintus ) {
if ( $send->{to} = $maintu->email_raw ) {
LJ::send_mail( $send );
$sent = 1;
}
}
} elsif ( $u ) {
if ( $send->{to} = $u->email_raw ) {
LJ::send_mail( $send );
$sent = 1;
}
} else {
$send->{to} = $sendto;
LJ::send_mail( $send );
$sent = 1;
}

return error_ml( '/admin/sendmail/index.tt.error.nouseremail' )
unless $sent;

# 3. update userlog and return success message
$remote->log_event( 'siteadmin_email', { account => $account, msgid => $msgid } );
return success_ml( '/admin/sendmail/index.tt.success.msgtext', undef,
[ { text => LJ::Lang::ml( '/admin/sendmail/index.tt.success.linktext.a' ),
url => '/admin/sendmail' } ] );
}
# end form processing

# Construct data for dropdown of available email addresses;
# the user should have at least one of these for this page to be useful.
# If the user somehow has sendmail priv but no relevant account priv,
# we print an error in the template in that case.
my @account_menu = ( "", LJ::Lang::ml( '/admin/sendmail/index.tt.select.account.choose' ) );

foreach my $account ( sort keys %LJ::SENDMAIL_ACCOUNTS ) {
my $priv = $LJ::SENDMAIL_ACCOUNTS{$account};
push @account_menu, ( $account, "$account\@$LJ::DOMAIN" )
if $remote->has_priv( $priv );
}

$rv->{has_menu} = ( @account_menu > 2 );
$rv->{account_menu} = \@account_menu;

return DW::Template->render_template( 'admin/sendmail/index.tt', $rv );
}


1;
1 change: 1 addition & 0 deletions cgi-bin/DW/Hooks/PrivList.pm
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ LJ::Hooks::register_hook( 'privlist-add', sub {
mysqlstatus => "Access to /admin/mysql_status",
propedit => "Allow to change userprops for other users",
rename => "Access to rename_opts console command",
sendmail => "Access to /admin/sendmail",
spamreports => "Access to /admin/spamreports",
styleview => "Access to private styles on /customize/advanced",
themes => "Access to /admin/themes",
Expand Down
6 changes: 4 additions & 2 deletions cgi-bin/LJ/DB.pm
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ sub get_cluster_master
# 'L' == poLL, 'M' == Messaging, 'H' == sHopping cart,
# 'F' == PubSubHubbub subscription id (F for Fred),
# 'K' == sitekeyword, 'I' == shopping cart Item,
# 'X' == sphinX id, 'U' == OAuth ConsUmer,
# 'X' == sphinX id, 'U' == OAuth ConsUmer, 'N' == seNdmail history
#
sub alloc_global_counter
{
Expand All @@ -658,7 +658,7 @@ sub alloc_global_counter

# $dom can come as a direct argument or as a string to be mapped via hook
my $dom_unmod = $dom;
unless ( $dom =~ /^[ESLPAHCMFKIVXU]$/ ) {
unless ( $dom =~ /^[ESLPAHCMFKIVXUN]$/ ) {
$dom = LJ::Hooks::run_hook('map_global_counter_domain', $dom);
}
return LJ::errobj("InvalidParameters", params => { dom => $dom_unmod })->cond_throw
Expand Down Expand Up @@ -703,6 +703,8 @@ sub alloc_global_counter
$newmax = $dbh->selectrow_array( "SELECT MAX(consumer_id) FROM oauth_consumer" );
} elsif ( $dom eq 'V' ) {
$newmax = $dbh->selectrow_array( "SELECT MAX(vgiftid) FROM vgift_ids" );
} elsif ( $dom eq 'N' ) {
$newmax = $dbh->selectrow_array( "SELECT MAX(msgid) FROM siteadmin_email_history" );
} elsif ( $dom eq 'K' ) {
# pick maximum id from sitekeywords & interests
my $max_sitekeys = $dbh->selectrow_array( "SELECT MAX(kwid) FROM sitekeywords" );
Expand Down
9 changes: 9 additions & 0 deletions doc/config-local.pl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@
$COMMENT_IMPORT_MAX = undef;
$COMMENT_IMPORT_ERROR = "Importing more than 10,000 comments is currently disabled.";

# privileges for various email aliases in /admin/sendmail
# make sure these map to existing support categories on your site
%SENDMAIL_ACCOUNTS = (
support => 'supportread:support',
abuse => 'supportread:abuse',
accounts => 'supportread:accounts',
antispam => 'siteadmin:spamreports',
);

# Set the URI for iOS to find the icon it uses for home-screen
# bookmarks on user subdomains (or anything else rendered through
# S2). This file is not part of the dw-free installation, and is
Expand Down
4 changes: 2 additions & 2 deletions htdocs/stc/controlstrip.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ html body
#lj_controlstrip td
{
font-family: Arial, sans-serif;
font-size: .8em;
line-height: 1.618em;
font-size: 11px;
line-height: 16.5px;
letter-spacing: normal;
padding: 0.4045em 0.809em;
white-space: normal;
Expand Down
Loading

0 comments on commit bb3f4b0

Please sign in to comment.