Example #1
0
func ReceiveChanges(changes chan gitsync.GitChange, webPort uint16, repo gitsync.Repo) {
	log.Info("webport %d", webPort)
	var webEvents = make(chan *gitsync.GitChange, 128)
	if webPort != 0 {
		go serveWeb(webPort, webEvents)
	}

	for {
		select {
		case change, ok := <-changes:
			if !ok {
				log.Debug("Exiting Loop")
				break
			}

			log.Info("saw %+v", change)
			if change.FromRepo(repo) {
				if err := fetchChange(change, repo.Path()); err != nil {
					log.Info("Error fetching change")
				} else {
					log.Info("fetched change")
				}
			}

			if webPort != 0 {
				select {
				case webEvents <- &change:
				default:
					log.Info("Dropped event %+v from websocket")
				}
			}
		}
	}
}
Example #2
0
//UserRegister handle user registration
func UserRegister(e *EndptMsg, ws *websocket.Conn) {
	userID := e.UserID
	password, ok := e.GetDataString("password")
	if !ok {
		websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":null password"}}`)
		return
	}

	//check if user already exist
	if isUserExist(userID) {
		log.Info("[registerUser]User '" + userID + "' already registered")
		websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":"email address already registered"}}`)
		return
	}

	log.Info("[registerUser] registering " + userID)

	hashedPass, err := authHassPassword(password)
	if err != nil {
		log.Error("[RegisterUser]:failed to hass password : " + err.Error())
		websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":"internal error"}}`)
		return
	}

	if len(hashedPass) == 0 {
		log.Error("[RegisterUser]:failed to hass password : password len = 0")
		websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":"invalid password"}}`)
		return
	}
	log.Debug("generated password = " + hashedPass)

	uri := Config.GetString("mongodb_uri")

	sess, err := mgo.Dial(uri)
	if err != nil {
		log.Error("Can't connect to mongo, go error :" + err.Error())
		websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":"internal DB error"}}`)
		return
	}
	defer sess.Close()

	sess.SetSafe(&mgo.Safe{})
	collection := sess.DB("ircboks").C("user")
	doc := AuthInfo{bson.NewObjectId(), userID, hashedPass}
	err = collection.Insert(doc)
	if err != nil {
		log.Error("Can't insert new user:" + err.Error())
		websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"failed", "reason":"internal DB error"}}`)
		return
	}
	websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"ok"}}`)
}
Example #3
0
//UserLogin handle login message from endpoint.
//It check user passwod and return following infos:
//	- resp
//	- login result
// - err
func UserLogin(e *EndptMsg, ws *websocket.Conn) (string, bool, error) {
	userID := e.UserID
	password, ok := e.GetDataString("password")
	if !ok {
		log.Info("[UserLogin]null password.userID = " + userID)
		return "", false, nil
	}
	//do login
	result, err := checkAuth(userID, password)

	if err != nil {
		return authFalseGenStr("error"), true, nil
	}

	if result == false {
		return authFalseGenStr("loginFailed"), true, nil
	}

	//check IRC client existence
	ctx, found := ContextMap.Get(userID)
	if !found {
		return authTrueGenStr(false, "", "", ""), true, nil
	}

	//update client context
	ctx.AddWs(ws)
	return authTrueGenStr(true, ctx.Nick, ctx.Server, ctx.User), true, nil
}
Example #4
0
// serveWeb starts a webserver that can serve a page and websocket events as
// they are seen.
// It is expected to be run only once and uses the http package global request
// router. It does NOT return.
func serveWeb(port uint16, events chan *gitsync.GitChange) {
	// the container for websocket clients, passed into every websocket handler
	// below
	var cs = clientSet{
		clients: make(map[*websocket.Conn]chan gitsync.GitChange)}

	// Handle any static files (JS/CSS files)
	if handler, err := webcontent.NewMapHandler(webcontent.Paths); err != nil {
		log.Error("Error building templates for web content: %s", err)
	} else {
		log.Debug("Registering / handler")
		http.Handle("/", handler)
	}

	// Events endpoint
	// Note: we wrap the handler in a closure to pass in the clientSet
	http.Handle("/events", websocket.Handler(func(ws *websocket.Conn) {
		handleGitChangeWebClient(&cs, ws)
	}))

	log.Info("Attempting to spawn webserver on %d", port)
	go cs.distribute(events)
	if err := http.ListenAndServe(fmt.Sprintf(":%v", port), nil); err != nil {
		log.Error("Error listening on %d: %s", port, err)
	}
}
Example #5
0
func (c *IRCClient) handleIrcEvent(evt *ogric.Event) {
	if eventsToIgnore[evt.Code] {
		return
	}

	if eventsToForward[evt.Code] {
		c.forwardEvent(evt)
		return
	}
	fnMap := map[string]func(*ogric.Event){
		"001":     c.process001,
		"PRIVMSG": c.processPrivMsg,
		"JOIN":    c.processJoined,
		"PART":    c.processPart,
		"353":     c.processStartNames,
		"366":     c.processEndNames,
		"NICK":    c.processNick,
	}

	fn, ok := fnMap[evt.Code]
	if ok {
		fn(evt)
	} else {
		log.Info("handleIrcEvent() unhandled event = " + evt.Code)
	}
}
Example #6
0
func (change GitChange) FromRepo(repo Repo) bool {
	repoRoot, err := repo.RootCommit()
	if err != nil {
		log.Info("Error getting root commit")
	}
	return change.RootCommit == repoRoot
}
Example #7
0
//Check auth
//return userId and auth result
func checkAuth(userID, password string) (bool, error) {
	//get user from db
	var user User
	bsonM := bson.M{"userId": userID}
	err := DBGetOne("ircboks", "user", bsonM, &user)
	if err != nil {
		log.Info("[checkAuth] user " + userID + " not found")
		return false, err
	}

	//check password
	return authComparePassword(user.Password, password), nil
}
Example #8
0
// handleGitChangeWebClient will build and register a channel to revieve events
// on from a distributor in clientSet. It will exit on error but will consume
// one more event after a client disconnects before it does so.
func handleGitChangeWebClient(cs *clientSet, ws *websocket.Conn) {
	var events = make(chan gitsync.GitChange)

	log.Info("Begin handling %s", makeWebsocketName(ws))
	defer log.Info("End handling %s", makeWebsocketName(ws))

	cs.AddClient(ws, events)
	defer cs.RemoveClient(ws)

	for event := range events {
		if data, err := json.Marshal(event); err != nil {
			log.Info("%s: Cannot marshall event data %+v. %s", makeWebsocketName(ws), event, err)
		} else {
			if _, err := ws.Write(data); err != nil {
				ws.Close()
				log.Error("%s: Cannot write out event: %s", makeWebsocketName(ws), err)
				return
			} else {
				log.Info("%s: Wrote out data", makeWebsocketName(ws))
			}
		}
	}
}
Example #9
0
//Loop handle all messages to/from irc client
func (c *IRCClient) Loop(info *ClientContext) {
	stopped := false
	for !stopped {
		select {
		case in := <-c.inChan:
			go c.processIrcMsg(in)
		case evt := <-c.evtChan:
			go c.handleIrcEvent(&evt)
		case <-c.stopChan:
			stopped = true
		}
	}
	log.Info("IRCClient.Loop for " + c.userID + " exited")
}
Example #10
0
func cleanup(dirName string) {
	// Delete all branches that begin with 'gitsync-'
	getBranches := exec.Command("git", "branch")
	getGitsyncBranches := exec.Command("grep", "gitsync-")
	deleteGitsyncBranches := exec.Command("xargs", "git", "branch", "-D")
	getBranches.Dir = dirName
	getGitsyncBranches.Dir = dirName
	deleteGitsyncBranches.Dir = dirName
	getGitsyncBranches.Stdin, _ = getBranches.StdoutPipe()
	deleteGitsyncBranches.Stdin, _ = getGitsyncBranches.StdoutPipe()
	err := deleteGitsyncBranches.Start()
	err = getGitsyncBranches.Start()
	err = getBranches.Run()
	err = getGitsyncBranches.Wait()
	err = deleteGitsyncBranches.Wait()

	if err != nil {
		log.Info("Could not delete gitsync branches ", err)
	}
}
Example #11
0
func main() {
	// Start changes handler
	var (
		username  = flag.String("user", "", "Username to report when sending changes to the network")
		groupIP   = flag.String("ip", gitsync.IP4MulticastAddr.IP.String(), "Multicast IP to connect to")
		groupPort = flag.Int("port", gitsync.IP4MulticastAddr.Port, "Port to use for network IO")
		logLevel  = flag.String("loglevel", "info", "Lowest log level to emit. Can be one of debug, info, warning, error.")
		logSocket = flag.String("logsocket", "", "proto://address:port target to send logs to")
		logFile   = flag.String("logfile", "", "path to file to log to")
		webPort   = flag.Int("webport", 0, "Port for local webserver. Off by default")
	)
	flag.Parse()

	if len(flag.Args()) == 0 {
		fatalf("No Git directory supplied")
	}

	if err := setupLogging(*logLevel, *logSocket, *logFile); err != nil {
		fatalf("Cannot setup logging: %s", err)
	}

	log.Info("Starting up")
	defer log.Info("Exiting")

	var (
		err       error
		dirName   = flag.Args()[0] // directories to watch
		userId    string           // username
		groupAddr *net.UDPAddr     // network address to connect to

		// channels to move change messages around
		remoteChanges   = make(chan gitsync.GitChange, 128)
		toRemoteChanges = make(chan gitsync.GitChange, 128)
	)
	dirName = util.AbsPath(dirName)

	// get the user's name
	if *username != "" {
		userId = *username
	} else if user, err := user.Current(); err == nil {
		userId = user.Username
	} else {
		fatalf("Cannot get username: %v", err)
	}

	if groupAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", *groupIP, *groupPort)); err != nil {
		fatalf("Cannot resolve address %v:%v: %v", *groupIP, *groupPort, err)
	}

	// start directory poller
	repo, err := gitsync.NewCliRepo(userId, dirName)
	if err != nil {
		fatalf("Cannot open repo: %s", err)
	}

	if err = startGitDaemon(dirName); err != nil {
		log.Fatalf("Unable to start git daemon")
	}

	go gitsync.PollDirectory(log.Global, dirName, repo, toRemoteChanges, 1*time.Second)
	go gitsync.NetIO(log.Global, repo, groupAddr, remoteChanges, toRemoteChanges)
	go ReceiveChanges(remoteChanges, uint16(*webPort), repo)

	s := make(chan os.Signal, 1)
	signal.Notify(s, os.Kill, os.Interrupt, syscall.SIGUSR1)
	for {
		c := <-s
		cleanup(dirName)
		if (c == os.Kill) || (c == os.Interrupt) {
			break
		}

	}
}