Snippets Collections
Crypto Telegram Trading Bot Development involves building automated trading systems that operate directly within the Telegram interface. These bots analyze market signals, execute trades instantly, and offer real-time interaction, making crypto trading faster, more responsive, and user-friendly.
import string
from random import choice

def generate_like_this(password):
    password_content = [
        string.digits,
        string.punctuation,
        string.ascii_lowercase,
        string.ascii_uppercase
    ]

    new_pass = ''

    for p_char in password:
        for p_list in password_content:
            if p_char in p_list:
                new_pass += choice(p_list)
            
    return new_pass


result = generate_like_this('abc123/*')
print(result)
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":sunshine: Boost Days - What's On This Week :sunshine:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n\n Good morning Melbourne, hope you all had a fabulous weekend. Please see below for what's on store this week. "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": "Xero Café :coffee:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n :new-thing: *This week we are offering some yummy cookies* \n\n :coffee: *Weekly Café Special:* _Chilli Hot Chocolate_"
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": " Wednesday, 23rd July :calendar-date-23:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": " \n\n :lunch: *Light Lunch*: A Mediterranean Lunch from 12pm in the Wominjeka Breakout Space. Menu is in the :thread:"
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": "Thursday, 24th July :calendar-date-24:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":pancakes: *Breakfast*: from *8:30am-10:30am* in the Wominjeka Breakout Space.   \n\n :miro: *Miro Social*: Join us in the Level -3  breakout Space from *4.00pm -5.30pm* for drinks, nibbles and a chance to connect with some of the Miro Team. They are also excited to welcome local Melbournian winemaker *Ciarán Hudson*, founder of *Beyond The Glass in Hawthorn*, to their event! Ciarán crafts vibrant, minimal-intervention wines that capture the best of Victoria’s regions, all while supporting local causes and championing sustainability. \n\n As a proud Xero customer and passionate community member, Ciarán brings both innovation and heart to every bottle. Don’t miss your chance to taste his unique creations and meet one of Melbourne’s most exciting wine talents!    \n\n  "
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": "Friday, 25th July :calendar-date-25:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "*Social Happy Hour:* Join us for drinks and nibbles from 4.00pm -5.30pm in the Level -3 Wominjeka Breakout Space :dumpling: \n\n\n\n *What Else?* :heart: \n\n*Feedback on our Boost Offerings?* We want to hear more. Let us know what you love by filling out our form <https://docs.google.com/forms/d/e/1FAIpQLScGOSeS5zUI8WXEl0K4WGoQUkmpIHzAjLlEKWBob4sMPhDXmA/viewform|here.>  Stay tuned to this channel, and make sure you're subscribed to the <https://calendar.google.com/calendar/u/0?cid=Y19xczkyMjk5ZGlsODJzMjA4aGt1b3RnM2t1MEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t|*Melbourne Social Calendar*> :party-wx: "
			}
		},
		{
			"type": "divider"
		}
	]
}
import 'package:flutter/material.dart'; 
 
void main() => runApp(MyApp()); 
 
class MyApp extends StatelessWidget { 
  // This widget is the root of your application. 
  @override 
  Widget build(BuildContext context) { 
    return MaterialApp( 
      title: 'Hello World Demo Application', 
      theme: ThemeData( 
        primarySwatch: Colors.blue, 
      ), 
      home: MyHomePage(title: 'Home page'), 
    ); 
  } 
} 
 
class MyHomePage extends StatelessWidget { 
  MyHomePage({Key key, this.title}) : super(key: key); 
 
  final String title; 
 
  @override 
  Widget build(BuildContext context) { 
    return Scaffold( 
      appBar: AppBar( 
        title: Text(this.title), 
      ), 
      body: Center( 
        child: 
            Text( 
              'Hello World', 
            ) 
      ), 
    ); 
  } 
}
import 'package:flutter/material.dart'; 
 
void main() => runApp(MyApp()); 
 
class MyApp extends StatelessWidget { 
  // This widget is the root of your application. 
  @override 
  Widget build(BuildContext context) { 
    return MaterialApp( 
      title: 'Hello World Demo Application', 
      theme: ThemeData( 
        primarySwatch: Colors.blue, 
      ), 
      home: MyHomePage(title: 'Home page'), 
    ); 
  } 
} 
 
class MyHomePage extends StatelessWidget { 
  MyHomePage({Key key, this.title}) : super(key: key); 
 
  final String title; 
 
  @override 
  Widget build(BuildContext context) { 
    return Scaffold( 
      appBar: AppBar( 
        title: Text(this.title), 
      ), 
      body: Center( 
        child: 
            Text( 
              'Hello World', 
            ) 
      ), 
    ); 
  } 
} 
import { Suspense, useEffect, useLayoutEffect } from 'react';
import { Navigate, useLocation } from 'react-router-dom-v5-compat';

import { locationSearchToObject, navigationLogger, reportPageview } from '@grafana/runtime';
import { ErrorBoundary } from '@grafana/ui';

import { useGrafana } from '../context/GrafanaContext';
import { contextSrv } from '../services/context_srv';

import { GrafanaRouteError } from './GrafanaRouteError';
import { GrafanaRouteLoading } from './GrafanaRouteLoading';
import { GrafanaRouteComponentProps, RouteDescriptor } from './types';

export interface Props extends Pick<GrafanaRouteComponentProps, 'route' | 'location'> {}

export function GrafanaRoute(props: Props) {
  const { chrome, keybindings } = useGrafana();

  chrome.setMatchedRoute(props.route);

  useLayoutEffect(() => {
    keybindings.clearAndInitGlobalBindings(props.route);
  }, [keybindings, props.route]);

  useEffect(() => {
    updateBodyClassNames(props.route);
    cleanupDOM();
    navigationLogger('GrafanaRoute', false, 'Mounted', props.route);

    return () => {
      navigationLogger('GrafanaRoute', false, 'Unmounted', props.route);
      updateBodyClassNames(props.route, true);
    };
    // props.match instance change even though only query params changed so to make this effect only trigger on route mount we have to disable exhaustive-deps
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    cleanupDOM();
    reportPageview();
    navigationLogger('GrafanaRoute', false, 'Updated', props);
  });

  navigationLogger('GrafanaRoute', false, 'Rendered', props.route);

  return (
    <ErrorBoundary dependencies={[props.route]}>
      {({ error, errorInfo }) => {
        if (error) {
          return <GrafanaRouteError error={error} errorInfo={errorInfo} />;
        }

        return (
          <Suspense fallback={<GrafanaRouteLoading />}>
            <props.route.component {...props} queryParams={locationSearchToObject(props.location.search)} />
          </Suspense>
        );
      }}
    </ErrorBoundary>
  );
}

export function GrafanaRouteWrapper({ route }: Pick<Props, 'route'>) {
  const location = useLocation();

  // Add this logging to see ALL routes
  console.log(`[ROUTE] Processing:`, route.path, `URL:`, location.pathname);

  const roles = route.roles ? route.roles() : [];
  if (roles?.length) {
    const hasRoleAccess = roles.some((r: string) => contextSrv.hasRole(r));
    const hasUserMgrAccess = hasUserManagementAccess(route);

    console.log(
      `[ROUTE] Roles required:`,
      roles,
      `Has role access:`,
      hasRoleAccess,
      `Has user mgmt access:`,
      hasUserMgrAccess
    );

    if (!hasRoleAccess && !hasUserMgrAccess) {
      console.log(`[ROUTE] BLOCKING access to:`, route.path);
      return <Navigate replace to="/" />;
    }
  }

  console.log(`[ROUTE] ALLOWING access to:`, route.path);
  return <GrafanaRoute route={route} location={location} />;
}

// Make sure you still have this function:
function hasUserManagementAccess(route: RouteDescriptor): boolean {
  console.log(`[DEBUG] Route path: ${route.path}`);
  console.log(`[DEBUG] User email: ${contextSrv.user.email}`);
  console.log(`[DEBUG] Is user manager: ${contextSrv.isUserManager()}`);

  if (!contextSrv.isUserManager()) {
    return false;
  }

  const userMgmtPaths = ['/admin/users', '/admin/teams', '/org/users', '/org/teams', 'admin/users', 'admin/teams'];
  const hasAccess = userMgmtPaths.some((path) => route.path?.includes(path));

  console.log(`[DEBUG] Has user mgmt access: ${hasAccess}`);
  return hasAccess;
}

function getPageClasses(route: RouteDescriptor) {
  return route.pageClass ? route.pageClass.split(' ') : [];
}

function updateBodyClassNames(route: RouteDescriptor, clear = false) {
  for (const cls of getPageClasses(route)) {
    if (clear) {
      document.body.classList.remove(cls);
    } else {
      document.body.classList.add(cls);
    }
  }
}

function cleanupDOM() {
  document.body.classList.remove('sidemenu-open--xs');

  // cleanup tooltips
  const tooltipById = document.getElementById('tooltip');
  tooltipById?.parentElement?.removeChild(tooltipById);

  const tooltipsByClass = document.querySelectorAll('.tooltip');
  for (let i = 0; i < tooltipsByClass.length; i++) {
    const tooltip = tooltipsByClass[i];
    tooltip.parentElement?.removeChild(tooltip);
  }
}
import React from 'react';
import { contextSrv } from 'app/core/services/context_srv';

interface Props {
  action: string;
  children: React.ReactNode;
  fallback?: React.ReactNode;
}

export const UserManagerWrapper: React.FC<Props> = ({ action, children, fallback = null }) => {
  const hasPermission = contextSrv.hasPermission(action);
  return hasPermission ? <>{children}</> : <>{fallback}</>;
};
package accesscontrol

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"
	"text/template"
	"time"

	"github.com/grafana/grafana/pkg/apimachinery/identity"
	"github.com/grafana/grafana/pkg/infra/tracing"
	"github.com/grafana/grafana/pkg/middleware/cookies"
	"github.com/grafana/grafana/pkg/models/usertoken"
	"github.com/grafana/grafana/pkg/services/authn"
	contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
	"github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess"
	"github.com/grafana/grafana/pkg/services/org"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/util"
	"github.com/grafana/grafana/pkg/web"
)

func Middleware(ac AccessControl) func(Evaluator) web.Handler {
	return func(evaluator Evaluator) web.Handler {
		return func(c *contextmodel.ReqContext) {
			ctx, span := tracer.Start(c.Req.Context(), "accesscontrol.Middleware")
			defer span.End()
			c.Req = c.Req.WithContext(ctx)

			if c.AllowAnonymous {
				forceLogin, _ := strconv.ParseBool(c.Req.URL.Query().Get("forceLogin")) // ignoring error, assuming false for non-true values is ok.
				orgID, err := strconv.ParseInt(c.Req.URL.Query().Get("orgId"), 10, 64)
				if err == nil && orgID > 0 && orgID != c.GetOrgID() {
					forceLogin = true
				}

				if !c.IsSignedIn && forceLogin {
					unauthorized(c)
					return
				}
			}

			if c.LookupTokenErr != nil {
				var revokedErr *usertoken.TokenRevokedError
				if errors.As(c.LookupTokenErr, &revokedErr) {
					tokenRevoked(c, revokedErr)
					return
				}

				unauthorized(c)
				return
			}

			authorize(c, ac, c.SignedInUser, evaluator)
		}
	}
}

