From: Tom Hughes Date: Fri, 7 May 2010 21:28:07 +0000 (+0100) Subject: Merge branch 'master' into openid X-Git-Tag: live~7300 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/f85681c5cee9406aacc1745a3fb3bd0331d3c0e4?hp=-c Merge branch 'master' into openid Conflicts: app/controllers/user_controller.rb --- f85681c5cee9406aacc1745a3fb3bd0331d3c0e4 diff --combined app/controllers/user_controller.rb index 77f63dfc6,222840a06..41a08363c --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@@ -11,12 -11,12 +11,12 @@@ class UserController < ApplicationContr before_filter :require_allow_read_prefs, :only => [:api_details] before_filter :require_allow_read_gpx, :only => [:api_gpx_files] before_filter :require_cookies, :only => [:login, :confirm] - before_filter :require_administrator, :only => [:activate, :deactivate, :hide, :unhide, :delete] - before_filter :lookup_this_user, :only => [:activate, :deactivate, :hide, :unhide, :delete] + before_filter :require_administrator, :only => [:set_status, :delete, :list] + before_filter :lookup_this_user, :only => [:set_status, :delete] filter_parameter_logging :password, :pass_crypt, :pass_crypt_confirmation - cache_sweeper :user_sweeper, :only => [:account, :hide, :unhide, :delete] + cache_sweeper :user_sweeper, :only => [:account, :set_status, :delete] def save @title = t 'user.new.title' @@@ -24,71 -24,13 +24,71 @@@ if Acl.find_by_address(request.remote_ip, :conditions => {:k => "no_account_creation"}) render :action => 'new' else - @user = User.new(params[:user]) - - @user.status = "pending" - @user.data_public = true - @user.description = "" if @user.description.nil? - @user.creation_ip = request.remote_ip - @user.languages = request.user_preferred_languages + #The redirect from the OpenID provider reenters here again + #and we need to pass the parameters through to the + #open_id_authentication function a second time + if params[:open_id_complete] + openid_verify('', true) + #We have set the user.openid_url to nil beforehand. If it hasn't + #been set to a new valid openid_url, it means the openid couldn't be validated + if @user.nil? or @user.openid_url.nil? + render :action => 'new' + return + end + else + @user = User.new(params[:user]) + - @user.visible = true ++ @user.status = "pending" + @user.data_public = true + @user.description = "" if @user.description.nil? + @user.creation_ip = request.remote_ip + @user.languages = request.user_preferred_languages + #Set the openid_url to nil as for one it is used + #to check if the openid could be validated and secondly + #to not get dupplicate conflicts for an empty openid + @user.openid_url = nil + + if (!params[:user][:openid_url].nil? and params[:user][:openid_url].length > 0) + if (@user.pass_crypt.nil? or @user.pass_crypt.length == 0) + #if the password is empty, but we have a openid + #then generate a random passowrd to disable + #loging in via password + @user.pass_crypt = ActiveSupport::SecureRandom.base64(16) + @user.pass_crypt_confirmation = @user.pass_crypt + end + #Validate all of the other fields before + #redirecting to the openid provider + if !@user.valid? + render :action => 'new' + else + #TODO: Is it a problem to store the user variable with respect to password safty in the session variables? + #Store the user variable in the session for it to be accessible when redirecting back from the openid provider + session[:new_usr] = @user + begin + @norm_openid_url = OpenIdAuthentication.normalize_identifier(params[:user][:openid_url]) + rescue + flash.now[:error] = t 'user.login.openid invalid' + render :action => 'new' + return + end + #Verify that the openid provided is valid and that the user is the owner of the id + openid_verify(@norm_openid_url, true) + #openid_verify can return in two ways: + #Either it returns with a redirect to the openid provider who then freshly + #redirects back to this url if the openid is valid, or if the openid is not plausible + #and no provider for it could be found it just returns + #we want to just let the redirect through + if response.headers["Location"].nil? + render :action => 'new' + end + end + #At this point there was either an error and the page has been rendered, + #or there is a redirect to the openid provider and the rest of the method + #gets executed whenn this method gets reentered after redirecting back + #from the openid provider + return + end + end if @user.save flash[:notice] = t 'user.new.flash create success message' @@@ -104,15 -46,6 +104,15 @@@ @title = t 'user.account.title' @tokens = @user.oauth_tokens.find :all, :conditions => 'oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null' + #The redirect from the OpenID provider reenters here again + #and we need to pass the parameters through to the + #open_id_authentication function + if params[:open_id_complete] + openid_verify('', false) + @user.save + return + end + if params[:user] and params[:user][:display_name] and params[:user][:description] @user.display_name = params[:user][:display_name] @user.new_email = params[:user][:new_email] @@@ -133,15 -66,13 +133,15 @@@ @user.home_lat = params[:user][:home_lat] @user.home_lon = params[:user][:home_lon] + @user.openid_url = nil if (params[:user][:openid_url].length == 0) + if @user.save set_locale if @user.new_email.nil? or @user.new_email.empty? - flash.now[:notice] = t 'user.account.flash update success' + flash[:notice] = t 'user.account.flash update success' else - flash.now[:notice] = t 'user.account.flash update success confirm needed' + flash[:notice] = t 'user.account.flash update success confirm needed' begin Notifier.deliver_email_confirm(@user, @user.tokens.create) @@@ -149,22 -80,9 +149,24 @@@ # Ignore errors sending email end end + + redirect_to :action => "account", :display_name => @user.display_name end + + if (params[:user][:openid_url].length > 0) + begin + @norm_openid_url = OpenIdAuthentication.normalize_identifier(params[:user][:openid_url]) + if (@norm_openid_url != @user.openid_url) + #If the OpenID has changed, we want to check that it is a valid OpenID and one + #the user has control over before saving the openID as a password equivalent for + #the user. + openid_verify(@norm_openid_url, false) + end + rescue + flash.now[:error] = t 'user.login.openid invalid' + end + end + else if flash[:errors] flash[:errors].each do |attr,msg| @@@ -175,91 -93,6 +177,91 @@@ end end + def openid_specialcase_mapping(openid_url) + #Special case gmail.com, as it is pontentially a popular OpenID provider and unlike + #yahoo.com, where it works automatically, Google have hidden their OpenID endpoint + #somewhere obscure making it less userfriendly. + if (openid_url.match(/(.*)gmail.com(\/?)$/) or openid_url.match(/(.*)googlemail.com(\/?)$/) ) + return 'https://www.google.com/accounts/o8/id' + end + + return nil + end + + def openid_verify(openid_url,account_create) + authenticate_with_open_id(openid_url) do |result, identity_url| + if result.successful? + #We need to use the openid url passed back from the OpenID provider + #rather than the one supplied by the user, as these can be different. + #e.g. one can simply enter yahoo.com in the login box, i.e. no user specific url + #only once it comes back from the OpenID provider do we know the unique address for + #the user. + @user = session[:new_usr] unless @user #this is used for account creation when the user is not yet in the database + @user.openid_url = identity_url + elsif result.missing? + mapped_id = openid_specialcase_mapping(openid_url) + if mapped_id + openid_verify(mapped_id, account_create) + else + flash.now[:error] = t 'user.login.openid missing provider' + end + elsif result.invalid? + flash.now[:error] = t 'user.login.openid invalid' + else + flash.now[:error] = t 'user.login.auth failure' + end + end + end + + def open_id_authentication(openid_url) + #TODO: only ask for nickname and email, if we don't already have a user for that openID, in which case + #email and nickname are already filled out. I don't know how to do that with ruby syntax though, as we + #don't want to duplicate the do block + #On the other hand it also doesn't matter too much if we ask every time, as the OpenID provider should + #remember these results, and shouldn't repromt the user for these data each time. + user = nil + authenticate_with_open_id(openid_url, :return_to => request.protocol + request.host_with_port + '/login?referer=' + params[:referer], :optional => [:nickname, :email]) do |result, identity_url, registration| + if result.successful? + #We need to use the openid url passed back from the OpenID provider + #rather than the one supplied by the user, as these can be different. + #e.g. one can simply enter yahoo.com in the login box, i.e. no user specific url + #only once it comes back from the OpenID provider do we know the unique address for + #the user. + user = User.find_by_openid_url(identity_url) + if user + if user.visible? and user.active? + session[:user] = user.id + session_expires_after 1.month if session[:remember] + return user + else + user = nil + flash.now[:error] = t 'user.login.account not active' + end + else + #We don't have a user registered to this OpenID. Redirect to the create account page + #with username and email filled in if they have been given by the OpenID provider through + #the simple registration protocol + redirect_to :controller => 'user', :action => 'new', :nickname => registration['nickname'], :email => registration['email'], :openid => identity_url + end + else if result.missing? + #Try and apply some heuristics to make common cases more userfriendly + mapped_id = openid_specialcase_mapping(openid_url) + if mapped_id + open_id_authentication(mapped_id) + else + flash.now[:error] = t 'user.login.openid missing provider' + end + else if result.invalid? + flash.now[:error] = t 'user.login.openid invalid' + else + flash.now[:error] = t 'user.login.auth failure' + end + end + end + end + return user + end + def go_public @user.data_public = true @user.save @@@ -271,7 -104,7 +273,7 @@@ @title = t 'user.lost_password.title' if params[:user] and params[:user][:email] - user = User.find_by_email(params[:user][:email], :conditions => {:visible => true}) + user = User.find_by_email(params[:user][:email], :conditions => {:status => ["pending", "active", "confirmed"]}) if user token = user.tokens.create @@@ -296,7 -129,7 +298,7 @@@ if params[:user] @user.pass_crypt = params[:user][:pass_crypt] @user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation] - @user.active = true + @user.status = "active" @user.email_valid = true if @user.save @@@ -318,56 -151,36 +320,58 @@@ # The user is logged in already, so don't show them the signup # page, instead send them to the home page redirect_to :controller => 'site', :action => 'index' if session[:user] + + @nickname = params['nickname'] + @email = params['email'] + @openID = params['openid'] + + if !params['openid'].nil? + flash.now[:notice] = t 'user.new.openID association' + end end def login @title = t 'user.login.title' - if params[:user] - email_or_display_name = params[:user][:email] - pass = params[:user][:password] - user = User.authenticate(:username => email_or_display_name, :password => pass) - - if user - session[:user] = user.id - session_expires_after 1.month if params[:remember_me] - - # The user is logged in, if the referer param exists, redirect - # them to that unless they've also got a block on them, in - # which case redirect them to the block so they can clear it. - if user.blocked_on_view - redirect_to user.blocked_on_view, :referrer => params[:referrer] - elsif params[:referer] - redirect_to params[:referer] + #The redirect from the OpenID provider reenters here again + #and we need to pass the parameters through to the + # open_id_authentication function + if params[:open_id_complete] + user = open_id_authentication('') + elsif params[:user] + if !params[:user][:openid_url].nil? and !params[:user][:openid_url].empty? + session[:remember] = params[:remember_me] + #construct the openid request. This will redirect to the OpenID server to ask for validation + #The external OpenID server will then redirect back to the login method and reenters at the top + open_id_authentication(params[:user][:openid_url]) + return + else + email_or_display_name = params[:user][:email] + pass = params[:user][:password] + + if user = User.authenticate(:username => email_or_display_name, :password => pass) + session[:user] = user.id + session_expires_after 1.month if params[:remember_me] - elsif User.authenticate(:username => email_or_display_name, :password => pass, :inactive => true) ++ elsif User.authenticate(:username => email_or_display_name, :password => pass, :pending => true) + flash.now[:error] = t 'user.login.account not active' ++ elsif User.authenticate(:username => email_or_display_name, :password => pass, :suspended => true) ++ flash.now[:error] = t 'user.login.account suspended' else - redirect_to :controller => 'site', :action => 'index' + flash.now[:error] = t 'user.login.auth failure' end - elsif User.authenticate(:username => email_or_display_name, :password => pass, :pending => true) - flash.now[:error] = t 'user.login.account not active' - elsif User.authenticate(:username => email_or_display_name, :password => pass, :suspended => true) - flash.now[:error] = t 'user.login.account suspended' + end + end + + if user + # The user is logged in, if the referer param exists, redirect + # them to that unless they've also got a block on them, in + # which case redirect them to the block so they can clear it. + if user.blocked_on_view + redirect_to user.blocked_on_view, :referrer => params[:referrer] + elsif params[:referer] + redirect_to params[:referer] else - flash.now[:error] = t 'user.login.auth failure' + redirect_to :controller => 'site', :action => 'index' end end end @@@ -398,7 -211,7 +402,7 @@@ token = UserToken.find_by_token(params[:confirm_string]) if token and !token.user.active? @user = token.user - @user.active = true + @user.status = "active" @user.email_valid = true @user.save! referer = token.referer @@@ -423,7 -236,6 +427,6 @@@ @user = token.user @user.email = @user.new_email @user.new_email = nil - @user.active = true @user.email_valid = true if @user.save flash[:notice] = t 'user.confirm_email.success' @@@ -463,7 -275,7 +466,7 @@@ def make_friend if params[:display_name] name = params[:display_name] - new_friend = User.find_by_display_name(name, :conditions => {:visible => true}) + new_friend = User.find_by_display_name(name, :conditions => {:status => ["active", "confirmed"]}) friend = Friend.new friend.user_id = @user.id friend.friend_user_id = new_friend.id @@@ -489,7 -301,7 +492,7 @@@ def remove_friend if params[:display_name] name = params[:display_name] - friend = User.find_by_display_name(name, :conditions => {:visible => true}) + friend = User.find_by_display_name(name, :conditions => {:status => ["active", "confirmed"]}) if @user.is_friends_with?(friend) Friend.delete_all "user_id = #{@user.id} AND friend_user_id = #{friend.id}" flash[:notice] = t 'user.remove_friend.success', :name => friend.display_name @@@ -506,47 -318,57 +509,57 @@@ end ## - # activate a user, allowing them to log in - def activate - @this_user.update_attributes(:active => true) + # sets a user's status + def set_status + @this_user.update_attributes(:status => params[:status]) redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] end ## - # deactivate a user, preventing them from logging in - def deactivate - @this_user.update_attributes(:active => false) + # delete a user, marking them as deleted and removing personal data + def delete + @this_user.delete redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] end ## - # hide a user, marking them as logically deleted - def hide - @this_user.update_attributes(:visible => false) - redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] - end + # display a list of users matching specified criteria + def list + if request.post? + ids = params[:user].keys.collect { |id| id.to_i } - ## - # unhide a user, clearing the logically deleted flag - def unhide - @this_user.update_attributes(:visible => true) - redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] - end + User.update_all("status = 'confirmed'", :id => ids) if params[:confirm] + User.update_all("status = 'deleted'", :id => ids) if params[:hide] - ## - # delete a user, marking them as deleted and removing personal data - def delete - @this_user.delete - redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] + redirect_to url_for(:status => params[:status], :ip => params[:ip], :page => params[:page]) + else + conditions = Hash.new + conditions[:status] = params[:status] if params[:status] + conditions[:creation_ip] = params[:ip] if params[:ip] + + @user_pages, @users = paginate(:users, + :conditions => conditions, + :order => :id, + :per_page => 50) + end end + private + ## # require that the user is a administrator, or fill out a helpful error message # and return them to the user page. def require_administrator - unless @user.administrator? + if @user and not @user.administrator? flash[:error] = t('user.filter.not_an_administrator') - redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] + + if params[:display_name] + redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] + else + redirect_to :controller => 'user', :action => 'login', :referer => request.request_uri + end + elsif not @user + redirect_to :controller => 'user', :action => 'login', :referer => request.request_uri end end diff --combined app/models/user.rb index 09e1a7d35,31b0f27a0..f99ad3b40 --- a/app/models/user.rb +++ b/app/models/user.rb @@@ -3,10 -3,11 +3,11 @@@ class User < ActiveRecord::Bas has_many :traces, :conditions => { :visible => true } has_many :diary_entries, :order => 'created_at DESC' + has_many :diary_comments, :order => 'created_at DESC' has_many :messages, :foreign_key => :to_user_id, :conditions => { :to_user_visible => true }, :order => 'sent_on DESC' has_many :new_messages, :class_name => "Message", :foreign_key => :to_user_id, :conditions => { :to_user_visible => true, :message_read => false }, :order => 'sent_on DESC' has_many :sent_messages, :class_name => "Message", :foreign_key => :from_user_id, :conditions => { :from_user_visible => true }, :order => 'sent_on DESC' - has_many :friends, :include => :befriendee, :conditions => ["users.visible = ?", true] + has_many :friends, :include => :befriendee, :conditions => "users.status IN ('active', 'confirmed')" has_many :tokens, :class_name => "UserToken" has_many :preferences, :class_name => "UserPreference" has_many :changesets @@@ -22,7 -23,6 +23,7 @@@ validates_confirmation_of :pass_crypt#, :message => ' must match the confirmation password' validates_uniqueness_of :display_name, :allow_nil => true validates_uniqueness_of :email + validates_uniqueness_of :openid_url, :allow_nil => true validates_length_of :pass_crypt, :within => 8..255 validates_length_of :display_name, :within => 3..255, :allow_nil => true validates_email_format_of :email @@@ -56,8 -56,11 +57,11 @@@ user = token.user if token end - if user - user = nil unless user.visible? and (user.active? or options[:inactive]) + if user and + ( user.status == "deleted" or + ( user.status == "pending" and not options[:pending] ) or + ( user.status == "suspended" and not options[:suspended] ) ) + user = nil end token.update_attribute(:expiry, 1.week.from_now) if token and user @@@ -107,7 -110,8 +111,8 @@@ bounds = gc.bounds(radius) sql_for_distance = gc.sql_for_distance("home_lat", "home_lon") nearby = User.find(:all, - :conditions => ["id != ? AND visible = ? AND data_public = ? AND #{sql_for_distance} <= ?", id, true, true, radius], :order => sql_for_distance, :limit => num) + :conditions => ["id != ? AND status IN (\'active\', \'confirmed\') AND data_public = ? AND #{sql_for_distance} <= ?", id, true, radius], + :order => sql_for_distance, :limit => num) else nearby = [] end @@@ -129,6 -133,18 +134,18 @@@ return false end + ## + # returns true if a user is visible + def visible? + ["pending","active","confirmed"].include? self.status + end + + ## + # returns true if a user is active + def active? + ["active","confirmed"].include? self.status + end + ## # returns true if the user has the moderator role, false otherwise def moderator? @@@ -154,8 -170,9 +171,9 @@@ active_blocks.detect { |b| b.needs_view? } end + ## + # delete a user - leave the account but purge most personal data def delete - self.active = false self.display_name = "user_#{self.id}" self.description = "" self.home_lat = nil @@@ -163,8 -180,24 +181,24 @@@ self.image = nil self.email_valid = false self.new_email = nil - self.visible = false + self.status = "deleted" self.save end + ## + # return a spam score for a user + def spam_score + changeset_score = self.changesets.find(:all, :limit => 10).length * 50 + trace_score = self.traces.find(:all, :limit => 10).length * 50 + diary_entry_score = self.diary_entries.inject(0) { |s,e| s += OSM.spam_score(e.body) } + diary_comment_score = self.diary_comments.inject(0) { |s,e| s += OSM.spam_score(e.body) } + + score = OSM.spam_score(self.description) * 2 + score += diary_entry_score / self.diary_entries.length if self.diary_entries.length > 0 + score += diary_comment_score / self.diary_comments.length if self.diary_comments.length > 0 + score -= changeset_score + score -= trace_score + + return score.to_i + end end diff --combined config/environment.rb index 7f9343ce0,d8f9b2fc8..224b90706 --- a/config/environment.rb +++ b/config/environment.rb @@@ -56,7 -56,6 +56,7 @@@ Rails::Initializer.run do |config config.gem 'rmagick', :lib => 'RMagick' config.gem 'oauth', :version => '>= 0.3.6' config.gem 'httpclient' + config.gem 'ruby-openid', :lib => 'openid', :version => '>=2.0.4' config.gem 'SystemTimer', :version => '>= 1.1.3', :lib => 'system_timer' config.gem 'sanitize' @@@ -101,7 -100,7 +101,7 @@@ config.active_record.schema_format = :sql # Activate observers that should always be running - # config.active_record.observers = :cacher, :garbage_collector + config.active_record.observers = :spam_observer # Make Active Record use UTC-base instead of local time config.active_record.default_timezone = :utc diff --combined config/locales/en.yml index cb4de862e,fbf8e7a04..97551164f --- a/config/locales/en.yml +++ b/config/locales/en.yml @@@ -1485,37 -1485,12 +1485,38 @@@ en create_account: "create an account" email or username: "Email Address or Username:" password: "Password:" + openid: "OpenID:" + openid description: "Use your OpenID to login" + username_heading: "Login with username and password:" + openid_heading: "Login with an OpenID:" remember: "Remember me:" lost password link: "Lost your password?" login_button: "Login" account not active: "Sorry, your account is not active yet.
Please click on the link in the account confirmation email to activate your account." + account suspended: Sorry, your account has been suspended due to suspicious activity.
Please contact the webmaster if you wish to discuss this. auth failure: "Sorry, could not log in with those details." + openid missing provider: "Sorry, could not contact your OpenID provider" + openid invalid: "Sorry, your OpenID seems misformed" + openid_logo_alt: "Log in with an OpenID" + openid_providers: + openid: + title: Login with an OpenID URL + alt: Login with an OpenID URL + yahoo: + title: Login with a Yahoo! OpenID + alt: Login with a Yahoo! OpenID + google: + title: Login with a Google OpenID + alt: Login with a Google OpenID + myopenid: + title: Login with a myOpenID OpenID + alt: Login with a myOpenID OpenID + wordpress: + title: Login with a Wordpress.com OpenID + alt: Login with a Wordpress.com OpenID + myspace: + title: Login with a MySpace OpenID + alt: Login with a MySpace OpenID logout: title: "Logout" heading: "Logout from OpenStreetMap" @@@ -1550,20 -1525,6 +1551,20 @@@ display name description: "Your publicly displayed username. You can change this later in the preferences." password: "Password:" confirm password: "Confirm Password:" + openID associate: "Associate an OpenID with your account" + openID: "OpenID:" + openID description: '(Optional) If you have an OpenID you can associate it with this account to login' + openID nopassword: "With OpenID, you don't need to specify a password during signup, but some extra OpenStreetMap services or tools may still need one" + openID association: | + Your OpenID is not associated with a OpenStreetMap account yet. + signup: Signup flash create success message: "User was successfully created. Check your email for a confirmation note, and you will be mapping in no time :-)

