/// <summary>
 /// Gets the theme name for the given scope.  Does not return inherited value.
 /// </summary>
 public string GetThemeName(Scope scope)
 {
     AppService svc = AppServiceRepository.GetService();
     if (scope.IsCollection) return svc.GetCollection(scope.Workspace, scope.Collection).Theme;
     else if (scope.IsWorkspace) return svc.GetWorkspace(scope.Workspace).Theme;
     else return svc.Theme;
 }
 /// <summary>
 /// Gets the theme name by using fallback algrorithm of inheritance.
 /// </summary>
 /// <param name="scope"></param>
 /// <returns></returns>
 public string GetInheritedThemeName(Scope scope)
 {
     AppService svc = AppServiceRepository.GetService();
     string theme = null;
     if (scope.IsCollection) theme = svc.GetCollection(scope.Workspace, scope.Collection).Theme;
     if (theme == null && (scope.IsCollection || scope.IsWorkspace)) theme = svc.GetWorkspace(scope.Workspace).Theme;
     if (theme == null) theme = svc.Theme;
     if (theme == null) theme = "default";
     return theme;
 }
    /// <summary>
    /// Determines dynamically the collection, workspace, entry, and theme
    /// for the current request.
    /// </summary>
    /// <param name="ctx"></param>
    protected override void Execute(RequestContext ctx)
    {
      IContainer container = (IContainer)ctx.HttpContext.Application["Container"];
      appService = container.GetInstance<IAppServiceRepository>().GetService();
      LogService = container.GetInstance<ILogService>();
      AuthorizeService = container.GetInstance<IAuthorizeService>();
      //determine resource context based on routing data
      IRouteService r = RouteService.GetCurrent(ctx);
      if (EntryId == null) EntryId = r.GetEntryId();
      Scope = r.GetScope();
      base.Execute(ctx);

    }
    /// <summary>
    /// Gets all the roles for a user for the given scope.  The roles for the user are collected
    /// recursively by looking at the service, workspace, and collection levels.
    /// </summary>
    /// <param name="user"></param>
    /// <param name="id"></param>
    /// <returns></returns>
    public AuthRoles GetRoles(User user, Scope scope)
    {
      AppService appService = AppServiceRepository.GetService();
      AuthRoles roles = AuthRoles.None;
      if (user != null && user.IsAuthenticated)
      {
        roles |= AuthRoles.User; //all authenticated are users

        //if (scope.IsEntireSite)
        //{
          if (appService.Admins.Where(a => user.Ids.Select(i => i.ToUpperInvariant())
            .Contains(a.ToUpperInvariant())).SingleOrDefault() != null) roles |= AuthRoles.Administrator;
        //}
        //else
        if (!scope.IsEntireSite)
        {
          //get roles at workspace level
          AppWorkspace ws = appService.GetWorkspace(scope.Workspace);
          if (ws.Authors.Where(a => user.Ids.Select(i => i.ToUpperInvariant())
            .Contains(a.ToUpperInvariant())).SingleOrDefault() != null) roles |= AuthRoles.Author;
          if (ws.Contributors.Where(a => user.Ids.Select(i => i.ToUpperInvariant())
            .Contains(a.ToUpperInvariant())).SingleOrDefault() != null) roles |= AuthRoles.Contributor;

          if (scope.IsCollection) //continue at collection level getting scopes
          {
            AppCollection c = ws.GetCollection(scope.Collection);
            if (c.Authors.Where(a => user.Ids.Select(i => i.ToUpperInvariant())
            .Contains(a.ToUpperInvariant())).SingleOrDefault() != null)
              roles |= AuthRoles.Author;

            if (c.Contributors.Where(a => user.Ids.Select(i => i.ToUpperInvariant())
            .Contains(a.ToUpperInvariant())).SingleOrDefault() != null)
              roles |= AuthRoles.Contributor;
          }
        }
      }
      else
      {
        //all non-authenticated are anonymous
        roles |= AuthRoles.Anonymous;
      }
      return roles;
    }
    public AppService MoveInclude(Scope scope, string targetName, bool isPage, string areaName, int includeIdx, bool down)
    {
      if (!AuthorizeService.IsAuthorized(GetUser(), scope, AuthAction.UpdateServiceDoc))
        throw new UserNotAuthorizedException(GetUser().Name, "UpdateServiceDoc");

      LogService.Info("Moving {5} include at index {0} in area {1} of {2} named {3} in scope {4}.", includeIdx, areaName,
        isPage ? "page" : "widget", targetName, scope, down ? "down" : "up");

      AppService appSvc = AppServiceRepository.GetService();
      ServiceArea area = appSvc.GetArea(scope, targetName, isPage, areaName);
      var includes = area.Includes.ToList();

      if (includeIdx == 0 && !down) throw new Exception("This widget include is already at the top.");
      if (includeIdx == includes.Count - 1 && down) throw new Exception("This widget include is already at the bottom.");

      var include = includes.ElementAt(includeIdx);
      includes.Remove(include);
      int newIdx = includeIdx + (down ? 1 : -1);
      includes.Insert(newIdx, include);
      area.Includes = includes;
      AppServiceRepository.UpdateService(appSvc);
      return appSvc;
    }
    public AppService RemoveInclude(Scope scope, string targetName, bool isPage, string areaName, int includeIdx)
    {
      if (!AuthorizeService.IsAuthorized(GetUser(), scope, AuthAction.UpdateServiceDoc))
        throw new UserNotAuthorizedException(GetUser().Name, "UpdateServiceDoc");

      LogService.Info("Removing include at index {0} from area {1} of {2} named {3} in scope {4}.", includeIdx, areaName, isPage ? "page" : "widget", targetName, scope);

      AppService appSvc = AppServiceRepository.GetService();
      if (isPage)
      {
        appSvc.RemoveInclude<ServicePage>(scope, targetName, areaName, includeIdx);
      }
      else
      {
        appSvc.RemoveInclude<ServiceWidget>(scope, targetName, areaName, includeIdx);
      }

      AppServiceRepository.UpdateService(appSvc);
      return appSvc;
    }
    public AppService RemoveArea(Scope scope, string targetName, bool isPage, string areaName)
    {
      if (!AuthorizeService.IsAuthorized(GetUser(), scope, AuthAction.UpdateServiceDoc))
        throw new UserNotAuthorizedException(GetUser().Name, "UpdateServiceDoc");

      LogService.Info("Removing the area {0} from the {1} named {2} from scope {3}.", areaName, isPage ? "page" : "widget", targetName, scope);

      AppService appSvc = AppServiceRepository.GetService();
      if (isPage)
      {
        appSvc.RemoveArea<ServicePage>(scope, targetName, areaName);
      }
      else
      {
        appSvc.RemoveArea<ServiceWidget>(scope, targetName, areaName);
      }

      AppServiceRepository.UpdateService(appSvc);
      return appSvc;
    }
    public AppService AddTarget(Scope scope, string targetName, bool isPage)
    {
      if (!AuthorizeService.IsAuthorized(GetUser(), scope, AuthAction.UpdateServiceDoc))
        throw new UserNotAuthorizedException(GetUser().Name, "UpdateServiceDoc");

      LogService.Info("Adding the {0} named {1} to scope {2}.", isPage ? "page" : "widget", targetName, scope);

      AppService appSvc = AppServiceRepository.GetService();
      if (isPage)
      {
        appSvc.AddPage(scope, targetName);
      }
      else
      {
        appSvc.AddWidget(scope, targetName);
      }

      AppServiceRepository.UpdateService(appSvc);
      return appSvc;
    }
        public void SetTheme(Scope scope, string themeName)
        {
            //TODO: auth?
            AppService svc = AppServiceRepository.GetService();

            if (scope.IsEntireSite)
            {
                //for top level, when set to default, set to null since it is default
                if (themeName == "default") themeName = null;
                svc.Theme = themeName;
            }
            else if (scope.IsWorkspace) svc.GetWorkspace(scope.Workspace).Theme = themeName;
            else if (scope.IsCollection) svc.GetCollection(scope.Workspace, scope.Collection).Theme = themeName;

            AppServiceRepository.UpdateService(svc);
        }
        public ThemeSwitcherViewModel GetModel(HttpContextBase Context, Scope scope)
        {
            var themeNames = ThemeService.GetInstalledThemes();

            var currentTheme = (Context.Session != null && Context.Session["theme"] != null) ?
                                                                                 Context.Session["theme"].ToString() : ThemeService.GetInheritedThemeName(scope);

            var currentPageWidth = Context.Session != null && Context.Session["PageWidth"] != null ?
                                                                                       Context.Session["PageWidth"].ToString() : string.Empty;

            var currentPageTemplate = Context.Session != null && Context.Session["PageTemplate"] != null ?
                                                                                             Context.Session["PageTemplate"].ToString() : string.Empty;

            var themes = new List<Theme>(themeNames.Select(p => ThemeService.GetTheme(p)));

            var model = new ThemeSwitcherViewModel
            {
                ThemeNames = new SelectList(themes.Select(p => p.Name), currentTheme),
                Themes = new List<ThemeSwitcherThemeModel>(
                    themes.Select(theme =>
                                  new ThemeSwitcherThemeModel
                                  {
                                      ThemeName = theme.Name,
                                      Selected = theme.Name == currentTheme,
                                      PageTemplates = new SelectList(
                                          theme.Templates,
                                          currentTheme == theme.Name ? currentPageTemplate : string.Empty),
                                      PageWidths = new SelectList(
                                          theme.Widths,
                                          currentTheme == theme.Name ? currentPageWidth : string.Empty),
                                      Description = theme.Text.Text,
                                      Author = string.Format("<a href=\"{0}\" target=\"_blank\">{1}</a>", theme.Authors.First().Uri, theme.Authors.First().Name),
                                      Downloaded = GetDownloadCount(theme.Name),
                                      Customizations = GetCustomizations(theme)
                                  }))
            };

            return model;
        }
 public bool IsInRole(User user, Scope scope, AuthRoles role)
 {
   return (GetRoles(user, scope) & role) == role;
 }
    /// <summary>
    /// Gets whether any of the roles are authorized to perform the action within
    /// the given context based on the role matrix.  The role matrix
    /// is first checked at the collection level and then it bubbles up
    /// to the workspace level and onto the service level and then
    /// finally the default built-in role matrix.
    /// </summary>
    /// <param name="user">The user.</param>
    /// <param name="id">The entry Id or the collection Id.</param>
    /// <param name="action">The action.</param>
    /// <returns></returns>
    public bool IsAuthorized(AuthRoles roles, Scope scope, AuthAction action)
    {
      RoleMatrix rm = null;
      RoleAction ra = null;
      AppService appService = AppServiceRepository.GetService();

      if (!scope.IsEntireSite)
      {
        var w = appService.GetWorkspace(scope.Workspace);

        if (scope.IsCollection)
        {
          //try collection level first
          rm = w.GetCollection(scope.Collection).RoleMatrix;
          if (rm != null) ra = rm.RoleActions.Where(a => a.Name == action.ToString()).FirstOrDefault();
        }

        //try workspace level next
        if (ra == null)
        {
          rm = w.RoleMatrix;
          if (rm != null) ra = rm.RoleActions.Where(a => a.Name == action.ToString()).FirstOrDefault();
        }
      }

      //service level
      if (ra == null)
      {
        rm = appService.RoleMatrix;
        if (rm != null) ra = rm.RoleActions.Where(a => a.Name == action.ToString()).FirstOrDefault();
      }

      //use default role matrix
      if (ra == null)
      {
        rm = RoleMatrix.Default;
        if (rm != null) ra = rm.RoleActions.Where(a => a.Name == action.ToString()).FirstOrDefault();
      }

      if (ra == null)
      {
        LogService.Warn("Action not found in any role matrix.");
        return false;
      }

      return ((ra.AuthRoles & roles) > AuthRoles.None);
    }
 /// <summary>
 /// Gets whether the user is authorized to perform the action within
 /// the given context based on the role matrix.  The role matrix
 /// is first checked at the collection level and then it bubbles up
 /// to the workspace level and onto the service level and then
 /// finally the default built-in role matrix.
 /// </summary>
 /// <param name="user">The user.</param>
 /// <param name="id">The entry Id or the collection Id.</param>
 /// <param name="action">The action.</param>
 /// <returns></returns>
 public bool IsAuthorized(User user, Scope scope, AuthAction action)
 {
   return IsAuthorized(GetRoles(user, scope), scope, action);
 }
    private void LoadEntryConfig(EntryConfigModel m)
    {
      if (m.SelectedId != null)
      {
        var entry = AtomPubService.GetEntry(m.SelectedId);
        m.SelectedTitle = entry.Title.ToString();
      }

      m.Scopes = AuthorizeService.GetScopes(this.User.Identity as User);
      var scope = new Scope() { Workspace = m.CurrentWorkspace, Collection = m.CurrentCollection };
      if (m.CurrentWorkspace == null)
      {
        scope = m.Scopes.First();
        m.CurrentWorkspace = scope.Workspace;
        m.CurrentCollection = scope.Collection;
      }     

      m.Entries = AtomPubService.GetEntries(new EntryCriteria()
      {
        WorkspaceName = scope.Workspace,
        CollectionName = scope.Collection,
        Authorized = false,
        Published = true
      }, (m.Page ?? 1) - 1, 50);
    }
 public static void Auth(this IAuthorizeService auth, Scope scope, AuthAction action)
 {
   User user = System.Threading.Thread.CurrentPrincipal.Identity as User;
   if (!auth.IsAuthorized(auth.GetRoles(user, scope), scope, action))
     throw new UserNotAuthorizedException(user.Name, action.ToString());
 }