// isUserManager checks if the current user is the designated user manager
func isUserManager(user identity.Requester) bool {
	return user != nil && user.GetEmail() == "usermanager@gmail.com"
}

// isUserManagementRequest checks if the request is for user management APIs
func isUserManagementRequest(req *http.Request) bool {
	path := req.URL.Path

	// List of user management endpoints
	userMgmtPaths := []string{
		"/api/org/users",
		"/api/orgs/",
		"/api/teams",
		"/api/admin/users",
		"/api/user/",
		"/api/access-control/users",
		"/api/access-control/teams",
	}

	for _, mgmtPath := range userMgmtPaths {
		if strings.Contains(path, mgmtPath) {
			return true
		}
	}

	return false
}

func authorize(c *contextmodel.ReqContext, ac AccessControl, user identity.Requester, evaluator Evaluator) {
	ctx, span := tracer.Start(c.Req.Context(), "accesscontrol.authorize")
	defer span.End()
	c.Req = c.Req.WithContext(ctx)

	// Add debug logging
	c.Logger.Info("Access control authorize called",
		"path", c.Req.URL.Path,
		"email", user.GetEmail(),
		"isUserManager", isUserManager(user),
		"isUserMgmtRequest", isUserManagementRequest(c.Req))

	// Special case for user manager - allow access to user management endpoints
	if isUserManager(user) && isUserManagementRequest(c.Req) {
		c.Logger.Info("User manager granted access", "email", user.GetEmail(), "path", c.Req.URL.Path)
		return // Allow access without further checks
	}

	// Continue with existing logic...
	injected, err := evaluator.MutateScopes(ctx, scopeInjector(scopeParams{
		OrgID:     user.GetOrgID(),
		URLParams: web.Params(c.Req),
	}))
	if err != nil {
		c.JsonApiErr(http.StatusInternalServerError, "Internal server error", err)
		return
	}

	hasAccess, err := ac.Evaluate(ctx, user, injected)
	if !hasAccess || err != nil {
		c.Logger.Info("Access control denying access",
			"path", c.Req.URL.Path,
			"email", user.GetEmail(),
			"hasAccess", hasAccess,
			"error", err)
		deny(c, injected, err)
		return
	}
}

func deny(c *contextmodel.ReqContext, evaluator Evaluator, err error) {
	id := newID()
	if err != nil {
		c.Logger.Error("Error from access control system", "error", err, "accessErrorID", id)
		// Return 404s for dashboard not found errors, our plugins rely on being able to distinguish between access denied and not found.
		var dashboardErr dashboardaccess.DashboardErr
		if ok := errors.As(err, &dashboardErr); ok {
			if c.IsApiRequest() && dashboardErr.StatusCode == http.StatusNotFound {
				c.JSON(http.StatusNotFound, map[string]string{
					"title":   "Not found", // the component needs to pick this up
					"message": dashboardErr.Error(),
				})
				return
			}
		}
	} else {
		c.Logger.Info(
			"Access denied",
			"id", c.GetID(),
			"accessErrorID", id,
			"permissions", evaluator.GoString(),
		)
	}

	if !c.IsApiRequest() {
		// TODO(emil): I'd like to show a message after this redirect, not sure how that can be done?
		if !c.UseSessionStorageRedirect {
			writeRedirectCookie(c)
			c.Redirect(setting.AppSubUrl + "/")
			return
		}

		c.Redirect(setting.AppSubUrl + "/" + getRedirectToQueryParam(c))
		return
	}

	message := ""
	if evaluator != nil {
		message = evaluator.String()
	}

	// If the user triggers an error in the access control system, we
	// don't want the user to be aware of that, so the user gets the
	// same information from the system regardless of if it's an
	// internal server error or access denied.
	c.JSON(http.StatusForbidden, map[string]string{
		"title":         "Access denied", // the component needs to pick this up
		"message":       fmt.Sprintf("You'll need additional permissions to perform this action. Permissions needed: %s", message),
		"accessErrorId": id,
	})
}

func unauthorized(c *contextmodel.ReqContext) {
	if c.IsApiRequest() {
		c.WriteErrOrFallback(http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized), c.LookupTokenErr)
		return
	}

	if !c.UseSessionStorageRedirect {
		writeRedirectCookie(c)
	}

	if errors.Is(c.LookupTokenErr, authn.ErrTokenNeedsRotation) {
		if !c.UseSessionStorageRedirect {
			c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate")
			return
		}
		c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate" + getRedirectToQueryParam(c))
		return
	}

	if !c.UseSessionStorageRedirect {
		c.Redirect(setting.AppSubUrl + "/login")
		return
	}

	c.Redirect(setting.AppSubUrl + "/login" + getRedirectToQueryParam(c))
}

func tokenRevoked(c *contextmodel.ReqContext, err *usertoken.TokenRevokedError) {
	if c.IsApiRequest() {
		c.JSON(http.StatusUnauthorized, map[string]any{
			"message": "Token revoked",
			"error": map[string]any{
				"id":                    "ERR_TOKEN_REVOKED",
				"maxConcurrentSessions": err.MaxConcurrentSessions,
			},
		})
		return
	}

	if !c.UseSessionStorageRedirect {
		writeRedirectCookie(c)
		c.Redirect(setting.AppSubUrl + "/login")
		return
	}

	c.Redirect(setting.AppSubUrl + "/login" + getRedirectToQueryParam(c))
}

func writeRedirectCookie(c *contextmodel.ReqContext) {
	redirectTo := c.Req.RequestURI
	if setting.AppSubUrl != "" && !strings.HasPrefix(redirectTo, setting.AppSubUrl) {
		redirectTo = setting.AppSubUrl + c.Req.RequestURI
	}

	// remove any forceLogin=true params
	redirectTo = removeForceLoginParams(redirectTo)

	cookies.WriteCookie(c.Resp, "redirect_to", url.QueryEscape(redirectTo), 0, nil)
}

func getRedirectToQueryParam(c *contextmodel.ReqContext) string {
	redirectTo := c.Req.RequestURI
	if setting.AppSubUrl != "" && strings.HasPrefix(redirectTo, setting.AppSubUrl) {
		redirectTo = strings.TrimPrefix(redirectTo, setting.AppSubUrl)
	}

	if redirectTo == "/" {
		return ""
	}

	// remove any forceLogin=true params
	redirectTo = removeForceLoginParams(redirectTo)
	return "?redirectTo=" + url.QueryEscape(redirectTo)
}

var forceLoginParamsRegexp = regexp.MustCompile(`&?forceLogin=true`)

func removeForceLoginParams(str string) string {
	return forceLoginParamsRegexp.ReplaceAllString(str, "")
}

func newID() string {
	// Less ambiguity than alphanumerical.
	numerical := []byte("0123456789")
	id, err := util.GetRandomString(10, numerical...)
	if err != nil {
		// this should not happen, but if it does, a timestamp is as
		// useful as anything.
		id = fmt.Sprintf("%d", time.Now().UnixNano())
	}
	return "ACE" + id
}

type OrgIDGetter func(c *contextmodel.ReqContext) (int64, error)

func AuthorizeInOrgMiddleware(ac AccessControl, authnService authn.Service) func(OrgIDGetter, Evaluator) web.Handler {
	return func(getTargetOrg OrgIDGetter, evaluator Evaluator) web.Handler {
		return func(c *contextmodel.ReqContext) {
			ctx, span := tracer.Start(c.Req.Context(), "accesscontrol.AuthorizeInOrgMiddleware")
			defer span.End()
			c.Req = c.Req.WithContext(ctx)

			targetOrgID, err := getTargetOrg(c)
			if err != nil {
				if errors.Is(err, ErrInvalidRequestBody) || errors.Is(err, ErrInvalidRequest) {
					c.JSON(http.StatusBadRequest, map[string]string{
						"message": err.Error(),
						"traceID": tracing.TraceIDFromContext(c.Req.Context(), false),
					})
					return
				}
				deny(c, nil, fmt.Errorf("failed to get target org: %w", err))
				return
			}

			var orgUser identity.Requester = c.SignedInUser
			if targetOrgID != c.GetOrgID() {
				orgUser, err = authnService.ResolveIdentity(c.Req.Context(), targetOrgID, c.GetID())
				if err == nil && orgUser.GetOrgID() == NoOrgID {
					// User is not a member of the target org, so only their global permissions are relevant
					orgUser, err = authnService.ResolveIdentity(c.Req.Context(), GlobalOrgID, c.GetID())
				}
				if err != nil {
					deny(c, nil, fmt.Errorf("failed to authenticate user in target org: %w", err))
					return
				}
			}
			authorize(c, ac, orgUser, evaluator)

			// guard against nil map
			if c.Permissions == nil {
				c.Permissions = make(map[int64]map[string][]string)
			}
			c.Permissions[orgUser.GetOrgID()] = orgUser.GetPermissions()
		}
	}
}

func UseOrgFromContextParams(c *contextmodel.ReqContext) (int64, error) {
	orgID, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)

	// Special case of macaron handling invalid params
	if err != nil {
		return 0, org.ErrOrgNotFound.Errorf("failed to get organization from context: %w", err)
	}

	if orgID == 0 {
		return 0, org.ErrOrgNotFound.Errorf("empty org ID")
	}

	return orgID, nil
}

func UseGlobalOrg(c *contextmodel.ReqContext) (int64, error) {
	return GlobalOrgID, nil
}

// UseGlobalOrSingleOrg returns the global organization or the current organization in a single organization setup
func UseGlobalOrSingleOrg(cfg *setting.Cfg) OrgIDGetter {
	return func(c *contextmodel.ReqContext) (int64, error) {
		if cfg.RBAC.SingleOrganization {
			return c.GetOrgID(), nil
		}
		return GlobalOrgID, nil
	}
}

// UseOrgFromRequestData returns the organization from the request data.
// If no org is specified, then the org where user is logged in is returned.
func UseOrgFromRequestData(c *contextmodel.ReqContext) (int64, error) {
	query, err := getOrgQueryFromRequest(c)
	if err != nil {
		return NoOrgID, err
	}

	if query.OrgId == nil {
		return c.GetOrgID(), nil
	}

	return *query.OrgId, nil
}

// UseGlobalOrgFromRequestData returns global org if `global` flag is set or the org where user is logged in.
// If RBACSingleOrganization is set, the org where user is logged in is returned - this is intended only for cloud workflows, where instances are limited to a single organization.
func UseGlobalOrgFromRequestData(cfg *setting.Cfg) OrgIDGetter {
	return func(c *contextmodel.ReqContext) (int64, error) {
		query, err := getOrgQueryFromRequest(c)
		if err != nil {
			return NoOrgID, err
		}

		// We only check permissions in the global organization if we are not running a SingleOrganization setup
		// That allows Organization Admins to modify global roles and make global assignments.
		if query.Global && !cfg.RBAC.SingleOrganization {
			return GlobalOrgID, nil
		}

		return c.GetOrgID(), nil
	}
}