Please note that you will not be able to login until you've received and confirmed your email address.

If you use an antispam system which sends confirmation requests then please make sure you whitelist webmaster@openstreetmap.org as we are unable to reply to any confirmation requests." no_such_user: @@@ -1589,6 -1550,8 +1590,8 @@@ ago: "({{time_in_words_ago}} ago)" email address: "Email address:" created from: "Created from:" + status: "Status:" + spam score: "Spam Score:" description: Description user location: User location if set location: "If you set your location, a pretty map and stuff will appear here. You can set your home location on your {{settings_link}} page." @@@ -1613,6 -1576,7 +1616,7 @@@ create_block: "block this user" activate_user: "activate this user" deactivate_user: "deactivate this user" + confirm_user: "confirm this user" hide_user: "hide this user" unhide_user: "unhide this user" delete_user: "delete this user" @@@ -1627,10 -1591,6 +1631,10 @@@ current email address: "Current Email Address:" new email address: "New Email Address:" email never displayed publicly: "(never displayed publicly)" + openid: + openid: "OpenID:" + link: "http://wiki.openstreetmap.org/wiki/OpenID" + link text: "what is this?" public editing: heading: "Public editing:" enabled: "Enabled. Not anonymous and can edit data." @@@ -1684,6 -1644,30 +1688,30 @@@ not_a_friend: "{{name}} is not one of your friends." filter: not_an_administrator: "You need to be an administrator to perform that action." + list: + title: Users + heading: Users + showing: + one: Showing page {{page}} ({{first_item}} of {{items}}) + other: Showing page {{page}} ({{first_item}}-{{last_item}} of {{items}}) + summary: "{{name}} created from {{ip_address}} on {{date}}" + summary_no_ip: "{{name}} created on {{date}}" + confirm: Confirm Selected Users + hide: Hide Selected Users + empty: No matching users found + suspended: + title: Account Suspended + heading: Account Suspended + body: | +

