diff --git a/ChangeLog b/ChangeLog index fba406d8..59547951 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19578,3 +19578,11 @@ 2020-02-20 Fred Gleason * Updated the URL scheme check code in the 'Edit Feed' dialog in rdadmin(1). +2020-02-21 Fred Gleason + * Added a 'USERS.EMAIL_ADDRESS' field to the database. + * Added 'RDUser::emailAddress()', 'RDUser::setEmaiAddress()' and + 'RDUser::emailContact()' methods. + * Added 'RDUser::emailIsValid()' and 'RDUser::emailContact()' + static methods. + * Added logic to rdcastmanager(1) to insert the author's e-mail + contact automatically when posting a new episode. diff --git a/docs/tables/users.txt b/docs/tables/users.txt index 0925484e..f06b3c3e 100644 --- a/docs/tables/users.txt +++ b/docs/tables/users.txt @@ -5,10 +5,11 @@ on the system. FIELD NAME TYPE REMARKS -------------------------------------------------------------------------- -LOGIN_NAME varchar(255) Primary key -FULL_NAME varchar(255) Indexed +LOGIN_NAME varchar(191) Primary key +FULL_NAME varchar(191) Indexed +EMAIL_ADDRESS varchar(191) PHONE_NUMBER varchar(20) -DESCRIPTION varchar(255) +DESCRIPTION varchar(191) PASSWORD varchar(32) Not-NULL, Hashed WEBAPI_AUTH_TIMEOUT int(11) signed Seconds ENABLE_WEB enum('N','Y') diff --git a/lib/dbversion.h b/lib/dbversion.h index 1fb42dfc..cf8bf983 100644 --- a/lib/dbversion.h +++ b/lib/dbversion.h @@ -24,7 +24,7 @@ /* * Current Database Version */ -#define RD_VERSION_DATABASE 316 +#define RD_VERSION_DATABASE 317 #endif // DBVERSION_H diff --git a/lib/rdfeed.cpp b/lib/rdfeed.cpp index e99ed2ac..0dd549d7 100644 --- a/lib/rdfeed.cpp +++ b/lib/rdfeed.cpp @@ -1197,11 +1197,22 @@ unsigned RDFeed::CreateCast(QString *filename,int bytes,int msecs) const RDSqlQuery *q; RDSqlQuery *q1; unsigned cast_id=0; - + /* sql=QString().sprintf("select CHANNEL_TITLE,CHANNEL_DESCRIPTION,\ CHANNEL_CATEGORY,CHANNEL_LINK,MAX_SHELF_LIFE,\ UPLOAD_FORMAT,UPLOAD_EXTENSION from FEEDS \ where ID=%u",feed_id); + */ + sql=QString("select ")+ + "CHANNEL_TITLE,"+ // 00 + "CHANNEL_DESCRIPTION,"+ // 01 + "CHANNEL_CATEGORY,"+ // 02 + "CHANNEL_LINK,"+ // 03 + "MAX_SHELF_LIFE,"+ // 04 + "UPLOAD_FORMAT,"+ // 05 + "UPLOAD_EXTENSION "+ // 06 + "from FEEDS where "+ + QString().sprintf("ID=%u",feed_id); q=new RDSqlQuery(sql); if(!q->first()) { delete q; @@ -1218,6 +1229,7 @@ unsigned RDFeed::CreateCast(QString *filename,int bytes,int msecs) const "ITEM_CATEGORY=\""+RDEscapeString(q->value(2).toString())+"\","+ "ITEM_LINK=\""+RDEscapeString(q->value(3).toString())+"\","+ QString().sprintf("SHELF_LIFE=%d,",q->value(4).toInt())+ + "ITEM_AUTHOR=\""+RDEscapeString(rda->user()->emailContact())+"\","+ "EFFECTIVE_DATETIME=UTC_TIMESTAMP(),"+ "ORIGIN_DATETIME=UTC_TIMESTAMP()"; q1=new RDSqlQuery(sql); diff --git a/lib/rduser.cpp b/lib/rduser.cpp index b448823c..1f901c00 100644 --- a/lib/rduser.cpp +++ b/lib/rduser.cpp @@ -162,6 +162,38 @@ void RDUser::setFullName(const QString &name) const } +QString RDUser::emailAddress() const +{ + return RDGetSqlValue("USERS","LOGIN_NAME",user_name,"EMAIL_ADDRESS"). + toString(); +} + + +void RDUser::setEmailAddress(const QString &str) const +{ + SetRow("EMAIL_ADDRESS",str); +} + + +QString RDUser::emailContact() const +{ + QString ret; + + QString sql=QString("select ")+ + "EMAIL_ADDRESS,"+ // 00 + "FULL_NAME "+ // 01 + "from USERS where "+ + "LOGIN_NAME=\""+RDEscapeString(user_name)+"\""; + RDSqlQuery *q=new RDSqlQuery(sql); + if(q->first()) { + ret=RDUser::emailContact(q->value(0).toString(),q->value(1).toString()); + } + delete q; + + return ret; +} + + QString RDUser::description() const { return RDGetSqlValue("USERS","LOGIN_NAME",user_name,"DESCRIPTION").toString(); @@ -559,6 +591,36 @@ QStringList RDUser::services() const } +bool RDUser::emailIsValid(const QString &addr) +{ + QStringList f0=addr.split("@",QString::KeepEmptyParts); + + if(f0.size()!=2) { + return false; + } + QStringList f1=f0.last().split("."); + if(f1.size()<2) { + return false; + } + return true; +} + + +QString RDUser::emailContact(const QString &addr,const QString &fullname) +{ + QString ret; + + if(RDUser::emailIsValid(addr)) { + ret=addr; + if(!fullname.isEmpty()) { + ret+=" ("+fullname+")"; + } + } + + return ret; +} + + void RDUser::SetRow(const QString ¶m,const QString &value) const { RDSqlQuery *q; diff --git a/lib/rduser.h b/lib/rduser.h index 12fa6552..24ab4261 100644 --- a/lib/rduser.h +++ b/lib/rduser.h @@ -18,8 +18,6 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -#include - #ifndef RDUSER_H #define RDUSER_H @@ -43,6 +41,9 @@ class RDUser void setPamService(const QString &str) const; QString fullName() const; void setFullName(const QString &name) const; + QString emailAddress() const; + void setEmailAddress(const QString &str) const; + QString emailContact() const; QString description() const; void setDescription(const QString &desc) const; QString phone() const; @@ -92,23 +93,10 @@ class RDUser bool groupAuthorized(const QString &group_name); QStringList groups() const; bool cartAuthorized(unsigned cartnum) const; - - /** Check a default service to ensure it is valid for the current user. - * - * @param serv QString with the proposed default service, presumably gotten - * from RDAirPlayConf::defaultSvc() - * @return QString with serv if it was valid, otherwise an empty QString. - */ QString serviceCheckDefault(QString serv) const; - - /** Calculate the services associated with a user, based on the user's group - * membership and the relationship of groups to services. - * - * Note: admin users, those who pass adminConfig(), can see all services. - * - * @return QStringList with all the services associated with the user. - */ QStringList services() const; + static bool emailIsValid(const QString &addr); + static QString emailContact(const QString &addr,const QString &fullname); private: void SetRow(const QString ¶m,const QString &value) const; diff --git a/rdadmin/edit_user.cpp b/rdadmin/edit_user.cpp index b56f316d..340c091f 100644 --- a/rdadmin/edit_user.cpp +++ b/rdadmin/edit_user.cpp @@ -2,7 +2,7 @@ // // Edit a Rivendell User // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -32,8 +32,6 @@ EditUser::EditUser(const QString &user,QWidget *parent) : RDDialog(parent) { - setModal(true); - // // Fix the Window Size // @@ -53,7 +51,7 @@ EditUser::EditUser(const QString &user,QWidget *parent) // user_name_edit=new QLineEdit(this); user_name_edit->setGeometry(130,11,sizeHint().width()-140,19); - user_name_edit->setMaxLength(255); + user_name_edit->setMaxLength(191); user_name_edit->setValidator(validator); QLabel *user_name_label=new QLabel(user_name_edit,tr("&User Name:"),this); user_name_label->setGeometry(5,11,120,19); @@ -65,7 +63,7 @@ EditUser::EditUser(const QString &user,QWidget *parent) // user_full_name_edit=new QLineEdit(this); user_full_name_edit->setGeometry(130,32,sizeHint().width()-140,19); - user_full_name_edit->setMaxLength(255); + user_full_name_edit->setMaxLength(191); user_full_name_edit->setValidator(validator); QLabel *user_full_name_label= new QLabel(user_full_name_edit,tr("&Full Name:"),this); @@ -78,7 +76,7 @@ EditUser::EditUser(const QString &user,QWidget *parent) // user_description_edit=new QLineEdit(this); user_description_edit->setGeometry(130,53,sizeHint().width()-140,19); - user_description_edit->setMaxLength(255); + user_description_edit->setMaxLength(191); user_description_edit->setValidator(validator); QLabel *user_description_label= new QLabel(user_description_edit,tr("&Description:"),this); @@ -86,15 +84,28 @@ EditUser::EditUser(const QString &user,QWidget *parent) user_description_label->setFont(labelFont()); user_description_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + // + // Email Address + // + user_email_address_edit=new QLineEdit(this); + user_email_address_edit->setGeometry(130,74,sizeHint().width()-140,19); + user_email_address_edit->setMaxLength(191); + user_email_address_edit->setValidator(validator); + QLabel *user_email_address_label= + new QLabel(user_email_address_edit,tr("E-Mail Address")+":",this); + user_email_address_label->setGeometry(5,74,120,19); + user_email_address_label->setFont(labelFont()); + user_email_address_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + // // User Phone // user_phone_edit=new QLineEdit(this); - user_phone_edit->setGeometry(130,75,sizeHint().width()-140,19); + user_phone_edit->setGeometry(130,95,sizeHint().width()-140,19); user_phone_edit->setMaxLength(20); user_phone_edit->setValidator(validator); QLabel *user_phone_label=new QLabel(user_phone_edit,tr("&Phone:"),this); - user_phone_label->setGeometry(10,75,115,19); + user_phone_label->setGeometry(10,95,115,19); user_phone_label->setFont(labelFont()); user_phone_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); @@ -102,12 +113,12 @@ EditUser::EditUser(const QString &user,QWidget *parent) // Local Authentication // user_localauth_check=new QCheckBox(this); - user_localauth_check->setGeometry(20,97,15,15); + user_localauth_check->setGeometry(20,118,15,15); connect(user_localauth_check,SIGNAL(toggled(bool)), this,SLOT(localAuthToggledData(bool))); user_localauth_label=new QLabel(user_localauth_check, tr("Authenticate This User Locally"),this); - user_localauth_label->setGeometry(40,95,200,19); + user_localauth_label->setGeometry(40,116,200,19); user_localauth_label->setFont(labelFont()); user_localauth_label->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); @@ -115,11 +126,11 @@ EditUser::EditUser(const QString &user,QWidget *parent) // PAM Service // user_pamservice_edit=new QLineEdit(this); - user_pamservice_edit->setGeometry(130,119,140,19); + user_pamservice_edit->setGeometry(130,140,140,19); user_pamservice_edit->setMaxLength(32); user_pamservice_label= new QLabel(user_pamservice_edit,tr("PAM Service")+":",this); - user_pamservice_label->setGeometry(10,119,115,19); + user_pamservice_label->setGeometry(10,140,115,19); user_pamservice_label->setFont(labelFont()); user_pamservice_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); @@ -127,7 +138,7 @@ EditUser::EditUser(const QString &user,QWidget *parent) // Change Password Button // user_password_button=new QPushButton(this); - user_password_button->setGeometry(sizeHint().width()-90,97,80,50); + user_password_button->setGeometry(sizeHint().width()-90,118,80,50); user_password_button->setFont(buttonFont()); user_password_button->setText(tr("Change\n&Password")); connect(user_password_button,SIGNAL(clicked()),this,SLOT(passwordData())); @@ -136,20 +147,20 @@ EditUser::EditUser(const QString &user,QWidget *parent) // WebAPI Authorization Timeout // user_webapi_auth_spin=new QSpinBox(this); - user_webapi_auth_spin->setGeometry(130,141,80,19); + user_webapi_auth_spin->setGeometry(130,162,80,19); user_webapi_auth_spin->setRange(0,86400); user_webapi_auth_spin->setSpecialValueText(tr("Disabled")); QLabel *user_webapi_auth_label= new QLabel(user_webapi_auth_spin,tr("WebAPI Timeout:"),this); - user_webapi_auth_label->setGeometry(10,141,115,19); + user_webapi_auth_label->setGeometry(10,162,115,19); user_webapi_auth_label->setFont(labelFont()); user_webapi_auth_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); // // Administrative Group Priviledges // - user_admin_group=new Q3ButtonGroup(tr("Administrative Rights"),this); - user_admin_group->setGeometry(10,170,355,45); + user_admin_group=new QGroupBox(tr("Administrative Rights"),this); + user_admin_group->setGeometry(10,191,355,45); user_admin_group->setFont(labelFont()); user_admin_config_button=new QCheckBox(user_admin_group); @@ -167,8 +178,8 @@ EditUser::EditUser(const QString &user,QWidget *parent) // // Production Group Priviledges // - user_prod_group=new Q3ButtonGroup(tr("Production Rights"),this); - user_prod_group->setGeometry(10,225,355,106); + user_prod_group=new QGroupBox(tr("Production Rights"),this); + user_prod_group->setGeometry(10,246,355,106); user_prod_group->setFont(labelFont()); user_create_carts_button=new QCheckBox(user_prod_group); @@ -233,8 +244,8 @@ EditUser::EditUser(const QString &user,QWidget *parent) // // Traffic Group Priviledges // - user_traffic_group=new Q3ButtonGroup(tr("Traffic Rights"),this); - user_traffic_group->setGeometry(10,341,355,66); + user_traffic_group=new QGroupBox(tr("Traffic Rights"),this); + user_traffic_group->setGeometry(10,362,355,66); user_traffic_group->setFont(labelFont()); user_create_log_button=new QCheckBox(user_traffic_group); @@ -274,8 +285,8 @@ EditUser::EditUser(const QString &user,QWidget *parent) // // OnAir Group Priviledges // - user_onair_group=new Q3ButtonGroup(tr("OnAir Rights"),this); - user_onair_group->setGeometry(10,417,355,85); + user_onair_group=new QGroupBox(tr("OnAir Rights"),this); + user_onair_group->setGeometry(10,438,355,85); user_onair_group->setFont(labelFont()); user_playout_log_button=new QCheckBox(user_onair_group); @@ -324,8 +335,8 @@ EditUser::EditUser(const QString &user,QWidget *parent) // // Podcast Group Priviledges // - user_podcast_group=new Q3ButtonGroup(tr("Podcasting Rights"),this); - user_podcast_group->setGeometry(10,512,355,66); + user_podcast_group=new QGroupBox(tr("Podcasting Rights"),this); + user_podcast_group->setGeometry(10,533,355,66); user_podcast_group->setFont(labelFont()); user_add_podcast_button=new QCheckBox(user_podcast_group); @@ -366,7 +377,7 @@ EditUser::EditUser(const QString &user,QWidget *parent) // Group Permissions Button // user_assign_perms_button=new QPushButton(this); - user_assign_perms_button->setGeometry(10,582,sizeHint().width()/3-20,50); + user_assign_perms_button->setGeometry(10,603,sizeHint().width()/3-20,50); user_assign_perms_button->setFont(buttonFont()); user_assign_perms_button->setText(tr("Group\nPermissions")); connect(user_assign_perms_button,SIGNAL(clicked()),this,SLOT(groupsData())); @@ -375,7 +386,7 @@ EditUser::EditUser(const QString &user,QWidget *parent) // Services Permissions Button // user_assign_svcs_button=new QPushButton(this); - user_assign_svcs_button->setGeometry(sizeHint().width()/3+10,582,sizeHint().width()/3-20,50); + user_assign_svcs_button->setGeometry(sizeHint().width()/3+10,603,sizeHint().width()/3-20,50); user_assign_svcs_button->setFont(buttonFont()); user_assign_svcs_button->setText(tr("Service\nPermissions")); connect(user_assign_svcs_button,SIGNAL(clicked()),this,SLOT(servicesData())); @@ -385,7 +396,7 @@ EditUser::EditUser(const QString &user,QWidget *parent) // user_assign_feeds_button=new QPushButton(this); user_assign_feeds_button-> - setGeometry(2*sizeHint().width()/3+10,582,sizeHint().width()/3-20,50); + setGeometry(2*sizeHint().width()/3+10,603,sizeHint().width()/3-20,50); user_assign_feeds_button->setFont(buttonFont()); user_assign_feeds_button->setText(tr("Podcast Feed\nPermissions")); connect(user_assign_feeds_button,SIGNAL(clicked()),this,SLOT(feedsData())); @@ -417,6 +428,7 @@ EditUser::EditUser(const QString &user,QWidget *parent) user_name_edit->setReadOnly(true); user_full_name_edit->setText(user_user->fullName()); user_description_edit->setText(user_user->description()); + user_email_address_edit->setText(user_user->emailAddress()); user_phone_edit->setText(user_user->phone()); user_localauth_check->setChecked(user_user->localAuthentication()); user_pamservice_edit->setText(user_user->pamService()); @@ -467,6 +479,7 @@ EditUser::~EditUser() delete user_name_edit; delete user_full_name_edit; delete user_description_edit; + delete user_email_address_edit; delete user_phone_edit; delete user_admin_group; delete user_prod_group; @@ -477,7 +490,7 @@ EditUser::~EditUser() QSize EditUser::sizeHint() const { - return QSize(375,702); + return QSize(375,723); } @@ -582,6 +595,7 @@ void EditUser::okData() { user_user->setFullName(user_full_name_edit->text()); user_user->setDescription(user_description_edit->text()); + user_user->setEmailAddress(user_email_address_edit->text()); user_user->setPhone(user_phone_edit->text()); user_user->setLocalAuthentication(user_localauth_check->isChecked()); user_user->setPamService(user_pamservice_edit->text()); diff --git a/rdadmin/edit_user.h b/rdadmin/edit_user.h index b7572549..0d587288 100644 --- a/rdadmin/edit_user.h +++ b/rdadmin/edit_user.h @@ -2,7 +2,7 @@ // // Edit a Rivendell User // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -21,9 +21,8 @@ #ifndef EDIT_USER_H #define EDIT_USER_H -#include - #include +#include #include #include #include @@ -54,6 +53,7 @@ class EditUser : public RDDialog private: QLineEdit *user_name_edit; QLineEdit *user_full_name_edit; + QLineEdit *user_email_address_edit; QLineEdit *user_description_edit; QCheckBox *user_localauth_check; QLabel *user_localauth_label; @@ -64,11 +64,11 @@ class EditUser : public RDDialog QSpinBox *user_webapi_auth_spin; QCheckBox *user_web_box; QLabel *user_web_label; - Q3ButtonGroup *user_admin_group; - Q3ButtonGroup *user_prod_group; - Q3ButtonGroup *user_traffic_group; - Q3ButtonGroup *user_onair_group; - Q3ButtonGroup *user_podcast_group; + QGroupBox *user_admin_group; + QGroupBox *user_prod_group; + QGroupBox *user_traffic_group; + QGroupBox *user_onair_group; + QGroupBox *user_podcast_group; QCheckBox *user_admin_config_button; QCheckBox *user_create_carts_button; QCheckBox *user_delete_carts_button; diff --git a/rdadmin/rdadmin_cs.ts b/rdadmin/rdadmin_cs.ts index f21e1277..6e1007da 100644 --- a/rdadmin/rdadmin_cs.ts +++ b/rdadmin/rdadmin_cs.ts @@ -4510,6 +4510,10 @@ Permissions Allow &WebGet Login + + E-Mail Address + + EditUserPerms diff --git a/rdadmin/rdadmin_de.ts b/rdadmin/rdadmin_de.ts index fcaeca77..f91ef8f5 100644 --- a/rdadmin/rdadmin_de.ts +++ b/rdadmin/rdadmin_de.ts @@ -4379,6 +4379,10 @@ Permissions Allow &WebGet Login + + E-Mail Address + + EditUserPerms diff --git a/rdadmin/rdadmin_es.ts b/rdadmin/rdadmin_es.ts index e643b0d8..e3025d6b 100644 --- a/rdadmin/rdadmin_es.ts +++ b/rdadmin/rdadmin_es.ts @@ -4467,6 +4467,10 @@ Permissions Allow &WebGet Login + + E-Mail Address + + EditUserPerms diff --git a/rdadmin/rdadmin_fr.ts b/rdadmin/rdadmin_fr.ts index 604a3bf9..dad558fa 100644 --- a/rdadmin/rdadmin_fr.ts +++ b/rdadmin/rdadmin_fr.ts @@ -3648,6 +3648,10 @@ Permissions Allow &WebGet Login + + E-Mail Address + + EditUserPerms diff --git a/rdadmin/rdadmin_nb.ts b/rdadmin/rdadmin_nb.ts index 8ef4c6ba..3742e406 100644 --- a/rdadmin/rdadmin_nb.ts +++ b/rdadmin/rdadmin_nb.ts @@ -4280,6 +4280,10 @@ Permissions Allow &WebGet Login + + E-Mail Address + + EditUserPerms diff --git a/rdadmin/rdadmin_nn.ts b/rdadmin/rdadmin_nn.ts index 8ef4c6ba..3742e406 100644 --- a/rdadmin/rdadmin_nn.ts +++ b/rdadmin/rdadmin_nn.ts @@ -4280,6 +4280,10 @@ Permissions Allow &WebGet Login + + E-Mail Address + + EditUserPerms diff --git a/rdadmin/rdadmin_pt_BR.ts b/rdadmin/rdadmin_pt_BR.ts index 69312014..d990e730 100644 --- a/rdadmin/rdadmin_pt_BR.ts +++ b/rdadmin/rdadmin_pt_BR.ts @@ -4359,6 +4359,10 @@ Permissions Allow &WebGet Login + + E-Mail Address + + EditUserPerms diff --git a/utils/rddbmgr/revertschema.cpp b/utils/rddbmgr/revertschema.cpp index 5fbb612c..11f89209 100644 --- a/utils/rddbmgr/revertschema.cpp +++ b/utils/rddbmgr/revertschema.cpp @@ -41,6 +41,15 @@ bool MainObject::RevertSchema(int cur_schema,int set_schema,QString *err_msg) // NEW SCHEMA REVERSIONS GO HERE... + // + // Revert 317 + // + if((cur_schema==317)&&(set_schemacur_schema)) { + sql=QString("alter table USERS add column ")+ + "EMAIL_ADDRESS varchar(191) after FULL_NAME"; + if(!RDSqlQuery::apply(sql,err_msg)) { + return false; + } + + WriteSchemaVersion(++cur_schema); + } + // NEW SCHEMA UPDATES GO HERE...