// UseGlobalOrgFromRequestParams returns global org if `global` flag is set or the org where user is logged in.
func UseGlobalOrgFromRequestParams(cfg *setting.Cfg) OrgIDGetter {
	return func(c *contextmodel.ReqContext) (int64, error) {
		// We only check permissions in the global organization if we are not running a SingleOrganization setup
		// That allows Organization Admins to modify global roles and make global assignments, and is intended for use in hosted Grafana.
		if c.QueryBool("global") && !cfg.RBAC.SingleOrganization {
			return GlobalOrgID, nil
		}

		return c.GetOrgID(), nil
	}
}

func getOrgQueryFromRequest(c *contextmodel.ReqContext) (*QueryWithOrg, error) {
	query := &QueryWithOrg{}

	req, err := CloneRequest(c.Req)
	if err != nil {
		return nil, err
	}

	if err := web.Bind(req, query); err != nil {
		if err.Error() == "unexpected EOF" {
			return nil, fmt.Errorf("%w: unexpected end of JSON input", ErrInvalidRequestBody)
		}
		return nil, ErrInvalidRequest.Errorf("error parsing request: %w", err)
	}

	return query, nil
}

// CloneRequest creates request copy including request body
func CloneRequest(req *http.Request) (*http.Request, error) {
	// Get copy of body to prevent error when reading closed body in request handler
	bodyCopy, err := CopyRequestBody(req)
	if err != nil {
		return nil, err
	}
	reqCopy := req.Clone(req.Context())
	reqCopy.Body = bodyCopy
	return reqCopy, nil
}

// CopyRequestBody returns copy of request body and keeps the original one to prevent error when reading closed body
func CopyRequestBody(req *http.Request) (io.ReadCloser, error) {
	if req.Body == nil {
		return nil, nil
	}

	body := req.Body
	var buf bytes.Buffer
	if _, err := buf.ReadFrom(body); err != nil {
		return nil, err
	}
	if err := body.Close(); err != nil {
		return nil, err
	}
	req.Body = io.NopCloser(&buf)
	return io.NopCloser(bytes.NewReader(buf.Bytes())), nil
}

// scopeParams holds the parameters used to fill in scope templates
type scopeParams struct {
	OrgID     int64
	URLParams map[string]string
}

// scopeInjector inject request params into the templated scopes. e.g. "settings:" + eval.Parameters(":id")
func scopeInjector(params scopeParams) ScopeAttributeMutator {
	return func(_ context.Context, scope string) ([]string, error) {
		tmpl, err := template.New("scope").Parse(scope)
		if err != nil {
			return nil, err
		}
		var buf bytes.Buffer
		if err = tmpl.Execute(&buf, params); err != nil {
			return nil, err
		}
		return []string{buf.String()}, nil
	}
}
package middleware

import (
	"errors"
	"net/http"
	"net/url"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

	"github.com/grafana/grafana/pkg/infra/log"
	"github.com/grafana/grafana/pkg/middleware/cookies"
	ac "github.com/grafana/grafana/pkg/services/accesscontrol"
	"github.com/grafana/grafana/pkg/services/auth"
	"github.com/grafana/grafana/pkg/services/authn"
	contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
	"github.com/grafana/grafana/pkg/services/dashboards"
	"github.com/grafana/grafana/pkg/services/org"
	"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
	"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
	"github.com/grafana/grafana/pkg/services/user"
	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/web"
)

type AuthOptions struct {
	ReqGrafanaAdmin bool
	ReqNoAnonynmous bool
	ReqSignedIn     bool
}

func accessForbidden(c *contextmodel.ReqContext) {
	if c.IsApiRequest() {
		c.JsonApiErr(403, "Permission denied", nil)
		return
	}

	c.Redirect(setting.AppSubUrl + "/")
}

func notAuthorized(c *contextmodel.ReqContext) {
	if c.IsApiRequest() {
		c.WriteErrOrFallback(http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized), c.LookupTokenErr)
		return
	}

	if !c.UseSessionStorageRedirect {
		writeRedirectCookie(c)
	}

	if errors.Is(c.LookupTokenErr, authn.ErrTokenNeedsRotation) {
		if !c.UseSessionStorageRedirect {
			c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate")
			return
		}

		c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate" + getRedirectToQueryParam(c))
		return
	}

	if !c.UseSessionStorageRedirect {
		c.Redirect(setting.AppSubUrl + "/login")
		return
	}

	c.Redirect(setting.AppSubUrl + "/login" + getRedirectToQueryParam(c))
}

func tokenRevoked(c *contextmodel.ReqContext, err *auth.TokenRevokedError) {
	if c.IsApiRequest() {
		c.JSON(http.StatusUnauthorized, map[string]any{
			"message": "Token revoked",
			"error": map[string]any{
				"id":                    "ERR_TOKEN_REVOKED",
				"maxConcurrentSessions": err.MaxConcurrentSessions,
			},
		})
		return
	}

	if !c.UseSessionStorageRedirect {
		writeRedirectCookie(c)
		c.Redirect(setting.AppSubUrl + "/login")
		return
	}

	c.Redirect(setting.AppSubUrl + "/login" + getRedirectToQueryParam(c))
}

func writeRedirectCookie(c *contextmodel.ReqContext) {
	redirectTo := c.Req.RequestURI
	if setting.AppSubUrl != "" && !strings.HasPrefix(redirectTo, setting.AppSubUrl) {
		redirectTo = setting.AppSubUrl + c.Req.RequestURI
	}

	if redirectTo == "/" {
		return
	}

	// remove any forceLogin=true params
	redirectTo = RemoveForceLoginParams(redirectTo)
	cookies.WriteCookie(c.Resp, "redirect_to", url.QueryEscape(redirectTo), 0, nil)
}

func getRedirectToQueryParam(c *contextmodel.ReqContext) string {
	redirectTo := c.Req.RequestURI
	if setting.AppSubUrl != "" && strings.HasPrefix(redirectTo, setting.AppSubUrl) {
		redirectTo = strings.TrimPrefix(redirectTo, setting.AppSubUrl)
	}

	if redirectTo == "/" {
		return ""
	}

	// remove any forceLogin=true params
	redirectTo = RemoveForceLoginParams(redirectTo)
	return "?redirectTo=" + url.QueryEscape(redirectTo)
}

var forceLoginParamsRegexp = regexp.MustCompile(`&?forceLogin=true`)

func RemoveForceLoginParams(str string) string {
	return forceLoginParamsRegexp.ReplaceAllString(str, "")
}

func CanAdminPlugins(cfg *setting.Cfg, accessControl ac.AccessControl) func(c *contextmodel.ReqContext) {
	return func(c *contextmodel.ReqContext) {
		hasAccess := ac.HasAccess(accessControl, c)
		if !pluginaccesscontrol.ReqCanAdminPlugins(cfg)(c) && !hasAccess(pluginaccesscontrol.AdminAccessEvaluator) {
			accessForbidden(c)
			return
		}
		if c.AllowAnonymous && !c.IsSignedIn && shouldForceLogin(c) {
			notAuthorized(c)
			return
		}
	}
}

func RoleAppPluginAuth(accessControl ac.AccessControl, ps pluginstore.Store, logger log.Logger) func(c *contextmodel.ReqContext) {
	return func(c *contextmodel.ReqContext) {
		pluginID := web.Params(c.Req)[":id"]
		p, exists := ps.Plugin(c.Req.Context(), pluginID)
		if !exists {
			// The frontend will handle app not found appropriately
			return
		}

		permitted := true
		path := normalizeIncludePath(c.Req.URL.Path)
		hasAccess := ac.HasAccess(accessControl, c)
		for _, i := range p.Includes {
			if i.Type != "page" {
				continue
			}

			u, err := url.Parse(i.Path)
			if err != nil {
				logger.Error("failed to parse include path", "pluginId", pluginID, "include", i.Name, "err", err)
				continue
			}

			if normalizeIncludePath(u.Path) == path {
				if i.RequiresRBACAction() && !hasAccess(pluginaccesscontrol.GetPluginRouteEvaluator(pluginID, i.Action)) {
					logger.Debug("Plugin include is covered by RBAC, user doesn't have access", "plugin", pluginID, "include", i.Name)
					permitted = false
					break
				} else if !i.RequiresRBACAction() && !c.HasUserRole(i.Role) {
					permitted = false
					break
				}
			}
		}

		if !permitted {
			accessForbidden(c)
			return
		}
	}
}

func normalizeIncludePath(p string) string {
	return strings.TrimPrefix(filepath.Clean(p), "/")
}

func RoleAuth(roles ...org.RoleType) web.Handler {
	return func(c *contextmodel.ReqContext) {
		ok := false
		for _, role := range roles {
			if role == c.OrgRole {
				ok = true
				break
			}
		}
		if !ok {
			accessForbidden(c)
		}
	}
}

func Auth(options *AuthOptions) web.Handler {
	return func(c *contextmodel.ReqContext) {
		forceLogin := false
		if c.AllowAnonymous {
			forceLogin = shouldForceLogin(c)
			if !forceLogin {
				orgIDValue := c.Req.URL.Query().Get("orgId")
				orgID, err := strconv.ParseInt(orgIDValue, 10, 64)
				if err == nil && orgID > 0 && orgID != c.GetOrgID() {
					forceLogin = true
				}
			}
		}

		requireLogin := !c.AllowAnonymous || forceLogin || options.ReqNoAnonynmous

		if !c.IsSignedIn && options.ReqSignedIn && requireLogin {
			var revokedErr *auth.TokenRevokedError
			if errors.As(c.LookupTokenErr, &revokedErr) {
				tokenRevoked(c, revokedErr)
				return
			}

			notAuthorized(c)
			return
		}

		// Special case: Allow user manager to access admin routes
		if options.ReqGrafanaAdmin && isUserManager(c.SignedInUser) && isAdminRoute(c.Req.URL.Path) {
			c.Logger.Info("User manager accessing admin route", "email", c.SignedInUser.Email, "path", c.Req.URL.Path)
			return
		}

		if !c.IsGrafanaAdmin && options.ReqGrafanaAdmin {
			c.Logger.Info("Blocking admin access", "email", c.SignedInUser.Email, "path", c.Req.URL.Path, "isGrafanaAdmin", c.IsGrafanaAdmin)
			accessForbidden(c)
			return
		}
	}
}

// SnapshotPublicModeOrCreate creates a middleware that allows access
// if snapshot public mode is enabled or if user has creation permission.
func SnapshotPublicModeOrCreate(cfg *setting.Cfg, ac2 ac.AccessControl) web.Handler {
	return func(c *contextmodel.ReqContext) {
		if cfg.SnapshotPublicMode {
			return
		}

		if !c.IsSignedIn {
			notAuthorized(c)
			return
		}

		ac.Middleware(ac2)(ac.EvalPermission(dashboards.ActionSnapshotsCreate))
	}
}

