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") } } } } }
//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 : "******"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 = "******"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:"******"event":"registrationResult", "data" : {"result":"failed", "reason":"internal DB error"}}`) return } websocket.Message.Send(ws, `{"event":"registrationResult", "data" : {"result":"ok"}}`) }
//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 }
// 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) } }
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) } }
func (change GitChange) FromRepo(repo Repo) bool { repoRoot, err := repo.RootCommit() if err != nil { log.Info("Error getting root commit") } return change.RootCommit == repoRoot }
//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 }
// 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)) } } } }
//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") }
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) } }
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 } } }