+ Sorry, your account has been automatically suspended due to + suspicious activity. +

+

+ This decision will be reviewed by an administrator shortly, or + you may contact the webmaster if + you wish to discuss this. +

user_role: filter: not_an_administrator: "Only administrators can perform user role management, and you are not an administrator." diff --combined public/stylesheets/common.css index c92d748e2,73f0fb788..c61cf928b --- a/public/stylesheets/common.css +++ b/public/stylesheets/common.css @@@ -562,6 -562,27 +562,27 @@@ hr color: gray; } + /* Rules for the user list */ + + #user_list { + width: 100%; + font-size: small; + } + + #user_list tr { + vertical-align: center; + } + + #user_list p { + margin-top: 0px; + margin-bottom: 0px; + } + + #user_list_actions { + float: right; + margin-top: 10px; + } + /* Rules for the account settings page */ #accountForm td { @@@ -739,24 -760,3 +760,24 @@@ abbr.geo .table1 { background: #fff; } + +input.openid_url { + background: url('../images/openid-inputicon.gif') repeat-y left; + padding-left: 16px; +} + +/* Rules for Login page */ +.loginBox { + float: left; + width: 400px; + height: 200px; + margin-bottom: 40px; + border-style: solid; + border-width: 1px; + padding-left: 10px; + padding-right: 10px; +} + +.loginBox img { + border: 0; +} diff --combined test/fixtures/users.yml index 8c8577520,eb3c6ef6d..25b46f6f8 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@@ -2,7 -2,7 +2,7 @@@ normal_user: id: 1 email: test@openstreetmap.org - active: true + status: active pass_crypt: <%= Digest::MD5.hexdigest('test') %> creation_time: "2007-01-01 00:00:00" display_name: test @@@ -15,7 -15,7 +15,7 @@@ public_user: id: 2 email: test@example.com - active: true + status: active pass_crypt: <%= Digest::MD5.hexdigest('test') %> creation_time: "2008-05-01 01:23:45" display_name: test2 @@@ -28,7 -28,7 +28,7 @@@ inactive_user: id: 3 email: inactive@openstreetmap.org - active: false + status: pending pass_crypt: <%= Digest::MD5::hexdigest('test2') %> creation_time: "2008-07-01 02:23:45" display_name: Inactive User @@@ -41,7 -41,7 +41,7 @@@ second_public_user: id: 4 email: public@OpenStreetMap.org - active: true + status: active pass_crypt: <%= Digest::MD5.hexdigest('test') %> creation_time: "2008-05-01 01:23:45" display_name: pulibc_test2 @@@ -54,7 -54,7 +54,7 @@@ moderator_user: id: 5 email: moderator@example.com - active: true + status: active pass_crypt: <%= Digest::MD5.hexdigest('test') %> creation_time: "2008-05-01 01:23:45" display_name: moderator @@@ -63,18 -63,8 +63,18 @@@ administrator_user: id: 6 email: administrator@example.com - active: true + status: active pass_crypt: <%= Digest::MD5.hexdigest('test') %> creation_time: "2008-05-01 01:23:45" display_name: administrator data_public: true + +openid_user: + id: 7 + email: openid-user@example.com + active: true + pass_crypt: <%= Digest::MD5.hexdigest('test') %> + creation_time: "2008-05-01 01:23:45" + display_name: openIDuser + data_public: true + openid_url: http://localhost:1123/john.doe?openid.success=true