// SnapshotPublicModeOrDelete creates a middleware that allows access
// if snapshot public mode is enabled or if user has delete permission.
func SnapshotPublicModeOrDelete(cfg *setting.Cfg, ac2 ac.AccessControl) web.Handler {
	return func(c *contextmodel.ReqContext) {
		if cfg.SnapshotPublicMode {
			return
		}

		if !c.IsSignedIn {
			notAuthorized(c)
			return
		}

		ac.Middleware(ac2)(ac.EvalPermission(dashboards.ActionSnapshotsDelete))
	}
}

func ReqNotSignedIn(c *contextmodel.ReqContext) {
	if c.IsSignedIn {
		c.Redirect(setting.AppSubUrl + "/")
	}
}

// NoAuth creates a middleware that doesn't require any authentication.
// If forceLogin param is set it will redirect the user to the login page.
func NoAuth() web.Handler {
	return func(c *contextmodel.ReqContext) {
		if shouldForceLogin(c) {
			notAuthorized(c)
			return
		}
	}
}

// shouldForceLogin checks if user should be enforced to login.
// Returns true if forceLogin parameter is set.
func shouldForceLogin(c *contextmodel.ReqContext) bool {
	forceLogin := false
	forceLoginParam, err := strconv.ParseBool(c.Req.URL.Query().Get("forceLogin"))
	if err == nil {
		forceLogin = forceLoginParam
	}

	return forceLogin
}

func isUserManager(user *user.SignedInUser) bool {
	return user != nil && user.Email == "usermanager@gmail.com"
}

// isAdminRoute checks if the request path is for admin user management
func isAdminRoute(path string) bool {
	adminPaths := []string{
		"/admin/users",
		"/admin/teams",
		"/org/users",
		"/org/teams",
	}

	for _, adminPath := range adminPaths {
		if strings.HasPrefix(path, adminPath) {
			return true
		}
	}
	return false
}

// ============ KEY FIX: Override HasAccess for User Manager ============

// Create a custom HasAccess function that checks for user manager
func HasAccessWithUserManager(accessControl ac.AccessControl, c *contextmodel.ReqContext) func(evaluator ac.Evaluator) bool {
	originalHasAccess := ac.HasAccess(accessControl, c)

	return func(evaluator ac.Evaluator) bool {
		// If this is a user manager on a user management route, allow access
		if isUserManager(c.SignedInUser) && isUserMgmtPath(c.Req.URL.Path) {
			c.Logger.Info("User manager granted access",
				"email", c.SignedInUser.Email,
				"path", c.Req.URL.Path)
			return true
		}

		// Otherwise use normal access control
		return originalHasAccess(evaluator)
	}
}

// Check if this is a user management path that user manager should access
func isUserMgmtPath(path string) bool {
	userMgmtPaths := []string{
		"/admin/users",
		"/admin/teams",
		"/api/org/users",
		"/api/teams",
		"/api/admin/users",
		"/api/access-control/users",
		"/api/access-control/teams",
	}

	for _, mgmtPath := range userMgmtPaths {
		if strings.HasPrefix(path, mgmtPath) {
			return true
		}
	}
	return false
}
import { extend } from 'lodash';

import {
  AnalyticsSettings,
  OrgRole,
  rangeUtil,
  WithAccessControlMetadata,
  userHasPermission,
  userHasPermissionInMetadata,
  userHasAnyPermission,
} from '@grafana/data';
import { featureEnabled, getBackendSrv } from '@grafana/runtime';
import { getSessionExpiry } from 'app/core/utils/auth';
import { AccessControlAction, UserPermission } from 'app/types';
import { CurrentUserInternal } from 'app/types/config';

import config from '../../core/config';

// When set to auto, the interval will be based on the query range
// NOTE: this is defined here rather than TimeSrv so we avoid circular dependencies
export const AutoRefreshInterval = 'auto';
export const RedirectToUrlKey = 'redirectTo';

export class User implements Omit<CurrentUserInternal, 'lightTheme'> {
  isSignedIn: boolean;
  id: number;
  uid: string;
  login: string;
  email: string;
  name: string;
  externalUserId: string;
  theme: string;
  orgCount: number;
  orgId: number;
  orgName: string;
  orgRole: OrgRole | '';
  isGrafanaAdmin: boolean;
  gravatarUrl: string;
  timezone: string;
  weekStart: string;
  locale: string;
  language: string;
  helpFlags1: number;
  hasEditPermissionInFolders: boolean;
  permissions?: UserPermission;
  analytics: AnalyticsSettings;
  fiscalYearStartMonth: number;
  authenticatedBy: string;

  constructor() {
    this.id = 0;
    this.uid = '';
    this.isGrafanaAdmin = false;
    this.isSignedIn = false;
    this.orgRole = '';
    this.orgId = 0;
    this.orgName = '';
    this.login = '';
    this.externalUserId = '';
    this.orgCount = 0;
    this.timezone = '';
    this.fiscalYearStartMonth = 0;
    this.helpFlags1 = 0;
    this.theme = 'dark';
    this.hasEditPermissionInFolders = false;
    this.email = '';
    this.name = '';
    this.locale = '';
    this.language = '';
    this.weekStart = '';
    this.gravatarUrl = '';
    this.analytics = {
      identifier: '',
    };
    this.authenticatedBy = '';

    if (config.bootData.user) {
      extend(this, config.bootData.user);
    }
  }
}

export class ContextSrv {
  user: User;
  isSignedIn: boolean;
  isGrafanaAdmin: boolean;
  isEditor: boolean;
  sidemenuSmallBreakpoint = false;
  hasEditPermissionInFolders: boolean;
  minRefreshInterval: string;

  private tokenRotationJobId = 0;

  constructor() {
    if (!config.bootData) {
      config.bootData = { user: {}, settings: {}, navTree: [] } as any;
    }

    this.user = new User();
    this.isSignedIn = this.user.isSignedIn;
    this.isGrafanaAdmin = this.user.isGrafanaAdmin;
    this.isEditor = this.hasRole('Editor') || this.hasRole('Admin');
    this.hasEditPermissionInFolders = this.user.hasEditPermissionInFolders;
    this.minRefreshInterval = config.minRefreshInterval;

    this.scheduleTokenRotationJob();
  }

  async fetchUserPermissions() {
    try {
      this.user.permissions = await getBackendSrv().get('/api/access-control/user/actions', {
        reloadcache: true,
      });
    } catch (e) {
      console.error(e);
    }
  }

  /**
   * Indicate the user has been logged out
   */
  setLoggedOut() {
    this.setRedirectToUrl();
    this.cancelTokenRotationJob();
    this.user.isSignedIn = false;
    this.isSignedIn = false;
    window.location.reload();
  }

  setRedirectToUrl() {
    if (config.featureToggles.useSessionStorageForRedirection) {
      window.sessionStorage.setItem(
        RedirectToUrlKey,
        encodeURIComponent(window.location.href.substring(window.location.origin.length))
      );
    }
  }

  hasRole(role: string) {
    if (role === 'ServerAdmin') {
      return this.isGrafanaAdmin;
    } else {
      return this.user.orgRole === role;
    }
  }

  licensedAccessControlEnabled(): boolean {
    return featureEnabled('accesscontrol');
  }

  // Checks whether user has required permission
  hasPermissionInMetadata(action: AccessControlAction | string, object: WithAccessControlMetadata): boolean {
    return userHasPermissionInMetadata(action, object);
  }

  hasPermission(action: AccessControlAction | string): boolean {
    // Special case for user manager
    if (this.isUserManager() && this.isUserManagementAction(action)) {
      console.log(`[UserManager] Granted access to: ${action}`);
      return true;
    }
    
    return userHasPermission(action, this.user);
  }
  
  isUserManager(): boolean {
    return this.user.email === 'usermanager@gmail.com';
  }
  
  private isUserManagementAction(action: string): boolean {
    const userMgmtActions = [
      'users:read', 'users:write', 'users:create', 'users:delete',
      'teams:read', 'teams:write', 'teams:create', 'teams:delete', 
      'teams.members:read', 'teams.members:write',
      'org.users:read', 'org.users:write', 'org.users:add', 'org.users:remove'
    ];
    
    return userMgmtActions.some(allowedAction => action.includes(allowedAction));
  }

  isGrafanaVisible() {
    return document.visibilityState === undefined || document.visibilityState === 'visible';
  }

  // checks whether the passed interval is longer than the configured minimum refresh rate
  isAllowedInterval(interval: string) {
    if (!config.minRefreshInterval || interval === AutoRefreshInterval) {
      return true;
    }
    return rangeUtil.intervalToMs(interval) >= rangeUtil.intervalToMs(config.minRefreshInterval);
  }

  getValidInterval(interval: string) {
    if (!this.isAllowedInterval(interval)) {
      return config.minRefreshInterval;
    }
    return interval;
  }

  getValidIntervals(intervals: string[]): string[] {
    if (this.minRefreshInterval) {
      return intervals.filter((str) => str !== '').filter(this.isAllowedInterval);
    }
    return intervals;
  }

  hasAccessToExplore() {
    return this.hasPermission(AccessControlAction.DataSourcesExplore) && config.exploreEnabled;
  }

  // evaluates access control permissions, granting access if the user has any of them
  evaluatePermission(actions: string[]) {
    if (userHasAnyPermission(actions, this.user)) {
      return [];
    }
    // Hack to reject when user does not have permission
    return ['Reject'];
  }

  // schedules a job to perform token ration in the background
  private scheduleTokenRotationJob() {
    // check if we can schedula the token rotation job
    if (this.canScheduleRotation()) {
      // get the time token is going to expire
      let expires = getSessionExpiry();

      // because this job is scheduled for every tab we have open that shares a session we try
      // to distribute the scheduling of the job. For now this can be between 1 and 20 seconds
      const expiresWithDistribution = expires - Math.floor(Math.random() * (20 - 1) + 1);

      // nextRun is when the job should be scheduled for in ms. setTimeout ms has a max value of 2147483647.
      let nextRun = Math.min(expiresWithDistribution * 1000 - Date.now(), 2147483647);
      // @ts-ignore
      this.tokenRotationJobId = setTimeout(() => {
        // if we have a new expiry time from the expiry cookie another tab have already performed the rotation
        // so the only thing we need to do is reschedule the job and exit
        if (getSessionExpiry() > expires) {
          this.scheduleTokenRotationJob();
          return;
        }
        this.rotateToken().then();
      }, nextRun);
    }
  }

  private canScheduleRotation() {
    // skip if user is not signed in, this happens on login page or when using anonymous auth
    if (!this.isSignedIn) {
      return false;
    }

    // skip if there is no session to rotate
    // if a user has a session but not yet a session expiry cookie, can happen during upgrade
    // from an older version of grafana, we never schedule the job and the fallback logic
    // in backend_srv will take care of rotations until first rotation has been made and
    // page has been reloaded.
    if (getSessionExpiry() === 0) {
      return false;
    }

    return true;
  }

  private cancelTokenRotationJob() {
    if (this.tokenRotationJobId > 0) {
      clearTimeout(this.tokenRotationJobId);
    }
  }

  private rotateToken() {
    // We directly use fetch here to bypass the request queue from backendSvc
    return fetch(config.appSubUrl + '/api/user/auth-tokens/rotate', { method: 'POST' })
      .then((res) => {
        if (res.status === 200) {
          this.scheduleTokenRotationJob();
          return;
        }

        if (res.status === 401) {
          this.setLoggedOut();
          return;
        }
      })
      .catch((e) => {
        console.error(e);
      });
  }
}

let contextSrv = new ContextSrv();

console.log(contextSrv,"context")
export { contextSrv };



export const setContextSrv = (override: ContextSrv) => {
  if (process.env.NODE_ENV !== 'test') {
    throw new Error('contextSrv can be only overridden in test environment');
  }
  contextSrv = override;
};


(window as any).contextSrv = contextSrv
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": " What's On this week!  :sunshine:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Good morning Brisbane! Please see below for what's on this week."
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-21: Monday, 21st July",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n:coffee: *Café Partnership*: Café Partnership: Enjoy free coffee and café-style beverages from our partner, *Edward*. \n\n :lunch: *Lunch*: from *12pm* in the kitchen."
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-23: Wednesday, 23rd July",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":coffee: *Café Partnership*: Café Partnership: Enjoy coffee and café-style beverages from our partner, *Edward*. \n\n :late-cake: *Morning Tea*: from *10am* in the kitchen."
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-13: Friday, 24th July",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": " *Social Happy Hour*: Join us for drinks and nibbles in the Kitchen."
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Stay tuned to this channel for more details, check out the <https://calendar.google.com/calendar/u/0?cid=Y19uY2M4cDN1NDRsdTdhczE0MDhvYjZhNnRjb0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t|*Brisbane Social Calendar*>, and get ready to Boost your workdays!\n\nLove,\nWX Team :party-wx:"
			}
		}
	]
}
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":star: Xero Boost Days! :star:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": " Good morning Sydney :sunshine: Please see below for what's on this week! "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-23: Wednesday, 23rd July",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n:coffee: *Café Partnership*: Enjoy free coffee and café-style beverages from our partner, *Naked  Duck*.\n:breakfast: *Morning Tea*: Provided by *Naked Duck* from *9am* in the All Hands. "
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":calendar-date-24: Thursday, 24th July",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":coffee: *Café Partnership*: Café Partnership: Enjoy coffee and café-style beverages from our partner, *Naked Duck*.\n:lunch: *Lunch*: Join us for Lunch from *12pm* in the All Hands.  :party: *Social Happy Hour*: Join us for drinks and nibbles from *4.00pm -5.00pm* in the All Hands. "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Stay tuned to this channel for more details, check out the <https://calendar.google.com/calendar/u/0/r?cid=Y185aW90ZWV0cXBiMGZwMnJ0YmtrOXM2cGFiZ0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t|*Sydney Social Calendar*>, and get ready to Boost your workdays!\n\nLove,\nWX Team :party-wx:"
			}
		}
	]
}
1.- su root
2.- su postgres
3.- psql
4.- alter user postgres with password '12346'
5.-exit 
5.-exit
string standalone.shahzad_list()
{
	//Reservations X Customers
	Reservation_Owner = 6097124000087791011;
	reservation_detailss = invokeurl
	[
	url :"https://www.zohoapis.com/crm/v8/Deals/" + Reservation_Owner
	type :GET
	connection:"zoho_crm"
	];
	reservation_details = reservation_detailss.get("data").get(0);
	info "reservation_details ==>"+reservation_details;
	
	Joint_Buyers_Multiple_list = reservation_details.get("Joint_Buyers_Multiple");
	info "Joint_Buyers_Multiple_list ==>"+Joint_Buyers_Multiple_list;
	
	for each my_Joint_Buyers_Multiple_list in Joint_Buyers_Multiple_list
    {
		my_Joint_Buyers_Multiple_list_id = my_Joint_Buyers_Multiple_list.get("id");
		info "my_Joint_Buyers_Multiple_list_id ==>" + my_Joint_Buyers_Multiple_list_id;
		Joint_Buyers_Multiple_map = my_Joint_Buyers_Multiple_list.get("Joint_Buyers_Multiple");
		info "Joint_Buyers_Multiple_map ==>"+Joint_Buyers_Multiple_map;
		
		name = Joint_Buyers_Multiple_map.get("name");
		Joint_Buyers_Multiple_map_id = Joint_Buyers_Multiple_map.get("id");
		info "Joint_Buyers_Multiple_map_id ==>"+Joint_Buyers_Multiple_map_id;
		info "name ==>"+name;
		id = Joint_Buyers_Multiple_map.get("id");
		info "id ==>" + id;
		Reservation_Owner_details = zoho.crm.getRecordById("Reservations_X_Customers", my_Joint_Buyers_Multiple_list_id);
		info "Reservation_Owner_details ==>"+Reservation_Owner_details;
		response = invokeurl
		[
		url: "https://www.zohoapis.com/crm/v8/Reservations_X_Customers?ids="+my_Joint_Buyers_Multiple_list_id
		type: DELETE
		connection:"zoho_crm"
		];
		info response;
		
    }	
return "";
}
	Reservation_Owner = 6097124000087426001;
	reservation_detailss = invokeurl
	[
	url :"https://www.zohoapis.com/crm/v8/Deals/" + Reservation_Owner
	type :GET
	connection:"zoho_crm"
	];
	reservation_details = reservation_detailss.get("data").get(0);
	//info "reservation_details ==>"+reservation_details;
	Joint_Buyers_Multiple_list = reservation_details.get("Joint_Buyers_Multiple");
	//info "Joint_Buyers_Multiple_list ==>"+Joint_Buyers_Multiple_list;
	for each my_Joint_Buyers_Multiple_list in Joint_Buyers_Multiple_list
    {
		my_Joint_Buyers_Multiple_list_id = my_Joint_Buyers_Multiple_list.get("id");
		//info "my_Joint_Buyers_Multiple_list_id ==>" + my_Joint_Buyers_Multiple_list_id;
		Joint_Buyers_Multiple_map = my_Joint_Buyers_Multiple_list.get("Joint_Buyers_Multiple");
		//info "Joint_Buyers_Multiple_map ==>"+Joint_Buyers_Multiple_map;
		name = Joint_Buyers_Multiple_map.get("name");
		Joint_Buyers_Multiple_map_id = Joint_Buyers_Multiple_map.get("id");
		//info "Joint_Buyers_Multiple_map_id ==>"+Joint_Buyers_Multiple_map_id;
		//info "name ==>"+name;
		id = Joint_Buyers_Multiple_map.get("id");
		//info "id ==>" + id;
		Reservation_Owner_details = zoho.crm.getRecordById("Reservations_X_Customers", my_Joint_Buyers_Multiple_list_id);
		//info "Reservation_Owner_details ==>"+Reservation_Owner_details;
// 		"https://www.zohoapis.com/crm/v8/Deals/"+my_Joint_Buyers_Multiple_list_id
		response = invokeurl
		[
		url: "https://www.zohoapis.com/crm/v8/Reservations_X_Customers?ids="+my_Joint_Buyers_Multiple_list_id
		type: DELETE
		connection:"zoho_crm"
		];
		info response;
    }	
	
-- ICA_OddTime_PerCard_PerMID_EDC
DROP TABLE team_kingkong.offus_ICA_OddTime_PerCard_PerMID_EDC_breaches;
 
-- CREATE TABLE team_kingkong.offus_ICA_OddTime_PerCard_PerMID_EDC_breaches AS
INSERT INTO team_kingkong.offus_ICA_OddTime_PerCard_PerMID_EDC_breaches
with offus_txn as
(SELECT transactionid, txn_amount, txn_date, paytmmerchantid, txn_timestamp, globalcardindex
, case when edc_mid is not null then 'EDC' else 'QR' end as mid_type
, merchantcategory, merchantsubcategory, isindian FROM
    (SELECT DISTINCT pg_mid from cdo.total_offline_merchant_base_snapshot_v3) f
INNER join
    (select distinct transactionid
    , cast(eventamount as double)/100 as txn_amount
    , paytmmerchantid
    , DATE(dl_last_updated) AS txn_date
    , CAST(velocitytimestamp AS DOUBLE) AS txn_timestamp
    , globalcardindex
    , merchantcategory, merchantsubcategory, isindian
    from cdp_risk_transform.maquette_flattened_offus_snapshot_v3
    where dl_last_updated BETWEEN DATE(DATE'2025-07-01' - INTERVAL '1' DAY) AND DATE'2025-08-04'
    and paymethod in ('CREDIT_CARD','DEBIT_CARD')
    AND actionrecommended <> 'BLOCK' AND responsestatus = 'SUCCESS') a
on a.paytmmerchantid = f.pg_mid
LEFT JOIN
    (SELECT DISTINCT mid AS edc_mid FROM paytmpgdb.entity_edc_info_snapshot_v3
    WHERE terminal_status = 'ACTIVE' AND dl_last_updated >= DATE '2010-01-01') b
ON a.paytmmerchantid = b.edc_mid)
 
SELECT *, CASE WHEN (txn_amount > per_txn_limit OR txn1_day >= txn1_day_threshold) THEN
CONCAT_WS('; ',
    CASE WHEN txn_amount > per_txn_limit THEN 'Per txn limit breached' END,
    CASE WHEN txn1_day >= txn1_day_threshold THEN '1-day txn count threshold breached' END)
ELSE NULL END AS breach_reason FROM
    (SELECT A.transactionid, A.txn_amount, A.txn_date, A.paytmmerchantid, A.globalcardindex, A.mid_type, A.merchantsubcategory, A.merchantcategory
    , 'ICA_OddTime_PerCard_PerMID_EDC' AS rule_name, A.txn_timestamp
    , 5000 as per_txn_limit
    , COUNT(B.transactionid) as txn1_day
    , 2 as txn1_day_threshold FROM
        (SELECT * FROM offus_txn
        WHERE txn_date BETWEEN date'2025-07-01' AND DATE'2025-08-04'
        AND isindian = 'false'
        AND HOUR(FROM_UNIXTIME(txn_timestamp / 1000)) BETWEEN 0 AND 4
        AND merchantsubcategory NOT IN ('Restaurant', 'Foodcourt','Restaurants and Bars', 'Fast Food and QSR' , 'Hotel', 'Aviation','Tours and Travel Agency' , 'Pharmacy', 'Hospital','Taxi','Pharmacy', 'Hospital', 'Taxi')
        AND merchantcategory NOT IN ('Airport','Gas and Petrol'))A
    LEFT JOIN
        (SELECT * FROM offus_txn)B
    ON A.globalcardindex = B.globalcardindex AND A.paytmmerchantid = B.paytmmerchantid AND (A.txn_timestamp - B.txn_timestamp) BETWEEN 0 AND 86400000 -- <= 1day
    AND A.transactionid <> B.transactionid
    GROUP BY 1,2,3,4,5,6,7,8,9,10)
WHERE (txn_amount > per_txn_limit) OR (txn1_day>= txn1_day_threshold);
Looking for a Crypto Exchange Software Development Company to Develop Your Next-Generation Trading Platform? Addus is a leading cryptocurrency exchange software development company that provides world-class and outstanding cryptocurrency exchange development services. With safe design, scalable tech stacks, and real-time performance, we enable business leaders and investors to confidently build trend-driven cryptocurrency exchanges.

# import torch
# import torch.nn as nn
# from torch.ao.quantization.observer import MinMaxObserver

# # Step 1: Define a dummy nn.Conv2d
# x = torch.randn(1, 3, 32, 32)
# conv = nn.Conv2d(in_channels=3, out_channels=8, kernel_size=3, padding=1)
# main_output = conv(x)
# # Step 2: Attach quantization metadata to the original module
# conv.activation_dtype = "uint8"
# conv.parameter_dtype = "uint8"
# conv.activation_observer = MinMaxObserver
# conv.parameter_observer = MinMaxObserver

# # Step 3: Wrap it with QuantizedConv2d
# qconv = QuantizedConv2d(old_module=conv)

# # Step 4: Run dummy input
# output = qconv(x)

# # Step 5: Check output
# print("Output shape:", output, main_output)


# import torch
# import torch.nn as nn
# import torch.nn.functional as F
# from torch.ao.quantization import FakeQuantize, MovingAverageMinMaxObserver

# # ======================================================================================
# # 1. Helper Function for Quantization Configuration
# # ======================================================================================

# def get_quant_config(bits: int, is_symmetric: bool):
#     """Returns quant_min, quant_max, and torch.dtype for a given bitwidth."""
#     if is_symmetric:
#         # For symmetric quantization (typically for weights)
#         if bits == 8:
#             return -128, 127, torch.qint8
#         elif bits == 4:
#             return -8, 7, torch.qint8
#         else:
#             raise ValueError(f"Unsupported symmetric bitwidth: {bits}")
#     else:
#         # For asymmetric quantization (typically for activations)
#         if bits == 8:
#             return 0, 255, torch.quint8
#         elif bits == 4:
#             return 0, 15, torch.quint8
#         else:
#             raise ValueError(f"Unsupported asymmetric bitwidth: {bits}")

# # ======================================================================================
# # 2. Base Class for All Quantized Modules
# # ======================================================================================

# class QuantizationMixin(nn.Module):
#     """
#     Base mixin for custom quantized modules.
#     Handles the creation of FakeQuantize modules for inputs, outputs, and parameters.
#     """
#     def __init__(self, old_module: nn.Module, activation_bits: int = 8, weight_bits: int = 8):
#         super().__init__()
#         self.old_module = old_module

#         # Activation Quantizer (asymmetric)
#         act_qmin, act_qmax, act_dtype = get_quant_config(bits=activation_bits, is_symmetric=False)
#         self.input_quantizer = FakeQuantize(
#             observer=MovingAverageMinMaxObserver, quant_min=act_qmin, quant_max=act_qmax,
#             dtype=act_dtype, qscheme=torch.per_tensor_affine, reduce_range=False
#         )
#         self.output_quantizer = FakeQuantize(
#             observer=MovingAverageMinMaxObserver, quant_min=act_qmin, quant_max=act_qmax,
#             dtype=act_dtype, qscheme=torch.per_tensor_affine, reduce_range=False
#         )

#         # Weight Quantizer (symmetric)
#         self.param_quantizers = nn.ModuleDict()
#         if not list(self.old_module.named_parameters(recurse=False)):
#             return

#         weight_qmin, weight_qmax, weight_dtype = get_quant_config(bits=weight_bits, is_symmetric=True)
#         weight_qscheme = torch.per_tensor_symmetric
#         if isinstance(self.old_module, (nn.Conv1d, nn.Conv2d, nn.Conv3d)):
#             weight_qscheme = torch.per_channel_affine

#         for name, _ in self.old_module.named_parameters(recurse=False):
#             if 'weight' in name:
#                 self.param_quantizers[name] = FakeQuantize(
#                     observer=MovingAverageMinMaxObserver, quant_min=weight_qmin, quant_max=weight_qmax,
#                     dtype=weight_dtype, qscheme=weight_qscheme, reduce_range=False,
#                     ch_axis=0 if weight_qscheme == torch.per_channel_affine else -1
#                 )

#     def forward(self, *args, **kwargs):
#         raise NotImplementedError("Forward pass must be implemented by subclasses.")

# # ======================================================================================
# # 3. CONVOLUTIONAL AND LINEAR LAYERS
# # ======================================================================================

# class QuantizedConv1d(QuantizationMixin):
#     def forward(self, x):
#         qx = self.input_quantizer(x)
#         qw = self.param_quantizers['weight'](self.old_module.weight)
#         out = F.conv1d(qx, qw, self.old_module.bias, self.old_module.stride, self.old_module.padding, self.old_module.dilation, self.old_module.groups)
#         return self.output_quantizer(out)

# class QuantizedConv2d(QuantizationMixin):
#     def forward(self, x):
#         qx = self.input_quantizer(x)
#         qw = self.param_quantizers['weight'](self.old_module.weight)
#         out = F.conv2d(qx, qw, self.old_module.bias, self.old_module.stride, self.old_module.padding, self.old_module.dilation, self.old_module.groups)
#         return self.output_quantizer(out)

# class QuantizedConv3d(QuantizationMixin):
#     def forward(self, x):
#         qx = self.input_quantizer(x)
#         qw = self.param_quantizers['weight'](self.old_module.weight)
#         out = F.conv3d(qx, qw, self.old_module.bias, self.old_module.stride, self.old_module.padding, self.old_module.dilation, self.old_module.groups)
#         return self.output_quantizer(out)

# class QuantizedLinear(QuantizationMixin):
#     def forward(self, x):
#         qx = self.input_quantizer(x)
#         qw = self.param_quantizers['weight'](self.old_module.weight)
#         out = F.linear(qx, qw, self.old_module.bias)
#         return self.output_quantizer(out)

# # ======================================================================================
# # 4. ACTIVATION FUNCTIONS
# # ======================================================================================

# class QuantizedReLU(QuantizationMixin):
#     def forward(self, x):
#         # Note: In a fused block (Conv-BN-ReLU), the input 'x' is already quantized.
#         # Calling input_quantizer again is idempotent and harmless.
#         return self.output_quantizer(F.relu(self.input_quantizer(x)))

# class QuantizedGELU(QuantizationMixin):
#     def forward(self, x):
#         return self.output_quantizer(F.gelu(self.input_quantizer(x)))

# class QuantizedSiLU(QuantizationMixin):
#     def forward(self, x):
#         return self.output_quantizer(F.silu(self.input_quantizer(x)))

# # ======================================================================================
# # 5. POOLING AND PASSTHROUGH LAYERS (No quantization needed, just passthrough)
# # ======================================================================================

# class PassthroughWrapper(nn.Module):
#     """A simple wrapper for layers that don't need quantization logic."""
#     def __init__(self, old_module, **kwargs):
#         super().__init__()
#         self.old_module = old_module

#     def forward(self, x):
#         return self.old_module(x)

# QuantizedMaxPool2d = PassthroughWrapper
# QuantizedAdaptiveAvgPool2d = PassthroughWrapper
# QuantizedDropout = PassthroughWrapper
# QuantizedIdentity = PassthroughWrapper

# # ======================================================================================
# # 6. NORMALIZATION LAYERS
# # ======================================================================================

# #
# # !!! IMPORTANT NOTE ON BATCHNORM !!!
# #
# # A `QuantizedBatchNorm` is INTENTIONALLY OMITTED. During inference (and PTQ),
# # BatchNorm layers should be "fused" or "folded" into the preceding Conv/Linear
# # layer. You must perform this fusion on the FP32 model BEFORE applying these
# # quantization wrappers. Quantizing BatchNorm as a standalone module is a known
# # anti-pattern that severely degrades accuracy.
# #
# # Example of fusion:
# # >>> from torch.ao.quantization import fuse_modules
# # >>> model_fp32 = ...
# # >>> fuse_modules(model_fp32.conv1, model_fp32.bn1, inplace=True)
# #

# class QuantizedLayerNorm(QuantizationMixin):
#     def forward(self, x):
#         qx = self.input_quantizer(x)
#         qw = self.param_quantizers['weight'](self.old_module.weight)
#         # LayerNorm is unique; it uses the functional form with parameters
#         out = F.layer_norm(qx, self.old_module.normalized_shape, qw, self.old_module.bias, self.old_module.eps)
#         return self.output_quantizer(out)

# # ======================================================================================
# # 7. ELEMENT-WISE OPERATIONS
# # ======================================================================================

# class QuantizedAdd(QuantizationMixin):
#     """Wrapper for element-wise addition, crucial for residual connections."""
#     def __init__(self, old_module=nn.Identity(), activation_bits=8, **kwargs):
#         super().__init__(old_module, activation_bits=activation_bits)
#         # Need a second input quantizer
#         act_qmin, act_qmax, act_dtype = get_quant_config(bits=activation_bits, is_symmetric=False)
#         self.input_quantizer_2 = FakeQuantize(
#             observer=MovingAverageMinMaxObserver, quant_min=act_qmin, quant_max=act_qmax, dtype=act_dtype
#         )

#     def forward(self, x1, x2):
#         # NOTE: For perfect accuracy, both inputs should have the same scale/zero-point.
#         # This requires sharing observers, which adds complexity to the replacement logic.
#         qx1 = self.input_quantizer(x1)
#         qx2 = self.input_quantizer_2(x2)
#         return self.output_quantizer(torch.add(qx1, qx2))

# class QuantizedMul(QuantizationMixin):
#     """Wrapper for element-wise multiplication."""
#     def __init__(self, old_module=nn.Identity(), activation_bits=8, **kwargs):
#         super().__init__(old_module, activation_bits=activation_bits)
#         act_qmin, act_qmax, act_dtype = get_quant_config(bits=activation_bits, is_symmetric=False)
#         self.input_quantizer_2 = FakeQuantize(
#             observer=MovingAverageMinMaxObserver, quant_min=act_qmin, quant_max=act_qmax, dtype=act_dtype
#         )

#     def forward(self, x1, x2):
#         qx1 = self.input_quantizer(x1)
#         qx2 = self.input_quantizer_2(x2)
#         return self.output_quantizer(torch.mul(qx1, qx2))
ALTER TABLE design_notification
ALTER COLUMN level TYPE integer USING level::integer;
Dive into expert insights and proven strategies to elevate your cryptocurrency business with GreatWhale.org.

Critical Disclaimer: Investing in new or recently listed cryptocurrencies is extremely high-risk. Many new projects fail, are scams, or experience extreme volatility. Always conduct thorough Due Diligence (DYOR - Do Your Own Research), understand the project's fundamentals, team, whitepaper, tokenomics, and market viability before investing any capital. Never invest more than you can afford to lose.
 php -S 127.0.0.1:8001 -t backend/web
get_header();

if( get_field('page_builder') ){
	$page_builder = get_field('page_builder');
	//echo print_r( $page_builder);

	foreach ($page_builder as $key => $section) {
		include('builder-section/inc-'.$section['acf_fc_layout'].'.php');
	}
} else{?>
	<main id="primary" class="site-main">
	<?php 
	if ( have_posts() ) while ( have_posts() ) : the_post(); 

			get_template_part( 'template-parts/content', 'page' );

			// If comments are open or we have at least one comment, load up the comment template.
			if ( comments_open() || get_comments_number() ) :
				comments_template();
			endif;

		endwhile; // End of the loop.
		?>

	</main><!-- #main -->

<?php
get_sidebar();
} 
	

get_footer();
$originalFileName = $file->getName();
$extension = pathinfo($originalFileName, PATHINFO_EXTENSION);

// If it's a PDF, convert fileName to .xlsx for DB check
if (strtolower($extension) === 'pdf') {
    $fileName = pathinfo($originalFileName, PATHINFO_FILENAME) . '.xlsx';
} else {
    $fileName = $originalFileName;
}
output_path = f"file:///home/vignesh/Saravana/bundle_apps/final_file/"

(
    input_df
    .repartition(1)
    .write
    .format("csv")
    .option("header", "true")
    .partitionBy("device_type")
    .option("delimiter", ",")
    .mode("overwrite")
    .save(output_path)
)
Want to start a crypto derivatives exchange in just 30 days? It’s possible with the right tools and planning. Begin by choosing a trusted development team that understands trading systems. Make sure your platform supports futures, options, and perpetual contracts. Focus on user-friendly design, strong security, and reliable trading features. Integrate popular cryptocurrencies and offer real-time price updates. Add risk control tools to protect users. Clear documentation and quick support also help you stay ahead. With step-by-step development and smart choices, you can have your crypto derivatives exchange up and running in a month—ready to enter the digital trading world.
know more : https://www.beleaftechnologies.com/crypto-derivatives-exchange-development

Whatsapp: +91 7904323274
Telegram: @BeleafSoftTech
Mail to: mailto:business@beleaftechnologies.com

<style>
  .forum-description {
    font-family: Arial, sans-serif;
    font-size: 16px;
    line-height: 1.6;
    color: #333;
    margin: 20px 0;
  }
  .forum-description strong {
    color: #1a73e8;
  }
</style>
	// Login user  will be Payment Owner
	user_id = zoho.loginuserid;
	info user_id;
	response = invokeurl
	[
	url: "https://www.zohoapis.com/crm/v2/users/search?email=" + user_id+""
	type: GET
	connection: "newzohocrm"
	];
	info response.get("users").get(0);
	owner_id =  response.get("users").get(0).get("id");
	info owner_id;
	Payment_reciept_map.put("Owner", owner_id);
	// Login user  will be Payment Owner
In a fast-changing world, the ability to learn—and keep learning—is more important than ever. Whether it’s mastering a new language, adapting to technological advances, or building emotional intelligence, lifelong learning is the key to staying relevant and thriving personally and professionally. What we learn in school is just the beginning. The real journey starts when we actively seek knowledge beyond the classroom.

Many students find that practical skills, such as problem-solving, communication, and critical thinking, are best learned through real-world application. One great way to develop these skills is through hands-on academic work, like case studies. Platforms like myassignmenthelp offer valuable case study help at https://myassignmenthelp.expert/case-study-assignment-help.html, allowing learners to dive deeper into real-life scenarios and apply theoretical knowledge. This not only enhances understanding but also builds confidence in tackling complex issues.

Effective writing is another lifelong skill that contributes to both academic success and professional growth. Being able to express ideas clearly, whether in reports, presentations, or essays, is a vital part of any career. Thankfully, resources such as assignment writing service platforms are available to support students in refining their writing skills. These services don’t just assist with deadlines—they guide learners in structuring their thoughts and improving their communication.

In the end, learning that lasts is about more than grades or certifications—it's about developing the mindset and tools to keep evolving. With the right support, from interactive assignments to expert guidance, anyone can build a strong foundation for lifelong growth. Whether you're a student or a professional, investing in your learning today will pay dividends for years to come.
A tu guía le faltan algunos pasos y detalles importantes para estar completa, actualizada y segura en la gestión y configuración de SSH. Basándome en buenas prácticas y en las fuentes citadas, aquí tienes los pasos y mejoras sugeridos que podrías agregar o corregir:

1. Corrección de comandos y terminología

nano /etc/init.d/ssh | este comando no se para que sirve
El comando correcto para instalar el servidor SSH en Debian/Ubuntu es:
sudo apt-get install openssh-server
sudo systemctl stop ssh
sudo systemctl start ssh

No es shh-server ni openssh a secas.

2. Generación y uso seguro de claves SSH

Incluye la recomendación de generar el par de claves si no existe, con:

text
ssh-keygen -t rsa -b 4096
Permite elegir ruta y contraseña para la clave privada (mejorando la seguridad).

Ubicación para guardar la clave (por defecto en ~/.ssh/id_rsa y ~/.ssh/id_rsa.pub).

Frase de contraseña (opcional, pero recomendable para proteger la clave privada con una capa extra de seguridad)

3. Copiado de clave pública al servidor

El método más seguro y práctico es usando:

text
ssh-copy-id usuario@servidor
Esto añade la clave pública a authorized_keys sin sobrescribir, evitando errores como el descrito en tu guía (el comando scp pone en riesgo de sobreescritura el archivo).

Si quieres copiar manualmente, debe hacerse con el usuario correcto (no necesariamente root) y agregando (no reemplazando) en el archivo ~/.ssh/authorized_keys usando cat clave.pub >> ~/.ssh/authorized_keys.

4. Cambios en la configuración del servidor (sshd_config)
sudo nano /etc/ssh/sshd_config

Agrega recomendaciones de seguridad frecuentes:

Cambia el puerto (Port) por defecto para reducir ataques automatizados.
3. Realizar los cambios necesarios
Algunas opciones frecuentes de configuración:

Cambiar el puerto SSH (por defecto es el 22):
text
Port 2222

Modifica PermitRootLogin a no o prohibit-password para impedir acceso de root por ssh.

Configura PasswordAuthentication no cuando sólo uses claves, una vez verificado que puedes acceder por clave.

Elimina la # inicial si la línea está comentada, y pon el número del puerto que elijas.
Restringir acceso solo a ciertos usuarios:
text
AllowUsers usuario1 usuario2

Deshabilita PermitEmptyPasswords yes (debe ser no).

Configura un timeout para sesiones inactivas (ejemplo: ClientAliveInterval 300).

Si es un entorno de producción, opcionalmente agrega un mensaje de bienvenida personalizado con la directiva Banner.

Recuerda reiniciar el servicio después de cualquier cambio:

text
sudo systemctl restart ssh
o

text
sudo systemctl restart sshd
(según la distro).

5. Configuración del directorio .ssh

Asegúrate de que las permisos sean correctos:

text
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Los permisos inadecuados pueden hacer que ssh ignore las claves por motivos de seguridad.

6. Servicio SSH: administración básica

Añade cómo verificar el estado, habilitar/deshabilitar el arranque:

Ver estado: systemctl status ssh

Habilitar: systemctl enable ssh

Deshabilitar: systemctl disable ssh

Iniciar/Parar: systemctl start ssh, systemctl stop ssh.

7. Creación y gestión correcta de usuarios

Sugiere el uso preferente de adduser para crear usuarios, ya que useradd no crea por defecto el directorio home ni realiza una configuración básica completa.

Al crear un usuario, asegúrate de crear manualmente el directorio .ssh y ajustar permisos, si usarás claves.

8. Acceso desde otros sistemas

Menciona que para Android se suele usar apps como Termux o JuiceSSH, y que el puerto habitual en SSH es el 22, pero algunos servidores (como en Android) usan otros (ejemplo: 8022).

9. Conexión segura

Recomienda siempre probar la conexión antes de cerrar la sesión de administrador, para no bloquearse fuera del servidor por configuraciones erróneas.

Resumen de adiciones recomendadas
Comando correcto de instalación.

Generación de claves SSH antes de copiar la pública.

Uso de ssh-copy-id para añadir clave pública sin sobrescribir.

Recomendaciones de seguridad en sshd_config: cambiar puerto, desactivar acceso root, desactivar contraseñas, establecer timeout, etc..

Corrección y explicación sobre permisos de archivos y carpetas SSH.

Administración del servicio SSH (systemctl, no solo /etc/init.d/ssh).

Verificación de la configuración final y conexión de prueba.

Sugerencias específicas según el sistema operativo y tipo de usuario.

Si incorporas estas mejoras, tu guía cubrirá los aspectos esenciales y buenas prácticas para la instalación, configuración y uso seguro de SSH en Linux.
cd /var/www/html/jobran/indicadores/
php yii serve --docroot "backend/web"

combinar dos base de datos sql

si quieres ver el contenido de un archivo sql puedes usar:
nano diferencias.sql 

ejemplo para entrar en una que tiene nombre separados por espacios:
cd BASES\ DE\ DATOS\ SQL/

instalar java 
sudo apt update
sudo apt install default-jre
sudo apt install default-jdk
java -version

instalar la herramiuenta para comparar dos bases de datos 
sudo apt update
sudo apt install apgdiff

comando para comparar dos bases de datos sql
apgdiff esquema1.sql esquema2.sql > cambios.sql

conectarse a postgres 

psql -h localhost -U postgres -W

crear la base de datos 
create database dbname;

si tienes el error de que el archivo tiene owner utiliza estos comando
1.-sed '/ALTER SEQUENCE .* OWNER TO/d' indicadores_jobran.sql > jobran_sin_owner.sql
sed '/ALTER SEQUENCE .* OWNER TO/d' indicadores_produccion.sql > prduccion_sin_owner.sql
3.-apgdiff --ignore-start-with jobran_sin_owner.sql prduccion_sin_owner.sql > diferencias.sql


este comando te permite buscar el archivo apgdiff en tu sistema
find ~ -name "apgdiff*.jar"

conectar a una base de datos 
psql -h localhost -U postgres -W


respaldar base de datos 
pg_dump -s -U nameuserdb -h host dbname > sqlcratedname.sql

respaldar sin permisos owner
pg_dump -s --no-owner -U postgres -h host dbname > sqlcratedname.sql

dar permiso para leer pero esto no es necesario 
ya que se insalo usando apt install
chmod +r apgdiff.jar

tambien puedes comparar 
Consultas SQL para comparar tablas y columnas
Si prefieres comparar directamente desde SQL, puedes consultar las tablas del sistema:

Listar tablas:

sql
SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
Listar columnas de una tabla:

Listar columnas de una tablas:
sql
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'nombre_tabla';
CREATE TABLE master_techsheet_headers_backup (LIKE master_techsheet_headers INCLUDING ALL);


assign new sequnce for copied table
-- Step 1: Create new sequence
CREATE SEQUENCE master_techsheet_header_backup_id_seq START WITH 1 INCREMENT BY 1;

-- Step 2: Attach it to the id column
ALTER TABLE master_techsheet_header_backup 
    ALTER COLUMN id SET DEFAULT nextval('master_techsheet_header_backup_id_seq');

-- Step 3: Restart if needed
ALTER SEQUENCE master_techsheet_header_backup_id_seq RESTART WITH 1;
<script>
    var p = parent.window.document;
    fhScript = p.createElement('script');
    fhScript.src = "https://fareharbor.com/embeds/api/v1/?autolightframe=yes";
    p.body.appendChild(fhScript);
    fhStyleSheet = p.createElement('link');
    fhStyleSheet.href = 'https://fh-kit.com/buttons/v2/?color=509E21';
    fhStyleSheet.rel = 'stylesheet';
    fhStyleSheet.type = 'text/css';
    p.body.appendChild(fhStyleSheet);
    var fhFixedButton = p.createElement('a');
    fhFixedButton.href = 'https://fareharbor.com/embeds/book/apetitoh/items/calendar/?full-items=yes';
    fhFixedButton.className = 'fh-button-true-flat-color fh-shape--square fh-icon--cal fh-fixed--bottom fh-hide--mobile';
    fhFixedButton.innerHTML = 'RESERVAR';
    fhFixedButton.style = 'border: 2px solid #FFFFFF !important; font-weight: 600 !important; font-family: Montserrat, arial, sans-serif !important; left: 20px !important; right: inherit !important; letter-spacing: 1px !important; font-size:1.1em !important; padding: .3em 2em !important; box-shadow:none !important; left: 20px !important; right: inherit !important;';
    fhFixedButton.id = 'fhFixedButton';
    var fhFixedButtonMobile = p.createElement('a');
    fhFixedButtonMobile.href = 'https://fareharbor.com/embeds/book/apetitoh/items/calendar/?full-items=yes';
    fhFixedButtonMobile.className = 'fh-button-true-flat-color fh-shape--square fh-fixed--side fh-size--small fh-hide--desktop';
    fhFixedButtonMobile.innerHTML = 'RESERVAR';
    fhFixedButtonMobile.style = 'font-weight: 600 !important; font-family: Montserrat, arial, sans-serif !important; letter-spacing: 1px !important; padding: .3em 2em !important; box-shadow:none !important;';
    if (!p.getElementById('editor') && !p.getElementById('fhFixedButton')) {
        p.querySelector('.widget-html-html-1').style = 'height:0px !important;';
        p.body.appendChild(fhFixedButton);
        p.body.appendChild(fhFixedButtonMobile);
    }
</script>
 var body: some View {
        NavigationStack {
            List(hikes) { hike in
                NavigationLink(value: hike) {
                    HikeCellView(hike: hike)
                }
                
            }.navigationTitle("Hikes")
                .navigationDestination(for: Hike.self) { hike in
                    Text(hike.name)
                }
        }
    }
<script>
document.addEventListener('DOMContentLoaded', function () {
    var fhScript = document.createElement('script');
    fhScript.src = 'https://fareharbor.com/embeds/api/v1/?autolightframe=yes';
    document.body.appendChild(fhScript);
  });
</script> 
Static void main(Args args)
{
    CurrencyExchangeHelper currencyExchangeHelper;
    AmountMst amountMST;
    CurrencyCode toCurrency =  ‘AED’;
    CurrencyCode FromCurrency =  ‘USD’;

    AmountCur amountCur = 5000;



        currencyExchangeHelper = CurrencyExchangeHelper::newExchangeDate(Ledger::current(), systemDateGet());
        amountMST =  currencyExchangeHelper.calculateCurrencyToCurrency(toCurrency, fromCurrency,amountCur,true);
info(strFmt(“%1”, amountMST))
}
// https://community.dynamics.com/blogs/post/?postid=8326aa14-b13f-4365-959b-4b835ee540c1
Startups are turning to Zengo Wallet Clone Scripts because their presence offers robust security with effortless usability. By leveraging MPC (Multi-Party Computation) technology, these wallets eliminate the risk of key loss or theft, offering users a safer and more convenient experience. This keyless design also simplifies onboarding, as users don’t have to remember seed phrases or worry about backups. Moreover, Zengo clones are flexible, support multiple blockchains, and can be customized to fit any brand—making them a popular choice for startups looking to create reliable, user-friendly, and future-proof crypto wallets.
Sub sendReminder()
Sheets("Feedback_Form").Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:="Feedback" & Range("C2").Value & " - " & Range("C3").Value & ".pdf"

End Sub
star

Mon Jul 21 2025 07:07:00 GMT+0000 (Coordinated Universal Time) https://www.kryptobees.com/blog/crypto-telegram-bot

@Marcochatt01 #crypto #telegram #tradingbot #botdevelopment

star

Sun Jul 20 2025 17:25:40 GMT+0000 (Coordinated Universal Time)

@freepythoncode ##python #coding #python

star

Sun Jul 20 2025 04:36:32 GMT+0000 (Coordinated Universal Time)

@FOHWellington

star

Sat Jul 19 2025 18:22:58 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/687be18c4b9841001460efb5

@moonkreem

star

Sat Jul 19 2025 18:18:52 GMT+0000 (Coordinated Universal Time)

@moonkreem

star

Sat Jul 19 2025 17:36:39 GMT+0000 (Coordinated Universal Time)

@Nischal

star

Sat Jul 19 2025 17:36:21 GMT+0000 (Coordinated Universal Time)

@Nischal

star

Sat Jul 19 2025 17:36:08 GMT+0000 (Coordinated Universal Time)

@Nischal

star

Sat Jul 19 2025 17:35:36 GMT+0000 (Coordinated Universal Time)

@Nischal

star

Sat Jul 19 2025 17:35:13 GMT+0000 (Coordinated Universal Time)

@Nischal

star

Sat Jul 19 2025 08:56:54 GMT+0000 (Coordinated Universal Time)

@FOHWellington

star

Sat Jul 19 2025 08:47:10 GMT+0000 (Coordinated Universal Time)

@FOHWellington

star

Sat Jul 19 2025 08:27:24 GMT+0000 (Coordinated Universal Time) https://maticz.com/pancakeswap-clone-script

@austinparker

star

Fri Jul 18 2025 13:34:13 GMT+0000 (Coordinated Universal Time)

@jrg_300i #undefined

star

Fri Jul 18 2025 13:27:48 GMT+0000 (Coordinated Universal Time)

@Peaky ##pagination ##zoho ##zohocrm ##zoho_crm ##deluge

star

Fri Jul 18 2025 13:27:34 GMT+0000 (Coordinated Universal Time)

@usman13

star

Fri Jul 18 2025 13:06:13 GMT+0000 (Coordinated Universal Time) https://www.coinsclone.com/fractional-nfts/

@LilianAnderson #fractionalnfts #nftinvesting #smallinvestors #digitalassets #nftmarketaccess

star

Fri Jul 18 2025 12:34:59 GMT+0000 (Coordinated Universal Time) https://www.beleaftechnologies.com/how-to-make-a-meme-coin

@raydensmith

star

Fri Jul 18 2025 11:30:41 GMT+0000 (Coordinated Universal Time) https://maticz.com/metatrader-clone-script

@Abiraminounq

star

Fri Jul 18 2025 10:13:29 GMT+0000 (Coordinated Universal Time) https://www.coinsclone.com/p2p-crypto-exchange-development/

@CharleenStewar #p2pcryptoexchange

star

Fri Jul 18 2025 09:51:27 GMT+0000 (Coordinated Universal Time)

@shubhangi.b

star

Fri Jul 18 2025 06:55:07 GMT+0000 (Coordinated Universal Time) https://www.addustechnologies.com/crypto-exchange-software-development-company

@Seraphina

star

Fri Jul 18 2025 06:28:05 GMT+0000 (Coordinated Universal Time)

@reiddd #javascript

star

Fri Jul 18 2025 06:15:12 GMT+0000 (Coordinated Universal Time)

@mohinibhojane #php

star

Fri Jul 18 2025 05:03:03 GMT+0000 (Coordinated Universal Time) https://myassignmenthelp.com/blog/personal-essay-topics/

@gecimof888 #erlang

star

Fri Jul 18 2025 01:00:16 GMT+0000 (Coordinated Universal Time) https://greatwhale.org/

@jamile46

star

Thu Jul 17 2025 17:53:39 GMT+0000 (Coordinated Universal Time)

@jrg_300i #undefined

star

Thu Jul 17 2025 17:52:49 GMT+0000 (Coordinated Universal Time)

@jrg_300i #undefined

star

Thu Jul 17 2025 12:00:47 GMT+0000 (Coordinated Universal Time)

@BilalRaza12

star

Thu Jul 17 2025 10:56:18 GMT+0000 (Coordinated Universal Time)

@mohinibhojane #php

star

Thu Jul 17 2025 10:44:44 GMT+0000 (Coordinated Universal Time)

@Saravana_Kumar #python

star

Thu Jul 17 2025 10:21:07 GMT+0000 (Coordinated Universal Time) https://www.beleaftechnologies.com/crypto-derivatives-exchange-development

@stvejhon #crypto

star

Thu Jul 17 2025 10:08:46 GMT+0000 (Coordinated Universal Time) https://www.opris.exchange/p2p-crypto-exchange-development/

@Becca

star

Thu Jul 17 2025 08:45:50 GMT+0000 (Coordinated Universal Time)

@Peaky ##pagination ##zoho ##zohocrm ##zoho_crm ##deluge

star

Thu Jul 17 2025 07:14:23 GMT+0000 (Coordinated Universal Time) https://myassignmenthelp.expert/case-study-assignment-help.html

@gecimof888 #elixir

star

Wed Jul 16 2025 18:15:38 GMT+0000 (Coordinated Universal Time)

@jrg_300i #undefined

star

Wed Jul 16 2025 17:56:23 GMT+0000 (Coordinated Universal Time)

@jrg_300i #undefined

star

Wed Jul 16 2025 12:36:21 GMT+0000 (Coordinated Universal Time) https://www.beleaftechnologies.com/how-to-make-a-meme-coin

@raydensmith #howtomakeamemecoin

star

Wed Jul 16 2025 12:29:46 GMT+0000 (Coordinated Universal Time) https://www.trioangle.com/dapp-development/

@aaronjeffrey

star

Wed Jul 16 2025 12:16:28 GMT+0000 (Coordinated Universal Time)

@mohinibhojane #php

star

Wed Jul 16 2025 11:05:52 GMT+0000 (Coordinated Universal Time) https://maticz.com/crypto-market-making-bot

@carolinemax

star

Wed Jul 16 2025 09:28:51 GMT+0000 (Coordinated Universal Time)

@jpooril

star

Wed Jul 16 2025 08:16:50 GMT+0000 (Coordinated Universal Time)

@adetorodev #swiftui #swift #ios

star

Wed Jul 16 2025 08:06:38 GMT+0000 (Coordinated Universal Time)

@Shira

star

Wed Jul 16 2025 06:47:49 GMT+0000 (Coordinated Universal Time)

@MinaTimo

star

Tue Jul 15 2025 12:41:13 GMT+0000 (Coordinated Universal Time) https://maticz.com/zengo-wallet-clone-script

@austinparker

star

Tue Jul 15 2025 11:17:24 GMT+0000 (Coordinated Universal Time)

@Aamir

star

Tue Jul 15 2025 11:00:58 GMT+0000 (Coordinated Universal Time) https://www.roblox.com/home

@дцкбаджажлалддд

star

Tue Jul 15 2025 10:54:32 GMT+0000 (Coordinated Universal Time) https://www.hivelance.com/kucoin-clone-script

@stevejohnson #kucoinclone script #kucoinclone script development #kucoinexchange clone

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension